Skip to content

Commit 750e90e

Browse files
committed
Reader: partially accomodate the BDF 2.2 format
At least for some CJK character sets, FontForge writes a font which includes a METRICSSET section in the preamble, and later in some glyphs skips the SWIDTH/DWIDTH lines in preference to the default values specified in the METRICSSET. According to the Adobe document describing the 2.2 format, this is ia size optimization for storing bdf fonts because many glyphs have the same metrics, particular for vertical text layouts. X's bdftopcf never accepted these extensions not present in BDF 2.1, but fontforge writes them anyway. (I'm not sure who is using fontforge's BDF output, given this fact) This adds minimal support for these elements of the font. Testing performed: * converted yasa-200.bdf to pcf, then rendered with Adafruit_CircuitPython_BitmapFont's simpletest on a host computer with adafruit/Adafruit_CircuitPython_Bitmap_Font#34 applied. (this was broken before this PR) * converted a bdf file produced by otf2bdf and displayed it similarly (this was working before)
1 parent 9f4ab8c commit 750e90e

File tree

2 files changed

+73
-23
lines changed

2 files changed

+73
-23
lines changed

bdfint.h

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ typedef struct BDFSTAT {
5151
int digitCount;
5252
int digitWidths;
5353
int exHeight;
54+
int sWidthDefault;
55+
int dWidthDefault;
5456

5557
FontPropPtr fontProp;
5658
FontPropPtr pointSizeProp;

bdfread.c

+71-23
Original file line numberDiff line numberDiff line change
@@ -402,36 +402,39 @@ bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
402402
}
403403

404404
line = bdfGetLine(file, lineBuf, BDFLINELEN);
405-
if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
406-
bdfError("bad 'SWIDTH'\n");
407-
goto BAILOUT;
408-
}
409-
if (wy != 0) {
410-
bdfError("SWIDTH y value must be zero\n");
411-
goto BAILOUT;
412-
}
413-
if (bitmapExtra)
414-
bitmapExtra->sWidths[ndx] = wx;
415-
416-
/* 5/31/89 (ef) -- we should be able to ditch the character and recover */
417-
/* from all of these. */
405+
if (line && bdfIsPrefix(line, "SWIDTH")) {
406+
if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
407+
bdfError("bad 'SWIDTH'\n");
408+
goto BAILOUT;
409+
}
410+
if (wy != 0) {
411+
bdfError("SWIDTH y value must be zero\n");
412+
goto BAILOUT;
413+
}
414+
line = bdfGetLine(file, lineBuf, BDFLINELEN);
415+
} else {
416+
wx = pState->sWidthDefault;
417+
}
418+
if (bitmapExtra)
419+
bitmapExtra->sWidths[ndx] = wx;
420+
421+
if (line && bdfIsPrefix(line, "DWIDTH")) {
422+
if (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2) {
423+
bdfError("bad 'DWIDTH'\n");
424+
goto BAILOUT;
425+
}
426+
line = bdfGetLine(file, lineBuf, BDFLINELEN);
427+
} else {
428+
wx = pState->dWidthDefault;
429+
}
418430

419-
line = bdfGetLine(file, lineBuf, BDFLINELEN);
420-
if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
421-
bdfError("bad 'DWIDTH'\n");
422-
goto BAILOUT;
423-
}
424-
if (wy != 0) {
425-
bdfError("DWIDTH y value must be zero\n");
426-
goto BAILOUT;
427-
}
428431
/* xCharInfo metrics are stored as INT16 */
429432
if ((wx < INT16_MIN) || (wx > INT16_MAX)) {
430433
bdfError("character '%s' has out of range width, %d\n",
431434
charName, wx);
432435
goto BAILOUT;
433436
}
434-
line = bdfGetLine(file, lineBuf, BDFLINELEN);
437+
435438
if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) {
436439
bdfError("bad 'BBX'\n");
437440
goto BAILOUT;
@@ -612,6 +615,48 @@ bdfReadHeader(FontFilePtr file, bdfFileState *pState)
612615

613616
/***====================================================================***/
614617

618+
static Bool
619+
bdfReadMetricsSet(FontFilePtr file, FontPtr pFont, bdfFileState *pState,
620+
unsigned char *line, unsigned char *lineBuf, size_t lineLen)
621+
{
622+
int metricsSet, wx, wy;
623+
if (sscanf((char *) line, "METRICSSET %d", &metricsSet) != 1) {
624+
bdfError("bad 'METRICSSET'\n");
625+
goto BAILOUT;
626+
}
627+
628+
do {
629+
line = bdfGetLine(file, lineBuf, lineLen);
630+
if (!line) goto BAILOUT;
631+
632+
if (bdfIsPrefix(line, "SWIDTH")) {
633+
if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) {
634+
bdfError("bad 'SWIDTH'\n");
635+
goto BAILOUT;
636+
}
637+
pState->sWidthDefault = wx;
638+
}
639+
if (bdfIsPrefix(line, "DWIDTH")) {
640+
if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) {
641+
bdfError("bad 'DWIDTH'\n");
642+
goto BAILOUT;
643+
}
644+
pState->dWidthDefault = wx;
645+
}
646+
} while(
647+
bdfIsPrefix(line, "SWIDTH") ||
648+
bdfIsPrefix(line, "DWIDTH") ||
649+
bdfIsPrefix(line, "SWIDTH1") ||
650+
bdfIsPrefix(line, "DWIDTH1") ||
651+
bdfIsPrefix(line, "VVECTOR"));
652+
return (TRUE);
653+
654+
BAILOUT:
655+
return (FALSE);
656+
}
657+
658+
/***====================================================================***/
659+
615660
static Bool
616661
bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
617662
{
@@ -627,6 +672,9 @@ bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState)
627672
BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
628673

629674
line = bdfGetLine(file, lineBuf, BDFLINELEN);
675+
if (line && bdfIsPrefix(line, "METRICSSET")) {
676+
bdfReadMetricsSet(file, pFont, pState, line, lineBuf, BDFLINELEN);
677+
}
630678
if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) {
631679
bdfError("missing 'STARTPROPERTIES'\n");
632680
return (FALSE);

0 commit comments

Comments
 (0)