[HarfBuzz] harfbuzz: Branch 'master' - 2 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri Jun 27 14:22:52 PDT 2014


 src/hb-ot-cmap-table.hh |  147 +++++++++++++++++++++++++++++++++++++++++++-----
 src/hb-ot-font.cc       |   20 ++++++
 2 files changed, 152 insertions(+), 15 deletions(-)

New commits:
commit 23afcff1d14e57f5ce30a4100698d4f2dc530958
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 27 17:22:36 2014 -0400

    [ot-font] Implement Unicode variation selectors

diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index c1fc49e..c9890c5 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -44,6 +44,7 @@ struct hb_ot_font_t
   hb_blob_t *hmtx_blob;
 
   const OT::CmapSubtable *cmap;
+  const OT::CmapSubtable *cmap_uvs;
   hb_blob_t *cmap_blob;
 };
 
@@ -77,8 +78,10 @@ _hb_ot_font_create (hb_font_t *font)
   ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
   const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
   const OT::CmapSubtable *subtable = NULL;
+  const OT::CmapSubtable *subtable_uvs = NULL;
 
   /* 32-bit subtables. */
+  if (!subtable) subtable = cmap->find_subtable (0, 6);
   if (!subtable) subtable = cmap->find_subtable (0, 4);
   if (!subtable) subtable = cmap->find_subtable (3, 10);
   /* 16-bit subtables. */
@@ -87,7 +90,13 @@ _hb_ot_font_create (hb_font_t *font)
   /* Meh. */
   if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
 
+  /* UVS subtable. */
+  if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
+  /* Meh. */
+  if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
+
   ot_font->cmap = subtable;
+  ot_font->cmap_uvs = subtable_uvs;
 
   return ot_font;
 }
@@ -114,7 +123,16 @@ hb_ot_get_glyph (hb_font_t *font HB_UNUSED,
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
 
   if (unlikely (variation_selector))
-    return false;
+  {
+    switch (ot_font->cmap_uvs->get_glyph_variant (unicode,
+						  variation_selector,
+						  glyph))
+    {
+      case OT::GLYPH_VARIANT_NOT_FOUND:		return false;
+      case OT::GLYPH_VARIANT_FOUND:		return true;
+      case OT::GLYPH_VARIANT_USE_DEFAULT:	break;
+    }
+  }
 
   return ot_font->cmap->get_glyph (unicode, glyph);
 }
commit a5a4736916b6035e6413d4619f9e7287e683d51b
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri Jun 27 17:03:22 2014 -0400

    [cmap] Implement subtable format 14

diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index 8cc2ab7..58d59f8 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -42,9 +42,6 @@ namespace OT {
 
 struct CmapSubtableFormat0
 {
-  friend struct CmapSubtable;
-
-  private:
   inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
   {
     hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
@@ -71,9 +68,6 @@ struct CmapSubtableFormat0
 
 struct CmapSubtableFormat4
 {
-  friend struct CmapSubtable;
-
-  private:
   inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
   {
     unsigned int segCount;
@@ -206,9 +200,6 @@ struct CmapSubtableLongGroup
 template <typename UINT>
 struct CmapSubtableTrimmed
 {
-  friend struct CmapSubtable;
-
-  private:
   inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
   {
     /* Rely on our implicit array bound-checking. */
@@ -242,9 +233,6 @@ struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {};
 template <typename T>
 struct CmapSubtableLongSegmented
 {
-  friend struct CmapSubtable;
-
-  private:
   inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
   {
     int i = groups.bsearch (codepoint);
@@ -284,11 +272,129 @@ struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
   { return group.glyphID; }
 };
 
+typedef enum
+{
+  GLYPH_VARIANT_NOT_FOUND = 0,
+  GLYPH_VARIANT_FOUND = 1,
+  GLYPH_VARIANT_USE_DEFAULT = 2
+} glyph_variant_t;
+
+struct UnicodeValueRange
+{
+  inline int cmp (const hb_codepoint_t &codepoint) const
+  {
+    if (codepoint < startUnicodeValue) return -1;
+    if (codepoint > startUnicodeValue + additionalCount) return +1;
+    return 0;
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) {
+    TRACE_SANITIZE (this);
+    return TRACE_RETURN (c->check_struct (this));
+  }
+
+  UINT24	startUnicodeValue;	/* First value in this range. */
+  BYTE		additionalCount;	/* Number of additional values in this
+					 * range. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS;
+
+struct UVSMapping
+{
+  inline int cmp (const hb_codepoint_t &codepoint) const
+  {
+    return unicodeValue.cmp (codepoint);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) {
+    TRACE_SANITIZE (this);
+    return TRACE_RETURN (c->check_struct (this));
+  }
+
+  UINT24	unicodeValue;	/* Base Unicode value of the UVS */
+  GlyphID	glyphID;	/* Glyph ID of the UVS */
+  public:
+  DEFINE_SIZE_STATIC (5);
+};
+
+typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS;
+
+struct VariationSelectorRecord
+{
+  inline glyph_variant_t get_glyph (hb_codepoint_t codepoint,
+				    hb_codepoint_t *glyph,
+				    const void *base) const
+  {
+    int i;
+    const DefaultUVS &defaults = base+defaultUVS;
+    i = defaults.bsearch (codepoint);
+    if (i != -1)
+      return GLYPH_VARIANT_USE_DEFAULT;
+    const NonDefaultUVS &nonDefaults = base+nonDefaultUVS;
+    i = nonDefaults.bsearch (codepoint);
+    if (i != -1)
+    {
+      *glyph = nonDefaults[i].glyphID;
+       return GLYPH_VARIANT_FOUND;
+    }
+    return GLYPH_VARIANT_NOT_FOUND;
+  }
+
+  inline int cmp (const hb_codepoint_t &variation_selector) const
+  {
+    return varSelector.cmp (variation_selector);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c, void *base) {
+    TRACE_SANITIZE (this);
+    return TRACE_RETURN (c->check_struct (this) &&
+			 defaultUVS.sanitize (c, base) &&
+			 nonDefaultUVS.sanitize (c, base));
+  }
+
+  UINT24	varSelector;	/* Variation selector. */
+  OffsetTo<DefaultUVS, ULONG>
+		defaultUVS;	/* Offset to Default UVS Table. May be 0. */
+  OffsetTo<NonDefaultUVS, ULONG>
+		nonDefaultUVS;	/* Offset to Non-Default UVS Table. May be 0. */
+  public:
+  DEFINE_SIZE_STATIC (11);
+};
+
+struct CmapSubtableFormat14
+{
+  inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
+					    hb_codepoint_t variation_selector,
+					    hb_codepoint_t *glyph) const
+  {
+    return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
+  }
+
+  inline bool sanitize (hb_sanitize_context_t *c) {
+    TRACE_SANITIZE (this);
+    return TRACE_RETURN (c->check_struct (this) &&
+			 record.sanitize (c, this));
+  }
+
+  protected:
+  USHORT	format;		/* Format number is set to 0. */
+  ULONG		length;		/* Byte length of this subtable. */
+  SortedArrayOf<VariationSelectorRecord, ULONG>
+		record;		/* Variation selector records; sorted
+				 * in increasing order of `varSelector'. */
+  public:
+  DEFINE_SIZE_ARRAY (10, record);
+};
+
 struct CmapSubtable
 {
   /* Note: We intentionally do NOT implement subtable formats 2 and 8. */
 
-  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  inline bool get_glyph (hb_codepoint_t codepoint,
+			 hb_codepoint_t *glyph) const
   {
     switch (u.format) {
     case  0: return u.format0 .get_glyph(codepoint, glyph);
@@ -297,7 +403,18 @@ struct CmapSubtable
     case 10: return u.format10.get_glyph(codepoint, glyph);
     case 12: return u.format12.get_glyph(codepoint, glyph);
     case 13: return u.format13.get_glyph(codepoint, glyph);
-    default:return false;
+    case 14:
+    default: return false;
+    }
+  }
+
+  inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
+					    hb_codepoint_t variation_selector,
+					    hb_codepoint_t *glyph) const
+  {
+    switch (u.format) {
+    case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph);
+    default: return GLYPH_VARIANT_NOT_FOUND;
     }
   }
 
@@ -311,6 +428,7 @@ struct CmapSubtable
     case 10: return TRACE_RETURN (u.format10.sanitize (c));
     case 12: return TRACE_RETURN (u.format12.sanitize (c));
     case 13: return TRACE_RETURN (u.format13.sanitize (c));
+    case 14: return TRACE_RETURN (u.format13.sanitize (c));
     default:return TRACE_RETURN (true);
     }
   }
@@ -324,6 +442,7 @@ struct CmapSubtable
   CmapSubtableFormat10	format10;
   CmapSubtableFormat12	format12;
   CmapSubtableFormat13	format13;
+  CmapSubtableFormat14	format14;
   } u;
   public:
   DEFINE_SIZE_UNION (2, format);


More information about the HarfBuzz mailing list