Imported Upstream version 1.3.0
[platform/upstream/harfbuzz.git] / src / hb-ot-font.cc
index 39fc849..0b7e31b 100644 (file)
@@ -215,6 +215,28 @@ static inline bool get_glyph_from (const void *obj,
   return typed_obj->get_glyph (codepoint, glyph);
 }
 
+template <typename Type>
+static inline bool get_glyph_from_symbol (const void *obj,
+                                         hb_codepoint_t codepoint,
+                                         hb_codepoint_t *glyph)
+{
+  const Type *typed_obj = (const Type *) obj;
+  if (likely (typed_obj->get_glyph (codepoint, glyph)))
+    return true;
+
+  if (codepoint <= 0x00FFu)
+  {
+    /* For symbol-encoded OpenType fonts, we duplicate the
+     * U+F000..F0FF range at U+0000..U+00FF.  That's what
+     * Windows seems to do, and that's hinted about at:
+     * http://www.microsoft.com/typography/otspec/recom.htm
+     * under "Non-Standard (Symbol) Fonts". */
+    return typed_obj->get_glyph (0xF000u + codepoint, glyph);
+  }
+
+  return false;
+}
+
 struct hb_ot_face_cmap_accelerator_t
 {
   hb_cmap_get_glyph_func_t get_glyph_func;
@@ -231,6 +253,7 @@ struct hb_ot_face_cmap_accelerator_t
     const OT::CmapSubtable *subtable = NULL;
     const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
 
+    bool symbol = false;
     /* 32-bit subtables. */
     if (!subtable) subtable = cmap->find_subtable (3, 10);
     if (!subtable) subtable = cmap->find_subtable (0, 6);
@@ -241,7 +264,7 @@ struct hb_ot_face_cmap_accelerator_t
     if (!subtable) subtable = cmap->find_subtable (0, 2);
     if (!subtable) subtable = cmap->find_subtable (0, 1);
     if (!subtable) subtable = cmap->find_subtable (0, 0);
-    if (!subtable) subtable = cmap->find_subtable (3, 0);
+    if (!subtable)(subtable = cmap->find_subtable (3, 0)) && (symbol = true);
     /* Meh. */
     if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
 
@@ -258,18 +281,21 @@ struct hb_ot_face_cmap_accelerator_t
     this->uvs_table = subtable_uvs;
 
     this->get_glyph_data = subtable;
-    switch (subtable->u.format) {
-    /* Accelerate format 4 and format 12. */
-    default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;          break;
-    case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;  break;
-    case  4:
-      {
-        this->format4_accel.init (&subtable->u.format4);
-       this->get_glyph_data = &this->format4_accel;
-        this->get_glyph_func = this->format4_accel.get_glyph_func;
+    if (unlikely (symbol))
+      this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
+    else
+      switch (subtable->u.format) {
+      /* Accelerate format 4 and format 12. */
+      default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;                break;
+      case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;        break;
+      case  4:
+       {
+         this->format4_accel.init (&subtable->u.format4);
+         this->get_glyph_data = &this->format4_accel;
+         this->get_glyph_func = this->format4_accel.get_glyph_func;
+       }
+       break;
       }
-      break;
-    }
   }
 
   inline void fini (void)