[uniscribe] Make font selection work
authorBehdad Esfahbod <behdad@behdad.org>
Sun, 7 Aug 2011 02:06:52 +0000 (22:06 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Sun, 7 Aug 2011 02:32:07 +0000 (22:32 -0400)
Not tested yet.

src/hb-ot-name-private.hh
src/hb-uniscribe-shape.cc
src/test.cc

index cbc8c81..3355bd9 100644 (file)
 
 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) &&
index ecc801e..3b1a178 100644 (file)
@@ -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<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
@@ -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);
index 860e4d2..4051829 100644 (file)
@@ -38,7 +38,6 @@
 #include <stdio.h>
 
 
-
 int
 main (int argc, char **argv)
 {