Imported Upstream version 2.3.1
[platform/upstream/harfbuzz.git] / src / hb-ot-cff1-table.cc
1 /*
2  * Copyright © 2018 Adobe Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Adobe Author(s): Michiharu Ariza
25  */
26
27 #include "hb-ot-cff1-table.hh"
28 #include "hb-cff1-interp-cs.hh"
29
30 using namespace CFF;
31
32 /* SID to code */
33 static const uint8_t standard_encoding_to_code [] =
34 {
35     0,   32,   33,   34,   35,   36,   37,   38,  39,   40,   41,   42,   43,   44,   45,   46,
36    47,   48,   49,   50,   51,   52,   53,   54,  55,   56,   57,   58,   59,   60,   61,   62,
37    63,   64,   65,   66,   67,   68,   69,   70,  71,   72,   73,   74,   75,   76,   77,   78,
38    79,   80,   81,   82,   83,   84,   85,   86,  87,   88,   89,   90,   91,   92,   93,   94,
39    95,   96,   97,   98,   99,  100,  101,  102, 103,  104,  105,  106,  107,  108,  109,  110,
40   111,  112,  113,  114,  115,  116,  117,  118, 119,  120,  121,  122,  123,  124,  125,  126,
41   161,  162,  163,  164,  165,  166,  167,  168, 169,  170,  171,  172,  173,  174,  175,  177,
42   178,  179,  180,  182,  183,  184,  185,  186, 187,  188,  189,  191,  193,  194,  195,  196,
43   197,  198,  199,  200,  202,  203,  205,  206, 207,  208,  225,  227,  232,  233,  234,  235,
44   241,  245,  248,  249,  250,  251
45 };
46
47 /* SID to code */
48 static const uint8_t expert_encoding_to_code [] =
49 {
50     0,   32,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   44,   45,   46,
51     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   58,   59,    0,    0,    0,
52     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
53     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
54     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
55     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
56     0,    0,    0,   47,    0,    0,    0,    0,    0,    0,    0,    0,    0,   87,   88,    0,
57     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
58     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
59     0,    0,    0,    0,    0,    0,  201,    0,    0,    0,    0,  189,    0,    0,  188,    0,
60     0,    0,    0,  190,  202,    0,    0,    0,    0,  203,    0,    0,    0,    0,    0,    0,
61     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
62     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
63     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
64     0,    0,    0,    0,    0,   33,   34,   36,   37,   38,   39,   40,   41,   42,   43,   48,
65    49,   50,   51,   52,   53,   54,   55,   56,   57,   60,   61,   62,   63,   65,   66,   67,
66    68,   69,   73,   76,   77,   78,   79,   82,   83,   84,   86,   89,   90,   91,   93,   94,
67    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,
68   111,  112,  113,  114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,
69   161,  162,  163,  166,  167,  168,  169,  170,  172,  175,  178,  179,  182,  183,  184,  191,
70   192,  193,  194,  195,  196,  197,  200,  204,  205,  206,  207,  208,  209,  210,  211,  212,
71   213,  214,  215,  216,  217,  218,  219,  220,  221,  222,  223,  224,  225,  226,  227,  228,
72   229,  230,  231,  232,  233,  234,  235,  236,  237,  238,  239,  240,  241,  242,  243,  244,
73   245,  246,  247,  248,  249,  250,  251,  252,  253,  254,  255
74 };
75
76 /* glyph ID to SID */
77 static const uint16_t expert_charset_to_sid [] =
78 {
79     0,    1,  229,  230,  231,  232,  233,  234,  235,  236,  237,  238,   13,   14,   15,   99,
80   239,  240,  241,  242,  243,  244,  245,  246,  247,  248,   27,   28,  249,  250,  251,  252,
81   253,  254,  255,  256,  257,  258,  259,  260,  261,  262,  263,  264,  265,  266,  109,  110,
82   267,  268,  269,  270,  271,  272,  273,  274,  275,  276,  277,  278,  279,  280,  281,  282,
83   283,  284,  285,  286,  287,  288,  289,  290,  291,  292,  293,  294,  295,  296,  297,  298,
84   299,  300,  301,  302,  303,  304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  314,
85   315,  316,  317,  318,  158,  155,  163,  319,  320,  321,  322,  323,  324,  325,  326,  150,
86   164,  169,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,  340,
87   341,  342,  343,  344,  345,  346,  347,  348,  349,  350,  351,  352,  353,  354,  355,  356,
88   357,  358,  359,  360,  361,  362,  363,  364,  365,  366,  367,  368,  369,  370,  371,  372,
89   373,  374,  375,  376,  377,  378
90 };
91
92 /* glyph ID to SID */
93 static const uint16_t expert_subset_charset_to_sid [] =
94 {
95     0,    1,  231,  232,  235,  236,  237,  238,   13,   14,   15,   99,  239,  240,  241,  242,
96   243,  244,  245,  246,  247,  248,   27,   28,  249,  250,  251,  253,  254,  255,  256,  257,
97   258,  259,  260,  261,  262,  263,  264,  265,  266,  109,  110,  267,  268,  269,  270,  272,
98   300,  301,  302,  305,  314,  315,  158,  155,  163,  320,  321,  322,  323,  324,  325,  326,
99   150,  164,  169,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,
100   340,  341,  342,  343,  344,  345,  346
101 };
102
103 /* code to SID */
104 static const uint8_t standard_encoding_to_sid [] =
105 {
106     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
107     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
108     1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,   15,   16,
109     17,  18,   19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,
110     33,  34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,
111     49,  50,   51,   52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   62,   63,   64,
112     65,  66,   67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
113     81,  82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,   95,    0,
114     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
115     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
116     0,   96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,
117     0,  111,  112,  113,  114,    0,  115,  116,  117,  118,  119,  120,  121,  122,    0,  123,
118     0,  124,  125,  126,  127,  128,  129,  130,  131,    0,  132,  133,    0,  134,  135,  136,
119   137,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
120     0,   138,   0,  139,    0,    0,    0,    0,  140,  141,  142,  143,    0,    0,    0,    0,
121     0,   144,   0,    0,    0,  145,    0,    0,  146,  147,  148,  149,    0,    0,    0,    0
122 };
123
124 hb_codepoint_t OT::cff1::lookup_standard_encoding_for_code (hb_codepoint_t sid)
125 {
126   if (sid < ARRAY_LENGTH (standard_encoding_to_code))
127     return (hb_codepoint_t)standard_encoding_to_code[sid];
128   else
129     return 0;
130 }
131
132 hb_codepoint_t OT::cff1::lookup_expert_encoding_for_code (hb_codepoint_t sid)
133 {
134   if (sid < ARRAY_LENGTH (expert_encoding_to_code))
135     return (hb_codepoint_t)expert_encoding_to_code[sid];
136   else
137     return 0;
138 }
139
140 hb_codepoint_t OT::cff1::lookup_expert_charset_for_sid (hb_codepoint_t glyph)
141 {
142   if (glyph < ARRAY_LENGTH (expert_charset_to_sid))
143     return (hb_codepoint_t)expert_charset_to_sid[glyph];
144   else
145     return 0;
146 }
147
148 hb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph)
149 {
150   if (glyph < ARRAY_LENGTH (expert_subset_charset_to_sid))
151     return (hb_codepoint_t)expert_subset_charset_to_sid[glyph];
152   else
153     return 0;
154 }
155
156 hb_codepoint_t OT::cff1::lookup_standard_encoding_for_sid (hb_codepoint_t code)
157 {
158   if (code < ARRAY_LENGTH (standard_encoding_to_sid))
159     return (hb_codepoint_t)standard_encoding_to_sid[code];
160   else
161     return CFF_UNDEF_SID;
162 }
163
164 struct bounds_t
165 {
166   void init ()
167   {
168     min.set_int (0x7FFFFFFF, 0x7FFFFFFF);
169     max.set_int (-0x80000000, -0x80000000);
170   }
171
172   void update (const point_t &pt)
173   {
174     if (pt.x < min.x) min.x = pt.x;
175     if (pt.x > max.x) max.x = pt.x;
176     if (pt.y < min.y) min.y = pt.y;
177     if (pt.y > max.y) max.y = pt.y;
178   }
179
180   void merge (const bounds_t &b)
181   {
182     if (empty ())
183       *this = b;
184     else if (!b.empty ())
185     {
186       if (b.min.x < min.x) min.x = b.min.x;
187       if (b.max.x > max.x) max.x = b.max.x;
188       if (b.min.y < min.y) min.y = b.min.y;
189       if (b.max.y > max.y) max.y = b.max.y;
190     }
191   }
192
193   void offset (const point_t &delta)
194   {
195     if (!empty ())
196     {
197       min.move (delta);
198       max.move (delta);
199     }
200   }
201
202   bool empty () const
203   { return (min.x >= max.x) || (min.y >= max.y); }
204
205   point_t min;
206   point_t max;
207 };
208
209 struct extents_param_t
210 {
211   void init (const OT::cff1::accelerator_t *_cff)
212   {
213     path_open = false;
214     cff = _cff;
215     bounds.init ();
216   }
217
218   void start_path ()         { path_open = true; }
219   void end_path ()           { path_open = false; }
220   bool is_path_open () const { return path_open; }
221
222   bool    path_open;
223   bounds_t  bounds;
224
225   const OT::cff1::accelerator_t *cff;
226 };
227
228 struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, extents_param_t>
229 {
230   static void moveto (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
231   {
232     param.end_path ();
233     env.moveto (pt);
234   }
235
236   static void line (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
237   {
238     if (!param.is_path_open ())
239     {
240       param.start_path ();
241       param.bounds.update (env.get_pt ());
242     }
243     env.moveto (pt1);
244     param.bounds.update (env.get_pt ());
245   }
246
247   static void curve (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
248   {
249     if (!param.is_path_open ())
250     {
251       param.start_path ();
252       param.bounds.update (env.get_pt ());
253     }
254     /* include control points */
255     param.bounds.update (pt1);
256     param.bounds.update (pt2);
257     env.moveto (pt3);
258     param.bounds.update (env.get_pt ());
259   }
260 };
261
262 static bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac=false);
263
264 struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, extents_param_t, cff1_path_procs_extents_t>
265 {
266   static void process_seac (cff1_cs_interp_env_t &env, extents_param_t& param)
267   {
268     unsigned int  n = env.argStack.get_count ();
269     point_t delta;
270     delta.x = env.argStack[n-4];
271     delta.y = env.argStack[n-3];
272     hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
273     hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
274
275     bounds_t  base_bounds, accent_bounds;
276     if (likely (!env.in_seac && base && accent
277                && _get_bounds (param.cff, base, base_bounds, true)
278                && _get_bounds (param.cff, accent, accent_bounds, true)))
279     {
280       param.bounds.merge (base_bounds);
281       accent_bounds.offset (delta);
282       param.bounds.merge (accent_bounds);
283     }
284     else
285       env.set_error ();
286   }
287 };
288
289 bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac)
290 {
291   bounds.init ();
292   if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
293
294   unsigned int fd = cff->fdSelect->get_fd (glyph);
295   cff1_cs_interpreter_t<cff1_cs_opset_extents_t, extents_param_t> interp;
296   const byte_str_t str = (*cff->charStrings)[glyph];
297   interp.env.init (str, *cff, fd);
298   interp.env.set_in_seac (in_seac);
299   extents_param_t  param;
300   param.init (cff);
301   if (unlikely (!interp.interpret (param))) return false;
302   bounds = param.bounds;
303   return true;
304 }
305
306 bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
307 {
308   bounds_t  bounds;
309
310   if (!_get_bounds (this, glyph, bounds))
311     return false;
312
313   if (bounds.min.x >= bounds.max.x)
314   {
315     extents->width = 0;
316     extents->x_bearing = 0;
317   }
318   else
319   {
320     extents->x_bearing = (int32_t)bounds.min.x.floor ();
321     extents->width = (int32_t)bounds.max.x.ceil () - extents->x_bearing;
322   }
323   if (bounds.min.y >= bounds.max.y)
324   {
325     extents->height = 0;
326     extents->y_bearing = 0;
327   }
328   else
329   {
330     extents->y_bearing = (int32_t)bounds.max.y.ceil ();
331     extents->height = (int32_t)bounds.min.y.floor () - extents->y_bearing;
332   }
333
334   return true;
335 }
336
337 struct get_seac_param_t
338 {
339   void init (const OT::cff1::accelerator_t *_cff)
340   {
341     cff = _cff;
342     base = 0;
343     accent = 0;
344   }
345
346   bool has_seac () const { return base && accent; }
347
348   const OT::cff1::accelerator_t *cff;
349   hb_codepoint_t  base;
350   hb_codepoint_t  accent;
351 };
352
353 struct cff1_cs_opset_seac_t : cff1_cs_opset_t<cff1_cs_opset_seac_t, get_seac_param_t>
354 {
355   static void process_seac (cff1_cs_interp_env_t &env, get_seac_param_t& param)
356   {
357     unsigned int  n = env.argStack.get_count ();
358     hb_codepoint_t  base_char = (hb_codepoint_t)env.argStack[n-2].to_int ();
359     hb_codepoint_t  accent_char = (hb_codepoint_t)env.argStack[n-1].to_int ();
360
361     param.base = param.cff->std_code_to_glyph (base_char);
362     param.accent = param.cff->std_code_to_glyph (accent_char);
363   }
364 };
365
366 bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
367 {
368   if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
369
370   unsigned int fd = fdSelect->get_fd (glyph);
371   cff1_cs_interpreter_t<cff1_cs_opset_seac_t, get_seac_param_t> interp;
372   const byte_str_t str = (*charStrings)[glyph];
373   interp.env.init (str, *this, fd);
374   get_seac_param_t  param;
375   param.init (this);
376   if (unlikely (!interp.interpret (param))) return false;
377
378   if (param.has_seac ())
379   {
380     *base = param.base;
381     *accent = param.accent;
382     return true;
383   }
384   return false;
385 }