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