Imported Upstream version 1.7.6
[platform/upstream/harfbuzz.git] / src / hb-ot-os2-table.hh
index 4709cd6..6cb8d49 100644 (file)
@@ -28,7 +28,7 @@
 #define HB_OT_OS2_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
+#include "hb-ot-os2-unicode-ranges.hh"
 
 namespace OT {
 
@@ -49,51 +49,127 @@ struct os2
     return_trace (c->check_struct (this));
   }
 
+  inline bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2));
+    hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
+    // TODO(grieger): move to hb_blob_copy_writable_or_fail
+    hb_blob_destroy (os2_blob);
+
+    OT::os2 *os2_prime = (OT::os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
+    if (unlikely (!os2_prime)) {
+      hb_blob_destroy (os2_prime_blob);
+      return false;
+    }
+
+    uint16_t min_cp, max_cp;
+    find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp);
+    os2_prime->usFirstCharIndex.set (min_cp);
+    os2_prime->usLastCharIndex.set (max_cp);
+
+    _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange);
+    bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob);
+
+    hb_blob_destroy (os2_prime_blob);
+    return result;
+  }
+
+  inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
+                                      HBUINT32 ulUnicodeRange[4]) const
+  {
+    for (unsigned int i = 0; i < 4; i++)
+      ulUnicodeRange[i].set (0);
+
+    for (unsigned int i = 0; i < codepoints.len; i++)
+    {
+      hb_codepoint_t cp = codepoints[i];
+      unsigned int bit = hb_get_unicode_range_bit (cp);
+      if (bit < 128)
+      {
+        unsigned int block = bit / 32;
+        unsigned int bit_in_block = bit % 32;
+        unsigned int mask = 1 << bit_in_block;
+        ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
+      }
+      if (cp >= 0x10000 && cp <= 0x110000)
+      {
+        /* the spec says that bit 57 ("Non Plane 0") implies that there's
+           at least one codepoint beyond the BMP; so I also include all
+           the non-BMP codepoints here */
+        ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
+      }
+    }
+  }
+
+  static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints,
+                                                 uint16_t *min_cp, /* OUT */
+                                                 uint16_t *max_cp  /* OUT */)
+  {
+    hb_codepoint_t min = -1, max = 0;
+
+    for (unsigned int i = 0; i < codepoints.len; i++)
+    {
+      hb_codepoint_t cp = codepoints[i];
+      if (cp < min)
+        min = cp;
+      if (cp > max)
+        max = cp;
+    }
+
+    if (min > 0xFFFF)
+      min = 0xFFFF;
+    if (max > 0xFFFF)
+      max = 0xFFFF;
+
+    *min_cp = min;
+    *max_cp = max;
+  }
+
   public:
-  USHORT       version;
+  HBUINT16     version;
 
   /* Version 0 */
-  SHORT                xAvgCharWidth;
-  USHORT       usWeightClass;
-  USHORT       usWidthClass;
-  USHORT       fsType;
-  SHORT                ySubscriptXSize;
-  SHORT                ySubscriptYSize;
-  SHORT                ySubscriptXOffset;
-  SHORT                ySubscriptYOffset;
-  SHORT                ySuperscriptXSize;
-  SHORT                ySuperscriptYSize;
-  SHORT                ySuperscriptXOffset;
-  SHORT                ySuperscriptYOffset;
-  SHORT                yStrikeoutSize;
-  SHORT                yStrikeoutPosition;
-  SHORT                sFamilyClass;
-  BYTE         panose[10];
-  ULONG                ulUnicodeRange[4];
+  HBINT16      xAvgCharWidth;
+  HBUINT16     usWeightClass;
+  HBUINT16     usWidthClass;
+  HBUINT16     fsType;
+  HBINT16      ySubscriptXSize;
+  HBINT16      ySubscriptYSize;
+  HBINT16      ySubscriptXOffset;
+  HBINT16      ySubscriptYOffset;
+  HBINT16      ySuperscriptXSize;
+  HBINT16      ySuperscriptYSize;
+  HBINT16      ySuperscriptXOffset;
+  HBINT16      ySuperscriptYOffset;
+  HBINT16      yStrikeoutSize;
+  HBINT16      yStrikeoutPosition;
+  HBINT16      sFamilyClass;
+  HBUINT8      panose[10];
+  HBUINT32     ulUnicodeRange[4];
   Tag          achVendID;
-  USHORT       fsSelection;
-  USHORT       usFirstCharIndex;
-  USHORT       usLastCharIndex;
-  SHORT                sTypoAscender;
-  SHORT                sTypoDescender;
-  SHORT                sTypoLineGap;
-  USHORT       usWinAscent;
-  USHORT       usWinDescent;
+  HBUINT16     fsSelection;
+  HBUINT16     usFirstCharIndex;
+  HBUINT16     usLastCharIndex;
+  HBINT16      sTypoAscender;
+  HBINT16      sTypoDescender;
+  HBINT16      sTypoLineGap;
+  HBUINT16     usWinAscent;
+  HBUINT16     usWinDescent;
 
   /* Version 1 */
-  //ULONG ulCodePageRange1;
-  //ULONG ulCodePageRange2;
+  //HBUINT32   ulCodePageRange1;
+  //HBUINT32   ulCodePageRange2;
 
   /* Version 2 */
-  //SHORT sxHeight;
-  //SHORT sCapHeight;
-  //USHORT  usDefaultChar;
-  //USHORT  usBreakChar;
-  //USHORT  usMaxContext;
+  //HBINT16    sxHeight;
+  //HBINT16    sCapHeight;
+  //HBUINT16   usDefaultChar;
+  //HBUINT16   usBreakChar;
+  //HBUINT16   usMaxContext;
 
   /* Version 5 */
-  //USHORT  usLowerOpticalPointSize;
-  //USHORT  usUpperOpticalPointSize;
+  //HBUINT16   usLowerOpticalPointSize;
+  //HBUINT16   usUpperOpticalPointSize;
 
   public:
   DEFINE_SIZE_STATIC (78);