src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh
changeset 54232 7c11a7cc7c1d
parent 50826 f5b95be8b6e2
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh	Wed Feb 27 18:46:55 2019 -0800
+++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh	Fri Mar 01 16:59:19 2019 -0800
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2011,2012  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -27,36 +28,131 @@
 #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')
+
 
-struct os2
+namespace OT {
+
+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));
+  }
+
+  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
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this));
   }
 
-  inline bool subset (hb_subset_plan_t *plan) const
+  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
   {
-    hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2));
+    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,21 +164,21 @@
     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;
@@ -100,7 +196,7 @@
     }
   }
 
-  static inline void find_min_and_max_codepoint (const hb_set_t *codepoints,
+  static void find_min_and_max_codepoint (const hb_set_t *codepoints,
                                                  uint16_t *min_cp, /* OUT */
                                                  uint16_t *max_cp  /* OUT */)
   {
@@ -119,17 +215,21 @@
   };
 
   // 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 @@
   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 */