Imported Upstream version 2.3.1
[platform/upstream/harfbuzz.git] / src / hb-ot-os2-table.hh
index c52b7eb..68dd63e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2011,2012  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
 #ifndef HB_OT_OS2_TABLE_HH
 #define HB_OT_OS2_TABLE_HH
 
-#include "hb-open-type-private.hh"
+#include "hb-open-type.hh"
 #include "hb-ot-os2-unicode-ranges.hh"
-#include "hb-subset-plan.hh"
 
-namespace OT {
+#include "hb-set.hh"
 
 /*
  * OS/2 and Windows Metrics
  * https://docs.microsoft.com/en-us/typography/opentype/spec/os2
  */
-#define HB_OT_TAG_os2 HB_TAG('O','S','/','2')
+#define HB_OT_TAG_OS2 HB_TAG('O','S','/','2')
+
+
+namespace OT {
 
-struct os2
+struct OS2V1Tail
 {
-  static const hb_tag_t tableTag = HB_OT_TAG_os2;
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBUINT32     ulCodePageRange1;
+  HBUINT32     ulCodePageRange2;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
 
-  inline bool sanitize (hb_sanitize_context_t *c) const
+struct OS2V2Tail
+{
+  bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this));
   }
 
-  inline bool subset (hb_subset_plan_t *plan) const
+  public:
+  HBINT16      sxHeight;
+  HBINT16      sCapHeight;
+  HBUINT16     usDefaultChar;
+  HBUINT16     usBreakChar;
+  HBUINT16     usMaxContext;
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+struct OS2V5Tail
+{
+  bool sanitize (hb_sanitize_context_t *c) const
   {
-    hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2));
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBUINT16     usLowerOpticalPointSize;
+  HBUINT16     usUpperOpticalPointSize;
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct OS2
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_OS2;
+
+  bool has_data () const { return this != &Null (OS2); }
+
+  const OS2V1Tail &v1 () const { return version >= 1 ? v1X : Null (OS2V1Tail); }
+  const OS2V2Tail &v2 () const { return version >= 2 ? v2X : Null (OS2V2Tail); }
+  const OS2V5Tail &v5 () const { return version >= 5 ? v5X : Null (OS2V5Tail); }
+
+  enum selection_flag_t {
+    ITALIC             = 1u<<0,
+    UNDERSCORE         = 1u<<1,
+    NEGATIVE           = 1u<<2,
+    OUTLINED           = 1u<<3,
+    STRIKEOUT          = 1u<<4,
+    BOLD               = 1u<<5,
+    REGULAR            = 1u<<6,
+    USE_TYPO_METRICS   = 1u<<7,
+    WWS                        = 1u<<8,
+    OBLIQUE            = 1u<<9
+  };
+
+  bool is_italic () const       { return fsSelection & ITALIC; }
+  bool is_oblique () const      { return fsSelection & OBLIQUE; }
+  bool is_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
+
+  enum width_class_t {
+    FWIDTH_ULTRA_CONDENSED     = 1, /* 50% */
+    FWIDTH_EXTRA_CONDENSED     = 2, /* 62.5% */
+    FWIDTH_CONDENSED           = 3, /* 75% */
+    FWIDTH_SEMI_CONDENSED      = 4, /* 87.5% */
+    FWIDTH_NORMAL              = 5, /* 100% */
+    FWIDTH_SEMI_EXPANDED       = 6, /* 112.5% */
+    FWIDTH_EXPANDED            = 7, /* 125% */
+    FWIDTH_EXTRA_EXPANDED      = 8, /* 150% */
+    FWIDTH_ULTRA_EXPANDED      = 9  /* 200% */
+  };
+
+  float get_width () const
+  {
+    switch (usWidthClass) {
+    case FWIDTH_ULTRA_CONDENSED:return 50.f;
+    case FWIDTH_EXTRA_CONDENSED:return 62.5f;
+    case FWIDTH_CONDENSED:     return 75.f;
+    case FWIDTH_SEMI_CONDENSED:        return 87.5f;
+    default:
+    case FWIDTH_NORMAL:                return 100.f;
+    case FWIDTH_SEMI_EXPANDED: return 112.5f;
+    case FWIDTH_EXPANDED:      return 125.f;
+    case FWIDTH_EXTRA_EXPANDED:        return 150.f;
+    case FWIDTH_ULTRA_EXPANDED:        return 200.f;
+    }
+  }
+
+  bool subset (hb_subset_plan_t *plan) const
+  {
+    hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table<OS2> (plan->source);
     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);
+    OS2 *os2_prime = (OS2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
     if (unlikely (!os2_prime)) {
       hb_blob_destroy (os2_prime_blob);
       return false;
@@ -68,41 +164,41 @@ struct os2
     os2_prime->usLastCharIndex.set (max_cp);
 
     _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange);
-    bool result = plan->add_table (HB_OT_TAG_os2, os2_prime_blob);
+    bool result = plan->add_table (HB_OT_TAG_OS2, os2_prime_blob);
 
     hb_blob_destroy (os2_prime_blob);
     return result;
   }
 
-  inline void _update_unicode_ranges (const hb_set_t *codepoints,
-                                      HBUINT32 ulUnicodeRange[4]) const
+  void _update_unicode_ranges (const hb_set_t *codepoints,
+                              HBUINT32 ulUnicodeRange[4]) const
   {
     for (unsigned int i = 0; i < 4; i++)
       ulUnicodeRange[i].set (0);
 
     hb_codepoint_t cp = HB_SET_VALUE_INVALID;
     while (codepoints->next (&cp)) {
-      unsigned int bit = hb_get_unicode_range_bit (cp);
+      unsigned int bit = _hb_ot_os2_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);
+       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));
+       /* 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_set_t *codepoints,
-                                                 uint16_t *min_cp, /* OUT */
-                                                 uint16_t *max_cp  /* OUT */)
+  static void find_min_and_max_codepoint (const hb_set_t *codepoints,
+                                                uint16_t *min_cp, /* OUT */
+                                                uint16_t *max_cp  /* OUT */)
   {
     *min_cp = codepoints->get_min ();
     *max_cp = codepoints->get_max ();
@@ -119,17 +215,21 @@ struct os2
   };
 
   // https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
