27 #ifndef HB_OT_OS2_TABLE_HH |
27 #ifndef HB_OT_OS2_TABLE_HH |
28 #define HB_OT_OS2_TABLE_HH |
28 #define HB_OT_OS2_TABLE_HH |
29 |
29 |
30 #include "hb-open-type-private.hh" |
30 #include "hb-open-type-private.hh" |
31 #include "hb-ot-os2-unicode-ranges.hh" |
31 #include "hb-ot-os2-unicode-ranges.hh" |
|
32 #include "hb-subset-plan.hh" |
32 |
33 |
33 namespace OT { |
34 namespace OT { |
34 |
35 |
35 /* |
36 /* |
36 * OS/2 and Windows Metrics |
37 * OS/2 and Windows Metrics |
37 * http://www.microsoft.com/typography/otspec/os2.htm |
38 * https://docs.microsoft.com/en-us/typography/opentype/spec/os2 |
38 */ |
39 */ |
39 |
|
40 #define HB_OT_TAG_os2 HB_TAG('O','S','/','2') |
40 #define HB_OT_TAG_os2 HB_TAG('O','S','/','2') |
41 |
41 |
42 struct os2 |
42 struct os2 |
43 { |
43 { |
44 static const hb_tag_t tableTag = HB_OT_TAG_os2; |
44 static const hb_tag_t tableTag = HB_OT_TAG_os2; |
61 hb_blob_destroy (os2_prime_blob); |
61 hb_blob_destroy (os2_prime_blob); |
62 return false; |
62 return false; |
63 } |
63 } |
64 |
64 |
65 uint16_t min_cp, max_cp; |
65 uint16_t min_cp, max_cp; |
66 find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp); |
66 find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp); |
67 os2_prime->usFirstCharIndex.set (min_cp); |
67 os2_prime->usFirstCharIndex.set (min_cp); |
68 os2_prime->usLastCharIndex.set (max_cp); |
68 os2_prime->usLastCharIndex.set (max_cp); |
69 |
69 |
70 _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange); |
70 _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange); |
71 bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob); |
71 bool result = plan->add_table (HB_OT_TAG_os2, os2_prime_blob); |
72 |
72 |
73 hb_blob_destroy (os2_prime_blob); |
73 hb_blob_destroy (os2_prime_blob); |
74 return result; |
74 return result; |
75 } |
75 } |
76 |
76 |
77 inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, |
77 inline void _update_unicode_ranges (const hb_set_t *codepoints, |
78 HBUINT32 ulUnicodeRange[4]) const |
78 HBUINT32 ulUnicodeRange[4]) const |
79 { |
79 { |
80 for (unsigned int i = 0; i < 4; i++) |
80 for (unsigned int i = 0; i < 4; i++) |
81 ulUnicodeRange[i].set (0); |
81 ulUnicodeRange[i].set (0); |
82 |
82 |
83 for (unsigned int i = 0; i < codepoints.len; i++) |
83 hb_codepoint_t cp = HB_SET_VALUE_INVALID; |
84 { |
84 while (codepoints->next (&cp)) { |
85 hb_codepoint_t cp = codepoints[i]; |
|
86 unsigned int bit = hb_get_unicode_range_bit (cp); |
85 unsigned int bit = hb_get_unicode_range_bit (cp); |
87 if (bit < 128) |
86 if (bit < 128) |
88 { |
87 { |
89 unsigned int block = bit / 32; |
88 unsigned int block = bit / 32; |
90 unsigned int bit_in_block = bit % 32; |
89 unsigned int bit_in_block = bit % 32; |
99 ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25)); |
98 ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25)); |
100 } |
99 } |
101 } |
100 } |
102 } |
101 } |
103 |
102 |
104 static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, |
103 static inline void find_min_and_max_codepoint (const hb_set_t *codepoints, |
105 uint16_t *min_cp, /* OUT */ |
104 uint16_t *min_cp, /* OUT */ |
106 uint16_t *max_cp /* OUT */) |
105 uint16_t *max_cp /* OUT */) |
107 { |
106 { |
108 hb_codepoint_t min = -1, max = 0; |
107 *min_cp = codepoints->get_min (); |
|
108 *max_cp = codepoints->get_max (); |
|
109 } |
109 |
110 |
110 for (unsigned int i = 0; i < codepoints.len; i++) |
111 enum font_page_t { |
111 { |
112 HEBREW_FONT_PAGE = 0xB100, // Hebrew Windows 3.1 font page |
112 hb_codepoint_t cp = codepoints[i]; |
113 SIMP_ARABIC_FONT_PAGE = 0xB200, // Simplified Arabic Windows 3.1 font page |
113 if (cp < min) |
114 TRAD_ARABIC_FONT_PAGE = 0xB300, // Traditional Arabic Windows 3.1 font page |
114 min = cp; |
115 OEM_ARABIC_FONT_PAGE = 0xB400, // OEM Arabic Windows 3.1 font page |
115 if (cp > max) |
116 SIMP_FARSI_FONT_PAGE = 0xBA00, // Simplified Farsi Windows 3.1 font page |
116 max = cp; |
117 TRAD_FARSI_FONT_PAGE = 0xBB00, // Traditional Farsi Windows 3.1 font page |
117 } |
118 THAI_FONT_PAGE = 0xDE00 // Thai Windows 3.1 font page |
|
119 }; |
118 |
120 |
119 if (min > 0xFFFF) |
121 // https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 |
120 min = 0xFFFF; |
122 inline font_page_t get_font_page () const |
121 if (max > 0xFFFF) |
123 { |
122 max = 0xFFFF; |
124 if (version != 0) |
123 |
125 return (font_page_t) 0; |
124 *min_cp = min; |
126 return (font_page_t) (fsSelection & 0xFF00); |
125 *max_cp = max; |
|
126 } |
127 } |
127 |
128 |
128 public: |
129 public: |
129 HBUINT16 version; |
130 HBUINT16 version; |
130 |
131 |