diff --git a/src/hb-ot-name-private.hh b/src/hb-ot-name-private.hh index cbc8c81b0..3355bd9d2 100644 --- a/src/hb-ot-name-private.hh +++ b/src/hb-ot-name-private.hh @@ -39,6 +39,20 @@ struct NameRecord { + static int cmp (const NameRecord *a, const NameRecord *b) + { + int ret; + ret = b->platformID.cmp (a->platformID); + if (ret) return ret; + ret = b->encodingID.cmp (a->encodingID); + if (ret) return ret; + ret = b->languageID.cmp (a->languageID); + if (ret) return ret; + ret = b->nameID.cmp (a->nameID); + if (ret) return ret; + return 0; + } + inline bool sanitize (hb_sanitize_context_t *c, void *base) { TRACE_SANITIZE (); /* We can check from base all the way up to the end of string... */ @@ -60,6 +74,28 @@ struct name { static const hb_tag_t Tag = HB_OT_TAG_name; + inline unsigned int get_name (unsigned int platform_id, + unsigned int encoding_id, + unsigned int language_id, + unsigned int name_id, + void *buffer, + unsigned int buffer_length) const + { + NameRecord key; + key.platformID.set (platform_id); + key.encodingID.set (encoding_id); + key.languageID.set (language_id); + key.nameID.set (name_id); + NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp); + + if (!match) + return 0; + + unsigned int length = MIN (buffer_length, (unsigned int) match->length); + memcmp (buffer, (this + stringOffset) + match->offset, length); + return length; + } + inline bool sanitize_records (hb_sanitize_context_t *c) { TRACE_SANITIZE (); unsigned int _count = count; @@ -70,6 +106,7 @@ struct name inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (); + return true; return c->check_struct (this) && likely (format == 0 || format == 1) && c->check_array (nameRecord, nameRecord[0].static_size, count) && diff --git a/src/hb-uniscribe-shape.cc b/src/hb-uniscribe-shape.cc index ecc801e3a..3b1a1786b 100644 --- a/src/hb-uniscribe-shape.cc +++ b/src/hb-uniscribe-shape.cc @@ -58,19 +58,33 @@ DWORD GetFontData( ); */ -static void +static bool populate_log_font (LOGFONTW *lf, HDC hdc, - hb_font_t *font, - hb_blob_t *blob) + hb_font_t *font) { memset (lf, 0, sizeof (*lf)); int dpi = GetDeviceCaps (hdc, LOGPIXELSY); lf->lfHeight = MulDiv (font->x_scale, dpi, 72); - WCHAR family_name[] = {'n','a','z','l','i'}; - for (unsigned int i = 0; family_name[i] && i < LF_FACESIZE - 1; i++) - lf->lfFaceName[i] = family_name[i]; + hb_blob_t *blob = Sanitizer::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e'))); + const name *name_table = Sanitizer::lock_instance (blob); + unsigned int len = name_table->get_name (3, 1, 0x409, 4, + lf->lfFaceName, + sizeof (lf->lfFaceName[0]) * LF_FACESIZE) + / sizeof (lf->lfFaceName[0]); + if (unlikely (!len)) { + DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry"); + return FALSE; + } + if (unlikely (len >= LF_FACESIZE)) { + DEBUG_MSG (UNISCRIBE, NULL, "Font name too long"); + return FALSE; + } + for (unsigned int i = 0; i < len; i++) + lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]); + lf->lfFaceName[len] = 0; + return TRUE; } hb_bool_t @@ -179,6 +193,7 @@ retry: DWORD num_fonts_installed; HANDLE fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed); + hb_blob_destroy (blob); if (unlikely (!fh)) FAIL ("AddFontMemResourceEx() failed"); @@ -187,7 +202,8 @@ retry: HDC hdc = GetDC (NULL); /* XXX The DC should be cached on the face I guess? */ LOGFONTW log_font; - populate_log_font (&log_font, hdc, font, blob); + if (unlikely (!populate_log_font (&log_font, hdc, font))) + FAIL ("populate_log_font() failed"); HFONT hfont = CreateFontIndirectW (&log_font); SelectObject (hdc, hfont); diff --git a/src/test.cc b/src/test.cc index 860e4d237..405182988 100644 --- a/src/test.cc +++ b/src/test.cc @@ -38,7 +38,6 @@ #include - int main (int argc, char **argv) {