-  inline font_page_t get_font_page () const
+  font_page_t get_font_page () const
+  { return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
   {
-    if (version != 0)
-      return (font_page_t) 0;
-    return (font_page_t) (fsSelection & 0xFF00);
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+    if (unlikely (version >= 1 && !v1X.sanitize (c))) return_trace (false);
+    if (unlikely (version >= 2 && !v2X.sanitize (c))) return_trace (false);
+    if (unlikely (version >= 5 && !v5X.sanitize (c))) return_trace (false);
+    return_trace (true);
   }
 
   public:
   HBUINT16     version;
-
-  /* Version 0 */
   HBINT16      xAvgCharWidth;
   HBUINT16     usWeightClass;
   HBUINT16     usWidthClass;
@@ -156,24 +256,11 @@ struct os2
   HBINT16      sTypoLineGap;
   HBUINT16     usWinAscent;
   HBUINT16     usWinDescent;
-
-  /* Version 1 */
-  //HBUINT32   ulCodePageRange1;
-  //HBUINT32   ulCodePageRange2;
-
-  /* Version 2 */
-  //HBINT16    sxHeight;
-  //HBINT16    sCapHeight;
-  //HBUINT16   usDefaultChar;
-  //HBUINT16   usBreakChar;
-  //HBUINT16   usMaxContext;
-
-  /* Version 5 */
-  //HBUINT16   usLowerOpticalPointSize;
-  //HBUINT16   usUpperOpticalPointSize;
-
+  OS2V1Tail    v1X;
+  OS2V2Tail    v2X;
+  OS2V5Tail    v5X;
   public:
-  DEFINE_SIZE_STATIC (78);
+  DEFINE_SIZE_MIN (78);
 };
 
 } /* namespace OT */