Add support for > 1bpp custom bitmap fonts

This commit is contained in:
Gordon Williams 2020-09-30 10:28:02 +01:00
parent 16fe29ca3f
commit 1be80451a3
4 changed files with 43 additions and 21 deletions

View File

@ -1,4 +1,5 @@
nRF52: Added option to build in I2C slave support
Add support for > 1bpp custom bitmap fonts
2v07 : Graphics.asImage() now contains buffer when bpp != 8 (fix #1863)
nRF52 SDK15: Fix NRF.setScan/findDevices/etc

View File

@ -288,7 +288,7 @@ uint32_t graphicsBlendColor(JsGraphics *gfx, double amt) {
unsigned int bi = bb*(1-amt) + fb*amt;
return (uint16_t)((bi>>3) | (gi>>2)<<5 | (ri>>3)<<11);
}
return gfx->data.fgColor;
return (amt>=0.5) ? gfx->data.fgColor : gfx->data.bgColor;
}
// ----------------------------------------------------------------------------------------------

View File

@ -68,7 +68,10 @@ typedef enum {
#ifdef USE_FONT_6X8
JSGRAPHICS_FONTSIZE_6X8 = 2 << 13, // a bitmap font
#endif
JSGRAPHICS_FONTSIZE_CUSTOM = 3 << 13,// a custom bitmap font made from fields in the graphics object (See below)
JSGRAPHICS_FONTSIZE_CUSTOM_1BPP = 4 << 13,// a custom bitmap font made from fields in the graphics object (See below)
JSGRAPHICS_FONTSIZE_CUSTOM_2BPP = 5 << 13,// a custom bitmap font made from fields in the graphics object (See below)
JSGRAPHICS_FONTSIZE_CUSTOM_4BPP = 6 << 13,// a custom bitmap font made from fields in the graphics object (See below)
JSGRAPHICS_FONTSIZE_CUSTOM_BIT = 4 << 13 // all custom fonts have this bit set
} JsGraphicsFontSize;

View File

