Huw Davies : fonts: Use the EBLC table to retrieve the ascent of the bitmap font.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Mar 21 13:21:28 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 130a0e4f41e8f3c381942734be3c3f14030bce46
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=130a0e4f41e8f3c381942734be3c3f14030bce46

Author: Huw Davies <huw at codeweavers.com>
Date:   Tue Mar 21 17:08:56 2006 +0000

fonts: Use the EBLC table to retrieve the ascent of the bitmap font.

---

 dlls/gdi/tests/gdiobj.c |    2 -
 tools/sfnt2fnt.c        |   87 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/dlls/gdi/tests/gdiobj.c b/dlls/gdi/tests/gdiobj.c
index 35b19a3..f9a621b 100644
--- a/dlls/gdi/tests/gdiobj.c
+++ b/dlls/gdi/tests/gdiobj.c
@@ -235,9 +235,7 @@ static void test_bitmap_font_metrics(voi
         { "MS Serif", FW_NORMAL, 21, 16, 5, 3, 0, 9, 23 },
         { "MS Serif", FW_NORMAL, 27, 21, 6, 3, 0, 12, 27 },
         { "MS Serif", FW_NORMAL, 35, 27, 8, 3, 0, 16, 34 },
-#if 0 /* FIXME: enable once the bug in sfnt2fnt is fixed */
         { "Courier", FW_NORMAL, 13, 11, 2, 0, 0, 8, 8 },
-#endif
         { "Courier", FW_NORMAL, 16, 13, 3, 0, 0, 9, 9 },
         { "Courier", FW_NORMAL, 20, 16, 4, 0, 0, 12, 12 },
         { "System", FW_BOLD, 16, 13, 3, 3, 0, 7, 15 }
diff --git a/tools/sfnt2fnt.c b/tools/sfnt2fnt.c
index 63e5b7a..921bb9a 100644
--- a/tools/sfnt2fnt.c
+++ b/tools/sfnt2fnt.c
@@ -34,6 +34,7 @@
 #include FT_FREETYPE_H
 #include FT_SFNT_NAMES_H
 #include FT_TRUETYPE_TABLES_H
+#include FT_TRUETYPE_TAGS_H
 
 #include "wine/unicode.h"
 #include "wine/wingdi16.h"
@@ -53,6 +54,45 @@ typedef struct {
     DWORD offset;
 } CHAR_TABLE_ENTRY;
 
+typedef struct {
+    DWORD version;
+    ULONG numSizes;
+} eblcHeader_t;
+
+typedef struct {
+    CHAR ascender;
+    CHAR descender;
+    BYTE widthMax;
+    CHAR caretSlopeNumerator;
+    CHAR caretSlopeDenominator;
+    CHAR caretOffset;
+    CHAR minOriginSB;
+    CHAR minAdvanceSB;
+    CHAR maxBeforeBL;
+    CHAR maxAfterBL;
+    CHAR pad1;
+    CHAR pad2;
+} sbitLineMetrics_t;
+
+typedef struct {
+    ULONG indexSubTableArrayOffset;
+    ULONG indexTableSize;
+    ULONG numberOfIndexSubTables;
+    ULONG colorRef;
+    sbitLineMetrics_t hori;
+    sbitLineMetrics_t vert;
+    USHORT startGlyphIndex;
+    USHORT endGlyphIndex;
+    BYTE ppemX;
+    BYTE ppemY;
+    BYTE bitDepth;
+    CHAR flags;
+} bitmapSizeTable_t;
+
+#define GET_BE_WORD(ptr)  MAKEWORD( ((BYTE *)(ptr))[1], ((BYTE *)(ptr))[0] )
+#define GET_BE_DWORD(ptr) ((DWORD)MAKELONG( GET_BE_WORD(&((WORD *)(ptr))[1]), \
+                                            GET_BE_WORD(&((WORD *)(ptr))[0]) ))
+
 #include "poppack.h"
 
 static const char *output_name;
@@ -141,7 +181,7 @@ static int lookup_charset(int enc)
 
 static void fill_fontinfo(FT_Face face, int enc, FILE *fp, int dpi, unsigned char def_char, int avg_width)
 {
-    int ascent, il, ppem, descent, width_bytes = 0, space_size, max_width = 0;
+    int ascent = 0, il, ppem, descent = 0, width_bytes = 0, space_size, max_width = 0;
     FNT_HEADER hdr;
     FONTINFO16 fi;
     BYTE left_byte, right_byte, byte;
@@ -153,6 +193,11 @@ static void fill_fontinfo(FT_Face face, 
     const union cptable *cptable;
     FT_SfntName sfntname;
     TT_OS2 *os2;
+    FT_ULong needed;
+    eblcHeader_t *eblc;
+    bitmapSizeTable_t *size_table;
+    int num_sizes;
+
     cptable = wine_cp_get_table(enc);
     if(!cptable)
         error("Can't find codepage %d\n", enc);
@@ -165,12 +210,44 @@ static void fill_fontinfo(FT_Face face, 
     }
 
     ppem = face->size->metrics.y_ppem;
+
+    needed = 0;
+    if(FT_Load_Sfnt_Table(face, TTAG_EBLC, 0, NULL, &needed))
+        error("Can't find EBLC table\n");
+
+    eblc = malloc(needed);
+    FT_Load_Sfnt_Table(face, TTAG_EBLC, 0, (FT_Byte *)eblc, &needed);
+
+    num_sizes = GET_BE_DWORD(&eblc->numSizes);
+
+    size_table = (bitmapSizeTable_t *)(eblc + 1);
+    for(i = 0; i < num_sizes; i++)
+    {
+        if(size_table->hori.ascender - size_table->hori.descender == ppem)
+        {
+            ascent = size_table->hori.ascender;
+            descent = -size_table->hori.descender;
+            break;
+        }
+        size_table++;
+    }
+
+    /* Versions of fontforge prior to early 2006 have incorrect
+       ascender values in the eblc table, so we won't find the 
+       correct bitmapSizeTable.  In this case use the height of
+       the Aring glyph instead. */
+    if(ascent == 0) 
+    {
+        if(FT_Load_Char(face, 0xc5, FT_LOAD_DEFAULT))
+            error("Can't find Aring\n");
+        ascent = face->glyph->metrics.horiBearingY >> 6;
+        descent = ppem - ascent;
+    }
+
+    free(eblc);
+
     start = sizeof(FNT_HEADER) + sizeof(FONTINFO16);
 
-    if(FT_Load_Char(face, 0xc5, FT_LOAD_DEFAULT))
-        error("Can't find Aring\n");
-    ascent = face->glyph->metrics.height >> 6;
-    descent = ppem - ascent;
     if(FT_Load_Char(face, 'M', FT_LOAD_DEFAULT))
         error("Can't find M\n");
     il = ascent - (face->glyph->metrics.height >> 6);




More information about the wine-cvs mailing list