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... */
{
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;
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) &&
);
*/
-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<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e')));
+ const name *name_table = Sanitizer<name>::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
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");
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);