@ -1035,8 +1035,8 @@ JsVar *jswrap_graphics_setFontSizeX(JsVar *parent, int size, bool isVectorFont)
if (size<1) size=1;
if (size>1023) size=1023;
}
if ((gfx.data.fontSize&JSGRAPHICS_FONTSIZE_FONT_MASK) == JSGRAPHICS_FONTSIZE_CUSTOM &&
(size&JSGRAPHICS_FONTSIZE_FONT_MASK) != JSGRAPHICS_FONTSIZE_CUSTOM) {
if ((gfx.data.fontSize&JSGRAPHICS_FONTSIZE_CUSTOM_BIT) &&
!(size&JSGRAPHICS_FONTSIZE_CUSTOM_BIT)) {
jsvObjectRemoveChild(parent, JSGRAPHICS_CUSTOMFONT_BMP);
jsvObjectRemoveChild(parent, JSGRAPHICS_CUSTOMFONT_WIDTH);
jsvObjectRemoveChild(parent, JSGRAPHICS_CUSTOMFONT_HEIGHT);
@ -1056,7 +1056,7 @@ JsVar *jswrap_graphics_setFontSizeX(JsVar *parent, int size, bool isVectorFont)
["bitmap","JsVar","A column-first, MSB-first, 1bpp bitmap containing the font bitmap"],
["firstChar","int32","The first character in the font - usually 32 (space)"],
["width","JsVar","The width of each character in the font. Either an integer, or a string where each character represents the width"],
["height","int32","The height as an integer (max 255). Bits 8-15 represent the scale factor (eg. `2<<8` is twice the size)"]
["height","int32","The height as an integer (max 255). Bits 8-15 represent the scale factor (eg. `2<<8` is twice the size). Bits 16-23 represent the BPP (0,1=1 bpp, 2=2 bpp, 4=4 bpp)"]
],
"return" : ["JsVar","The instance of Graphics this was called on, to allow call chaining"],
"return_object" : "Graphics"
@ -1079,14 +1079,24 @@ JsVar *jswrap_graphics_setFontCustom(JsVar *parent, JsVar *bitmap, int firstChar
jsExceptionHere(JSET_ERROR, "Font width must be a String or an integer");
return 0;
}
int scale = height>>8;
int scale = (height>>8)&255;
if (scale<1) scale=1;
int bpp = height>>16;
if (bpp<1) bpp=1;
JsGraphicsFontSize fontType;
if (bpp==1) fontType = JSGRAPHICS_FONTSIZE_CUSTOM_1BPP;
else if (bpp==2) fontType = JSGRAPHICS_FONTSIZE_CUSTOM_2BPP;
else if (bpp==4) fontType = JSGRAPHICS_FONTSIZE_CUSTOM_4BPP;
else {
jsExceptionHere(JSET_ERROR, "Invalid BPP - 1,2,4 supported");
return 0;
}
height = height&255;
jsvObjectSetChild(parent, JSGRAPHICS_CUSTOMFONT_BMP, bitmap);
jsvObjectSetChild(parent, JSGRAPHICS_CUSTOMFONT_WIDTH, width);
jsvObjectSetChildAndUnLock(parent, JSGRAPHICS_CUSTOMFONT_HEIGHT, jsvNewFromInteger(height));
jsvObjectSetChildAndUnLock(parent, JSGRAPHICS_CUSTOMFONT_FIRSTCHAR, jsvNewFromInteger(firstChar));
gfx.data.fontSize = (unsigned short)(scale + JSGRAPHICS_FONTSIZE_CUSTOM);
gfx.data.fontSize = (unsigned short)(scale + fontType);
graphicsSetVar(&gfx);
return jsvLockAgain(parent);
}
@ -1168,7 +1178,7 @@ JsVar *jswrap_graphics_setFont(JsVar *parent, JsVar *name, int size) {
JsVar *fontSetter = jspGetVarNamedField(parent,setterName,false);
if (fontSetter) {
jsvUnLock(jspExecuteFunction(fontSetter,parent,0,NULL));
sz = (unsigned short)(size + JSGRAPHICS_FONTSIZE_CUSTOM);
sz = (unsigned short)(size + JSGRAPHICS_FONTSIZE_CUSTOM_1BPP);
}
jsvUnLock2(fontSetter,setterName);
}
@ -1206,7 +1216,7 @@ JsVar *jswrap_graphics_getFont(JsVar *parent) {
if (f == JSGRAPHICS_FONTSIZE_6X8)
return jsvNewFromString("6x8");
#endif
if (f == JSGRAPHICS_FONTSIZE_CUSTOM) {
if (f & JSGRAPHICS_FONTSIZE_CUSTOM_BIT) {
// not implemented yet because it's painful trying to pass 5 arguments into setFontCustom
/*JsVar *n = jsvObjectGetChild(parent, JSGRAPHICS_CUSTOMFONT_NAME, 0);
if (n) return n;*/
@ -1282,7 +1292,7 @@ static int jswrap_graphics_getFontHeightInternal(JsGraphics *gfx) {
} else if (f == JSGRAPHICS_FONTSIZE_6X8) {
return 8*scale;
#endif
} else if (f == JSGRAPHICS_FONTSIZE_CUSTOM) {
} else if (f & JSGRAPHICS_FONTSIZE_CUSTOM_BIT) {
return scale*(int)jsvGetIntegerAndUnLock(jsvObjectGetChild(gfx->graphicsVar, JSGRAPHICS_CUSTOMFONT_HEIGHT, 0));
}
return 0;
@ -1318,11 +1328,14 @@ JsVar *jswrap_graphics_drawString(JsVar *parent, JsVar *var, int x, int y, bool
JsVar *customBitmap = 0, *customWidth = 0;
int customHeight = jswrap_graphics_getFontHeightInternal(&gfx);
int customBPP = 1;
int customFirstChar = 0;
JsGraphicsFontSize font = gfx.data.fontSize & JSGRAPHICS_FONTSIZE_FONT_MASK;
unsigned short scale = gfx.data.fontSize & JSGRAPHICS_FONTSIZE_SCALE_MASK;
if (font == JSGRAPHICS_FONTSIZE_CUSTOM) {
if (font & JSGRAPHICS_FONTSIZE_CUSTOM_BIT) {
if (font==JSGRAPHICS_FONTSIZE_CUSTOM_2BPP) customBPP = 2;
if (font==JSGRAPHICS_FONTSIZE_CUSTOM_4BPP) customBPP = 4;
customBitmap = jsvObjectGetChild(parent, JSGRAPHICS_CUSTOMFONT_BMP, 0);
customWidth = jsvObjectGetChild(parent, JSGRAPHICS_CUSTOMFONT_WIDTH, 0);
customFirstChar = (int)jsvGetIntegerAndUnLock(jsvObjectGetChild(parent, JSGRAPHICS_CUSTOMFONT_FIRSTCHAR, 0));
@ -1389,7 +1402,8 @@ JsVar *jswrap_graphics_drawString(JsVar *parent, JsVar *var, int x, int y, bool
graphicsDrawChar6x8(&gfx, x, y, ch, scale, solidBackground);
x+=6*scale;
#endif
} else if (font == JSGRAPHICS_FONTSIZE_CUSTOM) {
} else if (font & JSGRAPHICS_FONTSIZE_CUSTOM_BIT) {
int customBPPRange = (1<<customBPP)-1;
// get char width and offset in string
int width = 0, bmpOffset = 0;
if (jsvIsString(customWidth)) {
@ -1408,26 +1422,30 @@ JsVar *jswrap_graphics_drawString(JsVar *parent, JsVar *var, int x, int y, bool
}
if (ch>=customFirstChar && (x>minX-width) && (x<maxX) && (y>minY-customHeight) && y<maxY) {
int ch = customHeight/scale;
bmpOffset *= ch;
bmpOffset *= ch * customBPP;
// now render character
JsvStringIterator cit;
jsvStringIteratorNew(&cit, customBitmap, (size_t)bmpOffset>>3);
jsvStringIteratorNew(&cit, customBitmap, (size_t)(bmpOffset>>3));
bmpOffset &= 7;
int cx,cy;
int citdata = jsvStringIteratorGetChar(&cit);
citdata <<= customBPP*bmpOffset;
for (cx=0;cx<width;cx++) {
for (cy=0;cy<ch;cy++) {
bool set = (jsvStringIteratorGetChar(&cit)<<bmpOffset)&128;
if (solidBackground || set)
int col = ((citdata&255)>>(8-customBPP));
if (solidBackground || col)
graphicsFillRect(&gfx,
(x + cx*scale),
(y + cy*scale),
(x + cx*scale + scale-1),
(y + cy*scale + scale-1),
set ? gfx.data.fgColor : gfx.data.bgColor);
bmpOffset++;
if (bmpOffset==8) {
graphicsBlendColor(&gfx, col/(double)customBPPRange));
bmpOffset += customBPP;
citdata <<= customBPP;
if (bmpOffset>=8) {
bmpOffset=0;
jsvStringIteratorNext(&cit);
citdata = jsvStringIteratorGetChar(&cit);
}
}
}
@ -1471,7 +1489,7 @@ JsVarInt jswrap_graphics_stringWidth(JsVar *parent, JsVar *var) {
int customFirstChar = 0;
JsGraphicsFontSize font = gfx.data.fontSize & JSGRAPHICS_FONTSIZE_FONT_MASK;
unsigned short scale = gfx.data.fontSize & JSGRAPHICS_FONTSIZE_SCALE_MASK;
if (font == JSGRAPHICS_FONTSIZE_CUSTOM) {
if (font & JSGRAPHICS_FONTSIZE_CUSTOM_BIT) {
customWidth = jsvObjectGetChild(parent, JSGRAPHICS_CUSTOMFONT_WIDTH, 0);
customFirstChar = (int)jsvGetIntegerAndUnLock(jsvObjectGetChild(parent, JSGRAPHICS_CUSTOMFONT_FIRSTCHAR, 0));
}
@ -1497,7 +1515,7 @@ JsVarInt jswrap_graphics_stringWidth(JsVar *parent, JsVar *var) {
} else if (font == JSGRAPHICS_FONTSIZE_6X8) {
width += 6*scale;
#endif
} else if (font == JSGRAPHICS_FONTSIZE_CUSTOM) {
} else if (font & JSGRAPHICS_FONTSIZE_CUSTOM_BIT) {
if (jsvIsString(customWidth)) {
if (ch>=customFirstChar)
width += scale*(unsigned char)jsvGetCharInString(customWidth, (size_t)(ch-customFirstChar));