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