1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright © 2018 Adobe Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci *  This is part of HarfBuzz, a text shaping library.
5cb93a386Sopenharmony_ci *
6cb93a386Sopenharmony_ci * Permission is hereby granted, without written agreement and without
7cb93a386Sopenharmony_ci * license or royalty fees, to use, copy, modify, and distribute this
8cb93a386Sopenharmony_ci * software and its documentation for any purpose, provided that the
9cb93a386Sopenharmony_ci * above copyright notice and the following two paragraphs appear in
10cb93a386Sopenharmony_ci * all copies of this software.
11cb93a386Sopenharmony_ci *
12cb93a386Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13cb93a386Sopenharmony_ci * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14cb93a386Sopenharmony_ci * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15cb93a386Sopenharmony_ci * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16cb93a386Sopenharmony_ci * DAMAGE.
17cb93a386Sopenharmony_ci *
18cb93a386Sopenharmony_ci * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19cb93a386Sopenharmony_ci * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20cb93a386Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21cb93a386Sopenharmony_ci * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22cb93a386Sopenharmony_ci * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23cb93a386Sopenharmony_ci *
24cb93a386Sopenharmony_ci * Adobe Author(s): Michiharu Ariza
25cb93a386Sopenharmony_ci */
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_ci#include "hb.hh"
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci#ifndef HB_NO_CFF
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci#include "hb-draw.hh"
32cb93a386Sopenharmony_ci#include "hb-algs.hh"
33cb93a386Sopenharmony_ci#include "hb-ot-cff1-table.hh"
34cb93a386Sopenharmony_ci#include "hb-cff1-interp-cs.hh"
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ciusing namespace CFF;
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_cistruct sid_to_gid_t
39cb93a386Sopenharmony_ci{
40cb93a386Sopenharmony_ci  uint16_t  sid;
41cb93a386Sopenharmony_ci  uint8_t   gid;
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ci  int cmp (uint16_t a) const
44cb93a386Sopenharmony_ci  {
45cb93a386Sopenharmony_ci    if (a == sid) return 0;
46cb93a386Sopenharmony_ci    return (a < sid) ? -1 : 1;
47cb93a386Sopenharmony_ci  }
48cb93a386Sopenharmony_ci};
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci/* SID to code */
51cb93a386Sopenharmony_cistatic const uint8_t standard_encoding_to_code [] =
52cb93a386Sopenharmony_ci{
53cb93a386Sopenharmony_ci    0,   32,   33,   34,   35,   36,   37,   38,  39,   40,   41,   42,   43,   44,   45,   46,
54cb93a386Sopenharmony_ci   47,   48,   49,   50,   51,   52,   53,   54,  55,   56,   57,   58,   59,   60,   61,   62,
55cb93a386Sopenharmony_ci   63,   64,   65,   66,   67,   68,   69,   70,  71,   72,   73,   74,   75,   76,   77,   78,
56cb93a386Sopenharmony_ci   79,   80,   81,   82,   83,   84,   85,   86,  87,   88,   89,   90,   91,   92,   93,   94,
57cb93a386Sopenharmony_ci   95,   96,   97,   98,   99,  100,  101,  102, 103,  104,  105,  106,  107,  108,  109,  110,
58cb93a386Sopenharmony_ci  111,  112,  113,  114,  115,  116,  117,  118, 119,  120,  121,  122,  123,  124,  125,  126,
59cb93a386Sopenharmony_ci  161,  162,  163,  164,  165,  166,  167,  168, 169,  170,  171,  172,  173,  174,  175,  177,
60cb93a386Sopenharmony_ci  178,  179,  180,  182,  183,  184,  185,  186, 187,  188,  189,  191,  193,  194,  195,  196,
61cb93a386Sopenharmony_ci  197,  198,  199,  200,  202,  203,  205,  206, 207,  208,  225,  227,  232,  233,  234,  235,
62cb93a386Sopenharmony_ci  241,  245,  248,  249,  250,  251
63cb93a386Sopenharmony_ci};
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci/* SID to code */
66cb93a386Sopenharmony_cistatic const uint8_t expert_encoding_to_code [] =
67cb93a386Sopenharmony_ci{
68cb93a386Sopenharmony_ci    0,   32,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   44,   45,   46,
69cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   58,   59,    0,    0,    0,
70cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
71cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
72cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
73cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
74cb93a386Sopenharmony_ci    0,    0,    0,   47,    0,    0,    0,    0,    0,    0,    0,    0,    0,   87,   88,    0,
75cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
76cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
77cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,  201,    0,    0,    0,    0,  189,    0,    0,  188,    0,
78cb93a386Sopenharmony_ci    0,    0,    0,  190,  202,    0,    0,    0,    0,  203,    0,    0,    0,    0,    0,    0,
79cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
80cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
81cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
82cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,   33,   34,   36,   37,   38,   39,   40,   41,   42,   43,   48,
83cb93a386Sopenharmony_ci   49,   50,   51,   52,   53,   54,   55,   56,   57,   60,   61,   62,   63,   65,   66,   67,
84cb93a386Sopenharmony_ci   68,   69,   73,   76,   77,   78,   79,   82,   83,   84,   86,   89,   90,   91,   93,   94,
85cb93a386Sopenharmony_ci   95,   96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,
86cb93a386Sopenharmony_ci  111,  112,  113,  114,  115,  116,  117,  118,  119,  120,  121,  122,  123,  124,  125,  126,
87cb93a386Sopenharmony_ci  161,  162,  163,  166,  167,  168,  169,  170,  172,  175,  178,  179,  182,  183,  184,  191,
88cb93a386Sopenharmony_ci  192,  193,  194,  195,  196,  197,  200,  204,  205,  206,  207,  208,  209,  210,  211,  212,
89cb93a386Sopenharmony_ci  213,  214,  215,  216,  217,  218,  219,  220,  221,  222,  223,  224,  225,  226,  227,  228,
90cb93a386Sopenharmony_ci  229,  230,  231,  232,  233,  234,  235,  236,  237,  238,  239,  240,  241,  242,  243,  244,
91cb93a386Sopenharmony_ci  245,  246,  247,  248,  249,  250,  251,  252,  253,  254,  255
92cb93a386Sopenharmony_ci};
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci/* glyph ID to SID */
95cb93a386Sopenharmony_cistatic const uint16_t expert_charset_to_sid [] =
96cb93a386Sopenharmony_ci{
97cb93a386Sopenharmony_ci    0,    1,  229,  230,  231,  232,  233,  234,  235,  236,  237,  238,   13,   14,   15,   99,
98cb93a386Sopenharmony_ci  239,  240,  241,  242,  243,  244,  245,  246,  247,  248,   27,   28,  249,  250,  251,  252,
99cb93a386Sopenharmony_ci  253,  254,  255,  256,  257,  258,  259,  260,  261,  262,  263,  264,  265,  266,  109,  110,
100cb93a386Sopenharmony_ci  267,  268,  269,  270,  271,  272,  273,  274,  275,  276,  277,  278,  279,  280,  281,  282,
101cb93a386Sopenharmony_ci  283,  284,  285,  286,  287,  288,  289,  290,  291,  292,  293,  294,  295,  296,  297,  298,
102cb93a386Sopenharmony_ci  299,  300,  301,  302,  303,  304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  314,
103cb93a386Sopenharmony_ci  315,  316,  317,  318,  158,  155,  163,  319,  320,  321,  322,  323,  324,  325,  326,  150,
104cb93a386Sopenharmony_ci  164,  169,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,  340,
105cb93a386Sopenharmony_ci  341,  342,  343,  344,  345,  346,  347,  348,  349,  350,  351,  352,  353,  354,  355,  356,
106cb93a386Sopenharmony_ci  357,  358,  359,  360,  361,  362,  363,  364,  365,  366,  367,  368,  369,  370,  371,  372,
107cb93a386Sopenharmony_ci  373,  374,  375,  376,  377,  378
108cb93a386Sopenharmony_ci};
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci/* glyph ID to SID */
111cb93a386Sopenharmony_cistatic const uint16_t expert_subset_charset_to_sid [] =
112cb93a386Sopenharmony_ci{
113cb93a386Sopenharmony_ci    0,    1,  231,  232,  235,  236,  237,  238,   13,   14,   15,   99,  239,  240,  241,  242,
114cb93a386Sopenharmony_ci  243,  244,  245,  246,  247,  248,   27,   28,  249,  250,  251,  253,  254,  255,  256,  257,
115cb93a386Sopenharmony_ci  258,  259,  260,  261,  262,  263,  264,  265,  266,  109,  110,  267,  268,  269,  270,  272,
116cb93a386Sopenharmony_ci  300,  301,  302,  305,  314,  315,  158,  155,  163,  320,  321,  322,  323,  324,  325,  326,
117cb93a386Sopenharmony_ci  150,  164,  169,  327,  328,  329,  330,  331,  332,  333,  334,  335,  336,  337,  338,  339,
118cb93a386Sopenharmony_ci  340,  341,  342,  343,  344,  345,  346
119cb93a386Sopenharmony_ci};
120cb93a386Sopenharmony_ci
121cb93a386Sopenharmony_ci/* SID to glyph ID */
122cb93a386Sopenharmony_cistatic const sid_to_gid_t expert_charset_sid_to_gid [] =
123cb93a386Sopenharmony_ci{
124cb93a386Sopenharmony_ci    { 1, 1 },     { 13, 12 },   { 14, 13 },   { 15, 14 },
125cb93a386Sopenharmony_ci    { 27, 26 },   { 28, 27 },   { 99, 15 },   { 109, 46 },
126cb93a386Sopenharmony_ci    { 110, 47 },  { 150, 111 }, { 155, 101 }, { 158, 100 },
127cb93a386Sopenharmony_ci    { 163, 102 }, { 164, 112 }, { 169, 113 }, { 229, 2 },
128cb93a386Sopenharmony_ci    { 230, 3 },   { 231, 4 },   { 232, 5 },   { 233, 6 },
129cb93a386Sopenharmony_ci    { 234, 7 },   { 235, 8 },   { 236, 9 },   { 237, 10 },
130cb93a386Sopenharmony_ci    { 238, 11 },  { 239, 16 },  { 240, 17 },  { 241, 18 },
131cb93a386Sopenharmony_ci    { 242, 19 },  { 243, 20 },  { 244, 21 },  { 245, 22 },
132cb93a386Sopenharmony_ci    { 246, 23 },  { 247, 24 },  { 248, 25 },  { 249, 28 },
133cb93a386Sopenharmony_ci    { 250, 29 },  { 251, 30 },  { 252, 31 },  { 253, 32 },
134cb93a386Sopenharmony_ci    { 254, 33 },  { 255, 34 },  { 256, 35 },  { 257, 36 },
135cb93a386Sopenharmony_ci    { 258, 37 },  { 259, 38 },  { 260, 39 },  { 261, 40 },
136cb93a386Sopenharmony_ci    { 262, 41 },  { 263, 42 },  { 264, 43 },  { 265, 44 },
137cb93a386Sopenharmony_ci    { 266, 45 },  { 267, 48 },  { 268, 49 },  { 269, 50 },
138cb93a386Sopenharmony_ci    { 270, 51 },  { 271, 52 },  { 272, 53 },  { 273, 54 },
139cb93a386Sopenharmony_ci    { 274, 55 },  { 275, 56 },  { 276, 57 },  { 277, 58 },
140cb93a386Sopenharmony_ci    { 278, 59 },  { 279, 60 },  { 280, 61 },  { 281, 62 },
141cb93a386Sopenharmony_ci    { 282, 63 },  { 283, 64 },  { 284, 65 },  { 285, 66 },
142cb93a386Sopenharmony_ci    { 286, 67 },  { 287, 68 },  { 288, 69 },  { 289, 70 },
143cb93a386Sopenharmony_ci    { 290, 71 },  { 291, 72 },  { 292, 73 },  { 293, 74 },
144cb93a386Sopenharmony_ci    { 294, 75 },  { 295, 76 },  { 296, 77 },  { 297, 78 },
145cb93a386Sopenharmony_ci    { 298, 79 },  { 299, 80 },  { 300, 81 },  { 301, 82 },
146cb93a386Sopenharmony_ci    { 302, 83 },  { 303, 84 },  { 304, 85 },  { 305, 86 },
147cb93a386Sopenharmony_ci    { 306, 87 },  { 307, 88 },  { 308, 89 },  { 309, 90 },
148cb93a386Sopenharmony_ci    { 310, 91 },  { 311, 92 },  { 312, 93 },  { 313, 94 },
149cb93a386Sopenharmony_ci    { 314, 95 },  { 315, 96 },  { 316, 97 },  { 317, 98 },
150cb93a386Sopenharmony_ci    { 318, 99 },  { 319, 103 }, { 320, 104 }, { 321, 105 },
151cb93a386Sopenharmony_ci    { 322, 106 }, { 323, 107 }, { 324, 108 }, { 325, 109 },
152cb93a386Sopenharmony_ci    { 326, 110 }, { 327, 114 }, { 328, 115 }, { 329, 116 },
153cb93a386Sopenharmony_ci    { 330, 117 }, { 331, 118 }, { 332, 119 }, { 333, 120 },
154cb93a386Sopenharmony_ci    { 334, 121 }, { 335, 122 }, { 336, 123 }, { 337, 124 },
155cb93a386Sopenharmony_ci    { 338, 125 }, { 339, 126 }, { 340, 127 }, { 341, 128 },
156cb93a386Sopenharmony_ci    { 342, 129 }, { 343, 130 }, { 344, 131 }, { 345, 132 },
157cb93a386Sopenharmony_ci    { 346, 133 }, { 347, 134 }, { 348, 135 }, { 349, 136 },
158cb93a386Sopenharmony_ci    { 350, 137 }, { 351, 138 }, { 352, 139 }, { 353, 140 },
159cb93a386Sopenharmony_ci    { 354, 141 }, { 355, 142 }, { 356, 143 }, { 357, 144 },
160cb93a386Sopenharmony_ci    { 358, 145 }, { 359, 146 }, { 360, 147 }, { 361, 148 },
161cb93a386Sopenharmony_ci    { 362, 149 }, { 363, 150 }, { 364, 151 }, { 365, 152 },
162cb93a386Sopenharmony_ci    { 366, 153 }, { 367, 154 }, { 368, 155 }, { 369, 156 },
163cb93a386Sopenharmony_ci    { 370, 157 }, { 371, 158 }, { 372, 159 }, { 373, 160 },
164cb93a386Sopenharmony_ci    { 374, 161 }, { 375, 162 }, { 376, 163 }, { 377, 164 },
165cb93a386Sopenharmony_ci    { 378, 165 }
166cb93a386Sopenharmony_ci};
167cb93a386Sopenharmony_ci
168cb93a386Sopenharmony_ci/* SID to glyph ID */
169cb93a386Sopenharmony_cistatic const sid_to_gid_t expert_subset_charset_sid_to_gid [] =
170cb93a386Sopenharmony_ci{
171cb93a386Sopenharmony_ci  { 1, 1 },       { 13, 8 },      { 14, 9 },      { 15, 10 },
172cb93a386Sopenharmony_ci  { 27, 22 },     { 28, 23 },     { 99, 11 },     { 109, 41 },
173cb93a386Sopenharmony_ci  { 110, 42 },    { 150, 64 },    { 155, 55 },    { 158, 54 },
174cb93a386Sopenharmony_ci  { 163, 56 },    { 164, 65 },    { 169, 66 },    { 231, 2 },
175cb93a386Sopenharmony_ci  { 232, 3 },     { 235, 4 },     { 236, 5 },     { 237, 6 },
176cb93a386Sopenharmony_ci  { 238, 7 },     { 239, 12 },    { 240, 13 },    { 241, 14 },
177cb93a386Sopenharmony_ci  { 242, 15 },    { 243, 16 },    { 244, 17 },    { 245, 18 },
178cb93a386Sopenharmony_ci  { 246, 19 },    { 247, 20 },    { 248, 21 },    { 249, 24 },
179cb93a386Sopenharmony_ci  { 250, 25 },    { 251, 26 },    { 253, 27 },    { 254, 28 },
180cb93a386Sopenharmony_ci  { 255, 29 },    { 256, 30 },    { 257, 31 },    { 258, 32 },
181cb93a386Sopenharmony_ci  { 259, 33 },    { 260, 34 },    { 261, 35 },    { 262, 36 },
182cb93a386Sopenharmony_ci  { 263, 37 },    { 264, 38 },    { 265, 39 },    { 266, 40 },
183cb93a386Sopenharmony_ci  { 267, 43 },    { 268, 44 },    { 269, 45 },    { 270, 46 },
184cb93a386Sopenharmony_ci  { 272, 47 },    { 300, 48 },    { 301, 49 },    { 302, 50 },
185cb93a386Sopenharmony_ci  { 305, 51 },    { 314, 52 },    { 315, 53 },    { 320, 57 },
186cb93a386Sopenharmony_ci  { 321, 58 },    { 322, 59 },    { 323, 60 },    { 324, 61 },
187cb93a386Sopenharmony_ci  { 325, 62 },    { 326, 63 },    { 327, 67 },    { 328, 68 },
188cb93a386Sopenharmony_ci  { 329, 69 },    { 330, 70 },    { 331, 71 },    { 332, 72 },
189cb93a386Sopenharmony_ci  { 333, 73 },    { 334, 74 },    { 335, 75 },    { 336, 76 },
190cb93a386Sopenharmony_ci  { 337, 77 },    { 338, 78 },    { 339, 79 },    { 340, 80 },
191cb93a386Sopenharmony_ci  { 341, 81 },    { 342, 82 },    { 343, 83 },    { 344, 84 },
192cb93a386Sopenharmony_ci  { 345, 85 },    { 346, 86 }
193cb93a386Sopenharmony_ci};
194cb93a386Sopenharmony_ci
195cb93a386Sopenharmony_ci/* code to SID */
196cb93a386Sopenharmony_cistatic const uint8_t standard_encoding_to_sid [] =
197cb93a386Sopenharmony_ci{
198cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
199cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
200cb93a386Sopenharmony_ci    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,   15,   16,
201cb93a386Sopenharmony_ci    17,  18,   19,   20,   21,   22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,
202cb93a386Sopenharmony_ci    33,  34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,   48,
203cb93a386Sopenharmony_ci    49,  50,   51,   52,   53,   54,   55,   56,   57,   58,   59,   60,   61,   62,   63,   64,
204cb93a386Sopenharmony_ci    65,  66,   67,   68,   69,   70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
205cb93a386Sopenharmony_ci    81,  82,   83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,   94,   95,    0,
206cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
207cb93a386Sopenharmony_ci    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
208cb93a386Sopenharmony_ci    0,   96,   97,   98,   99,  100,  101,  102,  103,  104,  105,  106,  107,  108,  109,  110,
209cb93a386Sopenharmony_ci    0,  111,  112,  113,  114,    0,  115,  116,  117,  118,  119,  120,  121,  122,    0,  123,
210cb93a386Sopenharmony_ci    0,  124,  125,  126,  127,  128,  129,  130,  131,    0,  132,  133,    0,  134,  135,  136,
211cb93a386Sopenharmony_ci  137,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
212cb93a386Sopenharmony_ci    0,   138,   0,  139,    0,    0,    0,    0,  140,  141,  142,  143,    0,    0,    0,    0,
213cb93a386Sopenharmony_ci    0,   144,   0,    0,    0,  145,    0,    0,  146,  147,  148,  149,    0,    0,    0,    0
214cb93a386Sopenharmony_ci};
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_standard_encoding_for_code (hb_codepoint_t sid)
217cb93a386Sopenharmony_ci{
218cb93a386Sopenharmony_ci  if (sid < ARRAY_LENGTH (standard_encoding_to_code))
219cb93a386Sopenharmony_ci    return (hb_codepoint_t)standard_encoding_to_code[sid];
220cb93a386Sopenharmony_ci  else
221cb93a386Sopenharmony_ci    return 0;
222cb93a386Sopenharmony_ci}
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_expert_encoding_for_code (hb_codepoint_t sid)
225cb93a386Sopenharmony_ci{
226cb93a386Sopenharmony_ci  if (sid < ARRAY_LENGTH (expert_encoding_to_code))
227cb93a386Sopenharmony_ci    return (hb_codepoint_t)expert_encoding_to_code[sid];
228cb93a386Sopenharmony_ci  else
229cb93a386Sopenharmony_ci    return 0;
230cb93a386Sopenharmony_ci}
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_expert_charset_for_sid (hb_codepoint_t glyph)
233cb93a386Sopenharmony_ci{
234cb93a386Sopenharmony_ci  if (glyph < ARRAY_LENGTH (expert_charset_to_sid))
235cb93a386Sopenharmony_ci    return (hb_codepoint_t)expert_charset_to_sid[glyph];
236cb93a386Sopenharmony_ci  else
237cb93a386Sopenharmony_ci    return 0;
238cb93a386Sopenharmony_ci}
239cb93a386Sopenharmony_ci
240cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph)
241cb93a386Sopenharmony_ci{
242cb93a386Sopenharmony_ci  if (glyph < ARRAY_LENGTH (expert_subset_charset_to_sid))
243cb93a386Sopenharmony_ci    return (hb_codepoint_t)expert_subset_charset_to_sid[glyph];
244cb93a386Sopenharmony_ci  else
245cb93a386Sopenharmony_ci    return 0;
246cb93a386Sopenharmony_ci}
247cb93a386Sopenharmony_ci
248cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_expert_charset_for_glyph (hb_codepoint_t sid)
249cb93a386Sopenharmony_ci{
250cb93a386Sopenharmony_ci  const auto *pair = hb_sorted_array (expert_charset_sid_to_gid).bsearch (sid);
251cb93a386Sopenharmony_ci  return pair ? pair->gid : 0;
252cb93a386Sopenharmony_ci}
253cb93a386Sopenharmony_ci
254cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_expert_subset_charset_for_glyph (hb_codepoint_t sid)
255cb93a386Sopenharmony_ci{
256cb93a386Sopenharmony_ci  const auto *pair = hb_sorted_array (expert_subset_charset_sid_to_gid).bsearch (sid);
257cb93a386Sopenharmony_ci  return pair ? pair->gid : 0;
258cb93a386Sopenharmony_ci}
259cb93a386Sopenharmony_ci
260cb93a386Sopenharmony_cihb_codepoint_t OT::cff1::lookup_standard_encoding_for_sid (hb_codepoint_t code)
261cb93a386Sopenharmony_ci{
262cb93a386Sopenharmony_ci  if (code < ARRAY_LENGTH (standard_encoding_to_sid))
263cb93a386Sopenharmony_ci    return (hb_codepoint_t)standard_encoding_to_sid[code];
264cb93a386Sopenharmony_ci  else
265cb93a386Sopenharmony_ci    return CFF_UNDEF_SID;
266cb93a386Sopenharmony_ci}
267cb93a386Sopenharmony_ci
268cb93a386Sopenharmony_cistruct bounds_t
269cb93a386Sopenharmony_ci{
270cb93a386Sopenharmony_ci  void init ()
271cb93a386Sopenharmony_ci  {
272cb93a386Sopenharmony_ci    min.set_int (INT_MAX, INT_MAX);
273cb93a386Sopenharmony_ci    max.set_int (INT_MIN, INT_MIN);
274cb93a386Sopenharmony_ci  }
275cb93a386Sopenharmony_ci
276cb93a386Sopenharmony_ci  void update (const point_t &pt)
277cb93a386Sopenharmony_ci  {
278cb93a386Sopenharmony_ci    if (pt.x < min.x) min.x = pt.x;
279cb93a386Sopenharmony_ci    if (pt.x > max.x) max.x = pt.x;
280cb93a386Sopenharmony_ci    if (pt.y < min.y) min.y = pt.y;
281cb93a386Sopenharmony_ci    if (pt.y > max.y) max.y = pt.y;
282cb93a386Sopenharmony_ci  }
283cb93a386Sopenharmony_ci
284cb93a386Sopenharmony_ci  void merge (const bounds_t &b)
285cb93a386Sopenharmony_ci  {
286cb93a386Sopenharmony_ci    if (empty ())
287cb93a386Sopenharmony_ci      *this = b;
288cb93a386Sopenharmony_ci    else if (!b.empty ())
289cb93a386Sopenharmony_ci    {
290cb93a386Sopenharmony_ci      if (b.min.x < min.x) min.x = b.min.x;
291cb93a386Sopenharmony_ci      if (b.max.x > max.x) max.x = b.max.x;
292cb93a386Sopenharmony_ci      if (b.min.y < min.y) min.y = b.min.y;
293cb93a386Sopenharmony_ci      if (b.max.y > max.y) max.y = b.max.y;
294cb93a386Sopenharmony_ci    }
295cb93a386Sopenharmony_ci  }
296cb93a386Sopenharmony_ci
297cb93a386Sopenharmony_ci  void offset (const point_t &delta)
298cb93a386Sopenharmony_ci  {
299cb93a386Sopenharmony_ci    if (!empty ())
300cb93a386Sopenharmony_ci    {
301cb93a386Sopenharmony_ci      min.move (delta);
302cb93a386Sopenharmony_ci      max.move (delta);
303cb93a386Sopenharmony_ci    }
304cb93a386Sopenharmony_ci  }
305cb93a386Sopenharmony_ci
306cb93a386Sopenharmony_ci  bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
307cb93a386Sopenharmony_ci
308cb93a386Sopenharmony_ci  point_t min;
309cb93a386Sopenharmony_ci  point_t max;
310cb93a386Sopenharmony_ci};
311cb93a386Sopenharmony_ci
312cb93a386Sopenharmony_cistruct cff1_extents_param_t
313cb93a386Sopenharmony_ci{
314cb93a386Sopenharmony_ci  void init (const OT::cff1::accelerator_t *_cff)
315cb93a386Sopenharmony_ci  {
316cb93a386Sopenharmony_ci    path_open = false;
317cb93a386Sopenharmony_ci    cff = _cff;
318cb93a386Sopenharmony_ci    bounds.init ();
319cb93a386Sopenharmony_ci  }
320cb93a386Sopenharmony_ci
321cb93a386Sopenharmony_ci  void start_path   ()       { path_open = true; }
322cb93a386Sopenharmony_ci  void end_path     ()       { path_open = false; }
323cb93a386Sopenharmony_ci  bool is_path_open () const { return path_open; }
324cb93a386Sopenharmony_ci
325cb93a386Sopenharmony_ci  bool path_open;
326cb93a386Sopenharmony_ci  bounds_t bounds;
327cb93a386Sopenharmony_ci
328cb93a386Sopenharmony_ci  const OT::cff1::accelerator_t *cff;
329cb93a386Sopenharmony_ci};
330cb93a386Sopenharmony_ci
331cb93a386Sopenharmony_cistruct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, cff1_extents_param_t>
332cb93a386Sopenharmony_ci{
333cb93a386Sopenharmony_ci  static void moveto (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt)
334cb93a386Sopenharmony_ci  {
335cb93a386Sopenharmony_ci    param.end_path ();
336cb93a386Sopenharmony_ci    env.moveto (pt);
337cb93a386Sopenharmony_ci  }
338cb93a386Sopenharmony_ci
339cb93a386Sopenharmony_ci  static void line (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1)
340cb93a386Sopenharmony_ci  {
341cb93a386Sopenharmony_ci    if (!param.is_path_open ())
342cb93a386Sopenharmony_ci    {
343cb93a386Sopenharmony_ci      param.start_path ();
344cb93a386Sopenharmony_ci      param.bounds.update (env.get_pt ());
345cb93a386Sopenharmony_ci    }
346cb93a386Sopenharmony_ci    env.moveto (pt1);
347cb93a386Sopenharmony_ci    param.bounds.update (env.get_pt ());
348cb93a386Sopenharmony_ci  }
349cb93a386Sopenharmony_ci
350cb93a386Sopenharmony_ci  static void curve (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
351cb93a386Sopenharmony_ci  {
352cb93a386Sopenharmony_ci    if (!param.is_path_open ())
353cb93a386Sopenharmony_ci    {
354cb93a386Sopenharmony_ci      param.start_path ();
355cb93a386Sopenharmony_ci      param.bounds.update (env.get_pt ());
356cb93a386Sopenharmony_ci    }
357cb93a386Sopenharmony_ci    /* include control points */
358cb93a386Sopenharmony_ci    param.bounds.update (pt1);
359cb93a386Sopenharmony_ci    param.bounds.update (pt2);
360cb93a386Sopenharmony_ci    env.moveto (pt3);
361cb93a386Sopenharmony_ci    param.bounds.update (env.get_pt ());
362cb93a386Sopenharmony_ci  }
363cb93a386Sopenharmony_ci};
364cb93a386Sopenharmony_ci
365cb93a386Sopenharmony_cistatic bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac=false);
366cb93a386Sopenharmony_ci
367cb93a386Sopenharmony_cistruct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, cff1_extents_param_t, cff1_path_procs_extents_t>
368cb93a386Sopenharmony_ci{
369cb93a386Sopenharmony_ci  static void process_seac (cff1_cs_interp_env_t &env, cff1_extents_param_t& param)
370cb93a386Sopenharmony_ci  {
371cb93a386Sopenharmony_ci    unsigned int  n = env.argStack.get_count ();
372cb93a386Sopenharmony_ci    point_t delta;
373cb93a386Sopenharmony_ci    delta.x = env.argStack[n-4];
374cb93a386Sopenharmony_ci    delta.y = env.argStack[n-3];
375cb93a386Sopenharmony_ci    hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
376cb93a386Sopenharmony_ci    hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
377cb93a386Sopenharmony_ci
378cb93a386Sopenharmony_ci    bounds_t  base_bounds, accent_bounds;
379cb93a386Sopenharmony_ci    if (likely (!env.in_seac && base && accent
380cb93a386Sopenharmony_ci	       && _get_bounds (param.cff, base, base_bounds, true)
381cb93a386Sopenharmony_ci	       && _get_bounds (param.cff, accent, accent_bounds, true)))
382cb93a386Sopenharmony_ci    {
383cb93a386Sopenharmony_ci      param.bounds.merge (base_bounds);
384cb93a386Sopenharmony_ci      accent_bounds.offset (delta);
385cb93a386Sopenharmony_ci      param.bounds.merge (accent_bounds);
386cb93a386Sopenharmony_ci    }
387cb93a386Sopenharmony_ci    else
388cb93a386Sopenharmony_ci      env.set_error ();
389cb93a386Sopenharmony_ci  }
390cb93a386Sopenharmony_ci};
391cb93a386Sopenharmony_ci
392cb93a386Sopenharmony_cibool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac)
393cb93a386Sopenharmony_ci{
394cb93a386Sopenharmony_ci  bounds.init ();
395cb93a386Sopenharmony_ci  if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
396cb93a386Sopenharmony_ci
397cb93a386Sopenharmony_ci  unsigned int fd = cff->fdSelect->get_fd (glyph);
398cb93a386Sopenharmony_ci  cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp;
399cb93a386Sopenharmony_ci  const byte_str_t str = (*cff->charStrings)[glyph];
400cb93a386Sopenharmony_ci  interp.env.init (str, *cff, fd);
401cb93a386Sopenharmony_ci  interp.env.set_in_seac (in_seac);
402cb93a386Sopenharmony_ci  cff1_extents_param_t  param;
403cb93a386Sopenharmony_ci  param.init (cff);
404cb93a386Sopenharmony_ci  if (unlikely (!interp.interpret (param))) return false;
405cb93a386Sopenharmony_ci  bounds = param.bounds;
406cb93a386Sopenharmony_ci  return true;
407cb93a386Sopenharmony_ci}
408cb93a386Sopenharmony_ci
409cb93a386Sopenharmony_cibool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
410cb93a386Sopenharmony_ci{
411cb93a386Sopenharmony_ci#ifdef HB_NO_OT_FONT_CFF
412cb93a386Sopenharmony_ci  /* XXX Remove check when this code moves to .hh file. */
413cb93a386Sopenharmony_ci  return true;
414cb93a386Sopenharmony_ci#endif
415cb93a386Sopenharmony_ci
416cb93a386Sopenharmony_ci  bounds_t bounds;
417cb93a386Sopenharmony_ci
418cb93a386Sopenharmony_ci  if (!_get_bounds (this, glyph, bounds))
419cb93a386Sopenharmony_ci    return false;
420cb93a386Sopenharmony_ci
421cb93a386Sopenharmony_ci  if (bounds.min.x >= bounds.max.x)
422cb93a386Sopenharmony_ci  {
423cb93a386Sopenharmony_ci    extents->width = 0;
424cb93a386Sopenharmony_ci    extents->x_bearing = 0;
425cb93a386Sopenharmony_ci  }
426cb93a386Sopenharmony_ci  else
427cb93a386Sopenharmony_ci  {
428cb93a386Sopenharmony_ci    extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ());
429cb93a386Sopenharmony_ci    extents->width = font->em_scalef_x (bounds.max.x.to_real ()) - extents->x_bearing;
430cb93a386Sopenharmony_ci  }
431cb93a386Sopenharmony_ci  if (bounds.min.y >= bounds.max.y)
432cb93a386Sopenharmony_ci  {
433cb93a386Sopenharmony_ci    extents->height = 0;
434cb93a386Sopenharmony_ci    extents->y_bearing = 0;
435cb93a386Sopenharmony_ci  }
436cb93a386Sopenharmony_ci  else
437cb93a386Sopenharmony_ci  {
438cb93a386Sopenharmony_ci    extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ());
439cb93a386Sopenharmony_ci    extents->height = font->em_scalef_y (bounds.min.y.to_real ()) - extents->y_bearing;
440cb93a386Sopenharmony_ci  }
441cb93a386Sopenharmony_ci
442cb93a386Sopenharmony_ci  return true;
443cb93a386Sopenharmony_ci}
444cb93a386Sopenharmony_ci
445cb93a386Sopenharmony_ci#ifdef HB_EXPERIMENTAL_API
446cb93a386Sopenharmony_cistruct cff1_path_param_t
447cb93a386Sopenharmony_ci{
448cb93a386Sopenharmony_ci  cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_,
449cb93a386Sopenharmony_ci		     draw_helper_t &draw_helper_, point_t *delta_)
450cb93a386Sopenharmony_ci  {
451cb93a386Sopenharmony_ci    draw_helper = &draw_helper_;
452cb93a386Sopenharmony_ci    cff = cff_;
453cb93a386Sopenharmony_ci    font = font_;
454cb93a386Sopenharmony_ci    delta = delta_;
455cb93a386Sopenharmony_ci  }
456cb93a386Sopenharmony_ci
457cb93a386Sopenharmony_ci  void move_to (const point_t &p)
458cb93a386Sopenharmony_ci  {
459cb93a386Sopenharmony_ci    point_t point = p;
460cb93a386Sopenharmony_ci    if (delta) point.move (*delta);
461cb93a386Sopenharmony_ci    draw_helper->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
462cb93a386Sopenharmony_ci  }
463cb93a386Sopenharmony_ci
464cb93a386Sopenharmony_ci  void line_to (const point_t &p)
465cb93a386Sopenharmony_ci  {
466cb93a386Sopenharmony_ci    point_t point = p;
467cb93a386Sopenharmony_ci    if (delta) point.move (*delta);
468cb93a386Sopenharmony_ci    draw_helper->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
469cb93a386Sopenharmony_ci  }
470cb93a386Sopenharmony_ci
471cb93a386Sopenharmony_ci  void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
472cb93a386Sopenharmony_ci  {
473cb93a386Sopenharmony_ci    point_t point1 = p1, point2 = p2, point3 = p3;
474cb93a386Sopenharmony_ci    if (delta)
475cb93a386Sopenharmony_ci    {
476cb93a386Sopenharmony_ci      point1.move (*delta);
477cb93a386Sopenharmony_ci      point2.move (*delta);
478cb93a386Sopenharmony_ci      point3.move (*delta);
479cb93a386Sopenharmony_ci    }
480cb93a386Sopenharmony_ci    draw_helper->cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()),
481cb93a386Sopenharmony_ci			   font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()),
482cb93a386Sopenharmony_ci			   font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ()));
483cb93a386Sopenharmony_ci  }
484cb93a386Sopenharmony_ci
485cb93a386Sopenharmony_ci  void end_path () { draw_helper->end_path (); }
486cb93a386Sopenharmony_ci
487cb93a386Sopenharmony_ci  hb_font_t *font;
488cb93a386Sopenharmony_ci  draw_helper_t *draw_helper;
489cb93a386Sopenharmony_ci  point_t *delta;
490cb93a386Sopenharmony_ci
491cb93a386Sopenharmony_ci  const OT::cff1::accelerator_t *cff;
492cb93a386Sopenharmony_ci};
493cb93a386Sopenharmony_ci
494cb93a386Sopenharmony_cistruct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_interp_env_t, cff1_path_param_t>
495cb93a386Sopenharmony_ci{
496cb93a386Sopenharmony_ci  static void moveto (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt)
497cb93a386Sopenharmony_ci  {
498cb93a386Sopenharmony_ci    param.move_to (pt);
499cb93a386Sopenharmony_ci    env.moveto (pt);
500cb93a386Sopenharmony_ci  }
501cb93a386Sopenharmony_ci
502cb93a386Sopenharmony_ci  static void line (cff1_cs_interp_env_t &env, cff1_path_param_t &param, const point_t &pt1)
503cb93a386Sopenharmony_ci  {
504cb93a386Sopenharmony_ci    param.line_to (pt1);
505cb93a386Sopenharmony_ci    env.moveto (pt1);
506cb93a386Sopenharmony_ci  }
507cb93a386Sopenharmony_ci
508cb93a386Sopenharmony_ci  static void curve (cff1_cs_interp_env_t &env, cff1_path_param_t &param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
509cb93a386Sopenharmony_ci  {
510cb93a386Sopenharmony_ci    param.cubic_to (pt1, pt2, pt3);
511cb93a386Sopenharmony_ci    env.moveto (pt3);
512cb93a386Sopenharmony_ci  }
513cb93a386Sopenharmony_ci};
514cb93a386Sopenharmony_ci
515cb93a386Sopenharmony_cistatic bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
516cb93a386Sopenharmony_ci		       draw_helper_t &draw_helper, bool in_seac = false, point_t *delta = nullptr);
517cb93a386Sopenharmony_ci
518cb93a386Sopenharmony_cistruct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
519cb93a386Sopenharmony_ci{
520cb93a386Sopenharmony_ci  static void process_seac (cff1_cs_interp_env_t &env, cff1_path_param_t& param)
521cb93a386Sopenharmony_ci  {
522cb93a386Sopenharmony_ci    /* End previous path */
523cb93a386Sopenharmony_ci    param.end_path ();
524cb93a386Sopenharmony_ci
525cb93a386Sopenharmony_ci    unsigned int n = env.argStack.get_count ();
526cb93a386Sopenharmony_ci    point_t delta;
527cb93a386Sopenharmony_ci    delta.x = env.argStack[n-4];
528cb93a386Sopenharmony_ci    delta.y = env.argStack[n-3];
529cb93a386Sopenharmony_ci    hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
530cb93a386Sopenharmony_ci    hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
531cb93a386Sopenharmony_ci
532cb93a386Sopenharmony_ci    if (unlikely (!(!env.in_seac && base && accent
533cb93a386Sopenharmony_ci		    && _get_path (param.cff, param.font, base, *param.draw_helper, true)
534cb93a386Sopenharmony_ci		    && _get_path (param.cff, param.font, accent, *param.draw_helper, true, &delta))))
535cb93a386Sopenharmony_ci      env.set_error ();
536cb93a386Sopenharmony_ci  }
537cb93a386Sopenharmony_ci};
538cb93a386Sopenharmony_ci
539cb93a386Sopenharmony_cibool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
540cb93a386Sopenharmony_ci		draw_helper_t &draw_helper, bool in_seac, point_t *delta)
541cb93a386Sopenharmony_ci{
542cb93a386Sopenharmony_ci  if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
543cb93a386Sopenharmony_ci
544cb93a386Sopenharmony_ci  unsigned int fd = cff->fdSelect->get_fd (glyph);
545cb93a386Sopenharmony_ci  cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp;
546cb93a386Sopenharmony_ci  const byte_str_t str = (*cff->charStrings)[glyph];
547cb93a386Sopenharmony_ci  interp.env.init (str, *cff, fd);
548cb93a386Sopenharmony_ci  interp.env.set_in_seac (in_seac);
549cb93a386Sopenharmony_ci  cff1_path_param_t param (cff, font, draw_helper, delta);
550cb93a386Sopenharmony_ci  if (unlikely (!interp.interpret (param))) return false;
551cb93a386Sopenharmony_ci
552cb93a386Sopenharmony_ci  /* Let's end the path specially since it is called inside seac also */
553cb93a386Sopenharmony_ci  param.end_path ();
554cb93a386Sopenharmony_ci
555cb93a386Sopenharmony_ci  return true;
556cb93a386Sopenharmony_ci}
557cb93a386Sopenharmony_ci
558cb93a386Sopenharmony_cibool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
559cb93a386Sopenharmony_ci{
560cb93a386Sopenharmony_ci#ifdef HB_NO_OT_FONT_CFF
561cb93a386Sopenharmony_ci  /* XXX Remove check when this code moves to .hh file. */
562cb93a386Sopenharmony_ci  return true;
563cb93a386Sopenharmony_ci#endif
564cb93a386Sopenharmony_ci
565cb93a386Sopenharmony_ci  return _get_path (this, font, glyph, draw_helper);
566cb93a386Sopenharmony_ci}
567cb93a386Sopenharmony_ci#endif
568cb93a386Sopenharmony_ci
569cb93a386Sopenharmony_cistruct get_seac_param_t
570cb93a386Sopenharmony_ci{
571cb93a386Sopenharmony_ci  void init (const OT::cff1::accelerator_t *_cff)
572cb93a386Sopenharmony_ci  {
573cb93a386Sopenharmony_ci    cff = _cff;
574cb93a386Sopenharmony_ci    base = 0;
575cb93a386Sopenharmony_ci    accent = 0;
576cb93a386Sopenharmony_ci  }
577cb93a386Sopenharmony_ci
578cb93a386Sopenharmony_ci  bool has_seac () const { return base && accent; }
579cb93a386Sopenharmony_ci
580cb93a386Sopenharmony_ci  const OT::cff1::accelerator_t *cff;
581cb93a386Sopenharmony_ci  hb_codepoint_t  base;
582cb93a386Sopenharmony_ci  hb_codepoint_t  accent;
583cb93a386Sopenharmony_ci};
584cb93a386Sopenharmony_ci
585cb93a386Sopenharmony_cistruct cff1_cs_opset_seac_t : cff1_cs_opset_t<cff1_cs_opset_seac_t, get_seac_param_t>
586cb93a386Sopenharmony_ci{
587cb93a386Sopenharmony_ci  static void process_seac (cff1_cs_interp_env_t &env, get_seac_param_t& param)
588cb93a386Sopenharmony_ci  {
589cb93a386Sopenharmony_ci    unsigned int  n = env.argStack.get_count ();
590cb93a386Sopenharmony_ci    hb_codepoint_t  base_char = (hb_codepoint_t)env.argStack[n-2].to_int ();
591cb93a386Sopenharmony_ci    hb_codepoint_t  accent_char = (hb_codepoint_t)env.argStack[n-1].to_int ();
592cb93a386Sopenharmony_ci
593cb93a386Sopenharmony_ci    param.base = param.cff->std_code_to_glyph (base_char);
594cb93a386Sopenharmony_ci    param.accent = param.cff->std_code_to_glyph (accent_char);
595cb93a386Sopenharmony_ci  }
596cb93a386Sopenharmony_ci};
597cb93a386Sopenharmony_ci
598cb93a386Sopenharmony_cibool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
599cb93a386Sopenharmony_ci{
600cb93a386Sopenharmony_ci  if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
601cb93a386Sopenharmony_ci
602cb93a386Sopenharmony_ci  unsigned int fd = fdSelect->get_fd (glyph);
603cb93a386Sopenharmony_ci  cff1_cs_interpreter_t<cff1_cs_opset_seac_t, get_seac_param_t> interp;
604cb93a386Sopenharmony_ci  const byte_str_t str = (*charStrings)[glyph];
605cb93a386Sopenharmony_ci  interp.env.init (str, *this, fd);
606cb93a386Sopenharmony_ci  get_seac_param_t  param;
607cb93a386Sopenharmony_ci  param.init (this);
608cb93a386Sopenharmony_ci  if (unlikely (!interp.interpret (param))) return false;
609cb93a386Sopenharmony_ci
610cb93a386Sopenharmony_ci  if (param.has_seac ())
611cb93a386Sopenharmony_ci  {
612cb93a386Sopenharmony_ci    *base = param.base;
613cb93a386Sopenharmony_ci    *accent = param.accent;
614cb93a386Sopenharmony_ci    return true;
615cb93a386Sopenharmony_ci  }
616cb93a386Sopenharmony_ci  return false;
617cb93a386Sopenharmony_ci}
618cb93a386Sopenharmony_ci
619cb93a386Sopenharmony_ci
620cb93a386Sopenharmony_ci#endif
621