1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  cffload.c                                                              */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    OpenType and CFF data/program tables loader (body).                  */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/*  Copyright 1996-2014 by                                                 */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TYPE1_TABLES_H
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cffload.h"
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cffparse.h"
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "cfferrs.h"
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
3377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_UShort  cff_isoadobe_charset[229] =
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   1,   2,   3,   4,   5,   6,   7,
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      8,   9,  10,  11,  12,  13,  14,  15,
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     16,  17,  18,  19,  20,  21,  22,  23,
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     24,  25,  26,  27,  28,  29,  30,  31,
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     32,  33,  34,  35,  36,  37,  38,  39,
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     40,  41,  42,  43,  44,  45,  46,  47,
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     48,  49,  50,  51,  52,  53,  54,  55,
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     56,  57,  58,  59,  60,  61,  62,  63,
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     64,  65,  66,  67,  68,  69,  70,  71,
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     72,  73,  74,  75,  76,  77,  78,  79,
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     80,  81,  82,  83,  84,  85,  86,  87,
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     88,  89,  90,  91,  92,  93,  94,  95,
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     96,  97,  98,  99, 100, 101, 102, 103,
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    104, 105, 106, 107, 108, 109, 110, 111,
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    112, 113, 114, 115, 116, 117, 118, 119,
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    120, 121, 122, 123, 124, 125, 126, 127,
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    128, 129, 130, 131, 132, 133, 134, 135,
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    136, 137, 138, 139, 140, 141, 142, 143,
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    144, 145, 146, 147, 148, 149, 150, 151,
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    152, 153, 154, 155, 156, 157, 158, 159,
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    160, 161, 162, 163, 164, 165, 166, 167,
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    168, 169, 170, 171, 172, 173, 174, 175,
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    176, 177, 178, 179, 180, 181, 182, 183,
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    184, 185, 186, 187, 188, 189, 190, 191,
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    192, 193, 194, 195, 196, 197, 198, 199,
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    200, 201, 202, 203, 204, 205, 206, 207,
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    208, 209, 210, 211, 212, 213, 214, 215,
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    216, 217, 218, 219, 220, 221, 222, 223,
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    224, 225, 226, 227, 228
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_UShort  cff_expert_charset[166] =
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   1, 229, 230, 231, 232, 233, 234,
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    235, 236, 237, 238,  13,  14,  15,  99,
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    239, 240, 241, 242, 243, 244, 245, 246,
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    247, 248,  27,  28, 249, 250, 251, 252,
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    253, 254, 255, 256, 257, 258, 259, 260,
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    261, 262, 263, 264, 265, 266, 109, 110,
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    267, 268, 269, 270, 271, 272, 273, 274,
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    275, 276, 277, 278, 279, 280, 281, 282,
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    283, 284, 285, 286, 287, 288, 289, 290,
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    291, 292, 293, 294, 295, 296, 297, 298,
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    299, 300, 301, 302, 303, 304, 305, 306,
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    307, 308, 309, 310, 311, 312, 313, 314,
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    315, 316, 317, 318, 158, 155, 163, 319,
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    320, 321, 322, 323, 324, 325, 326, 150,
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    164, 169, 327, 328, 329, 330, 331, 332,
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    333, 334, 335, 336, 337, 338, 339, 340,
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    341, 342, 343, 344, 345, 346, 347, 348,
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    349, 350, 351, 352, 353, 354, 355, 356,
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    357, 358, 359, 360, 361, 362, 363, 364,
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    365, 366, 367, 368, 369, 370, 371, 372,
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    373, 374, 375, 376, 377, 378
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_UShort  cff_expertsubset_charset[87] =
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   1, 231, 232, 235, 236, 237, 238,
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     13,  14,  15,  99, 239, 240, 241, 242,
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    243, 244, 245, 246, 247, 248,  27,  28,
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    249, 250, 251, 253, 254, 255, 256, 257,
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    258, 259, 260, 261, 262, 263, 264, 265,
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    266, 109, 110, 267, 268, 269, 270, 272,
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    300, 301, 302, 305, 314, 315, 158, 155,
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    163, 320, 321, 322, 323, 324, 325, 326,
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    150, 164, 169, 327, 328, 329, 330, 331,
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    332, 333, 334, 335, 336, 337, 338, 339,
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    340, 341, 342, 343, 344, 345, 346
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_UShort  cff_standard_encoding[256] =
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      1,   2,   3,   4,   5,   6,   7,   8,
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      9,  10,  11,  12,  13,  14,  15,  16,
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     17,  18,  19,  20,  21,  22,  23,  24,
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     25,  26,  27,  28,  29,  30,  31,  32,
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     33,  34,  35,  36,  37,  38,  39,  40,
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     41,  42,  43,  44,  45,  46,  47,  48,
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     49,  50,  51,  52,  53,  54,  55,  56,
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     57,  58,  59,  60,  61,  62,  63,  64,
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     65,  66,  67,  68,  69,  70,  71,  72,
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     73,  74,  75,  76,  77,  78,  79,  80,
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     81,  82,  83,  84,  85,  86,  87,  88,
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     89,  90,  91,  92,  93,  94,  95,   0,
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,  96,  97,  98,  99, 100, 101, 102,
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    103, 104, 105, 106, 107, 108, 109, 110,
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 111, 112, 113, 114,   0, 115, 116,
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    117, 118, 119, 120, 121, 122,   0, 123,
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 124, 125, 126, 127, 128, 129, 130,
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    131,   0, 132, 133,   0, 134, 135, 136,
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    137,   0,   0,   0,   0,   0,   0,   0,
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 138,   0, 139,   0,   0,   0,   0,
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    140, 141, 142, 143,   0,   0,   0,   0,
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 144,   0,   0,   0, 145,   0,   0,
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    146, 147, 148, 149,   0,   0,   0,   0
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_UShort  cff_expert_encoding[256] =
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      1, 229, 230,   0, 231, 232, 233, 234,
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    235, 236, 237, 238,  13,  14,  15,  99,
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    239, 240, 241, 242, 243, 244, 245, 246,
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    247, 248,  27,  28, 249, 250, 251, 252,
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 253, 254, 255, 256, 257,   0,   0,
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 258,   0,   0, 259, 260, 261, 262,
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0, 263, 264, 265,   0, 266, 109,
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    110, 267, 268, 269,   0, 270, 271, 272,
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    273, 274, 275, 276, 277, 278, 279, 280,
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    281, 282, 283, 284, 285, 286, 287, 288,
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    289, 290, 291, 292, 293, 294, 295, 296,
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    297, 298, 299, 300, 301, 302, 303,   0,
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0,   0,   0,   0,   0,   0,   0,
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0, 304, 305, 306,   0,   0, 307, 308,
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    309, 310, 311,   0, 312,   0,   0, 312,
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,   0, 314, 315,   0,   0, 316, 317,
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    318,   0,   0,   0, 158, 155, 163, 319,
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    320, 321, 322, 323, 324, 325,   0,   0,
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    326, 150, 164, 169, 327, 328, 329, 330,
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    331, 332, 333, 334, 335, 336, 337, 338,
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    339, 340, 341, 342, 343, 344, 345, 346,
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    347, 348, 349, 350, 351, 352, 353, 354,
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    355, 356, 357, 358, 359, 360, 361, 362,
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    363, 364, 365, 366, 367, 368, 369, 370,
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    371, 372, 373, 374, 375, 376, 377, 378
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
17877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 1 */
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_UShort )
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_get_standard_encoding( FT_UInt  charcode )
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       : 0 );
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_cffload
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* read an offset from the index's stream current position */
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_ULong
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_read_offset( CFF_Index  idx,
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Error  *errorp )
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream = idx->stream;
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte    tmp[4];
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   result = 0;
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  nn;
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( nn = 0; nn < idx->off_size; nn++ )
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = ( result << 8 ) | tmp[nn];
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *errorp = error;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_init( CFF_Index  idx,
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Stream  stream,
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Bool    load )
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  count;
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( idx, sizeof ( *idx ) );
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    idx->stream = stream;
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    idx->start  = FT_STREAM_POS();
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_READ_USHORT( count ) &&
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         count > 0                )
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte   offsize;
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  size;
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* there is at least one element; read the offset size,           */
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* then access the offset table to compute the index's total size */
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_BYTE( offsize ) )
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( offsize < 1 || offsize > 4 )
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
253727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Table );
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      idx->count    = count;
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      idx->off_size = offsize;
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size          = (FT_ULong)( count + 1 ) * offsize;
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      idx->data_offset = idx->start + 3 + size;
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SKIP( size - offsize ) )
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size = cff_index_read_offset( idx, &error );
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( size == 0 )
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Table );
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      idx->data_size = --size;
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( load )
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* load the data */
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* skip the data */
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_SKIP( size ) )
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( idx->offsets );
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_done( CFF_Index  idx )
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx->stream )
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = idx->stream;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( idx->bytes )
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_RELEASE( idx->bytes );
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( idx->offsets );
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_ZERO( idx, sizeof ( *idx ) );
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_load_offsets( CFF_Index  idx )
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_Err_Ok;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream = idx->stream;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx->count > 0 && idx->offsets == NULL )
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte    offsize = idx->off_size;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong   data_size;
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*   p;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Byte*   p_end;
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong*  poff;
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      data_size = (FT_ULong)( idx->count + 1 ) * offsize;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_STREAM_SEEK( idx->start + 3 )             ||
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_FRAME_ENTER( data_size )                  )
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      poff   = idx->offsets;
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p      = (FT_Byte*)stream->cursor;
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p_end  = p + data_size;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( offsize )
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; p < p_end; p++, poff++ )
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          poff[0] = p[0];
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; p < p_end; p += 2, poff++ )
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          poff[0] = FT_PEEK_USHORT( p );
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 3:
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; p < p_end; p += 3, poff++ )
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          poff[0] = FT_PEEK_OFF3( p );
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; p < p_end; p += 4, poff++ )
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          poff[0] = FT_PEEK_ULONG( p );
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_EXIT();
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( idx->offsets );
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* Allocate a table containing pointers to an index's elements. */
380aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* The `pool' argument makes this function convert the index    */
381aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* entries to C-style strings (this is, NULL-terminated).       */
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_get_pointers( CFF_Index   idx,
384aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                          FT_Byte***  table,
385aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                          FT_Byte**   pool )
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
387727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error     = FT_Err_Ok;
388aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Memory  memory    = idx->stream->memory;
389727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
390727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Byte**  t         = NULL;
391aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Byte*   new_bytes = NULL;
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    *table = NULL;
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx->offsets == NULL )
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_load_offsets( idx );
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( idx->count > 0                                        &&
404aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !FT_NEW_ARRAY( t, idx->count + 1 )                    &&
405aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         ( !pool || !FT_ALLOC( new_bytes,
406aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                               idx->data_size + idx->count ) ) )
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
408aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ULong  n, cur_offset;
409aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ULong  extra = 0;
410aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_Byte*  org_bytes = idx->bytes;
411aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
412aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
413aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* at this point, `idx->offsets' can't be NULL */
414aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      cur_offset = idx->offsets[0] - 1;
415aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
416aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* sanity check */
417ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( cur_offset != 0 )
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
419aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_TRACE0(( "cff_index_get_pointers:"
420aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                    " invalid first offset value %d set to zero\n",
421aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                    cur_offset ));
422aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        cur_offset = 0;
423aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
425aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( !pool )
426aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        t[0] = org_bytes + cur_offset;
427aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
428aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        t[0] = new_bytes + cur_offset;
429aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
430aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      for ( n = 1; n <= idx->count; n++ )
431aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
432aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_ULong  next_offset = idx->offsets[n] - 1;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
435ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* two sanity checks for invalid offset tables */
436ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        if ( next_offset < cur_offset )
437aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          next_offset = cur_offset;
438ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        else if ( next_offset > idx->data_size )
439ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          next_offset = idx->data_size;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( !pool )
442aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          t[n] = org_bytes + next_offset;
443aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        else
444aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
445aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          t[n] = new_bytes + next_offset + extra;
446aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
447aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( next_offset != cur_offset )
448aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
449aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
450aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            t[n][0] = '\0';
451aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            t[n]   += 1;
452aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            extra++;
453aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
454aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
455aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
456aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        cur_offset = next_offset;
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *table = t;
459aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
460aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( pool )
461aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        *pool = new_bytes;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_access_element( CFF_Index  idx,
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_UInt    element,
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Byte**  pbytes,
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_ULong*  pbyte_len )
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
475727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error  error = FT_Err_Ok;
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx && idx->count > element )
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute start and end offsets */
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = idx->stream;
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong   off1, off2 = 0;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* load offsets from file or the offset table */
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !idx->offsets )
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ULong  pos = element * idx->off_size;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        off1 = cff_index_read_offset( idx, &error );
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( off1 != 0 )
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          do
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            element++;
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            off2 = cff_index_read_offset( idx, &error );
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( off2 == 0 && element < idx->count );
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else   /* use offsets table */
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        off1 = idx->offsets[element];
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( off1 )
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          do
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            element++;
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            off2 = idx->offsets[element];
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          } while ( off2 == 0 && element < idx->count );
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
5227f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* XXX: should check off2 does not exceed the end of this entry; */
5237f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /*      at present, only truncate off2 at the end of this stream */
5247f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( off2 > stream->size + 1                    ||
5257f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner           idx->data_offset > stream->size - off2 + 1 )
5267f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
5277f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        FT_ERROR(( "cff_index_access_element:"
5287f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                   " offset to next entry (%d)"
5297f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                   " exceeds the end of stream (%d)\n",
5307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                   off2, stream->size - idx->data_offset + 1 ));
5317f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        off2 = stream->size - idx->data_offset + 1;
5327f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      }
5337f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* access element */
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( off1 && off2 > off1 )
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *pbyte_len = off2 - off1;
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( idx->bytes )
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* this index was completely loaded in memory, that's easy */
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *pbytes = idx->bytes + off1 - 1;
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* this index is still on disk/file, access it through a frame */
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* empty index element */
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *pbytes    = 0;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *pbyte_len = 0;
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
560727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_forget_element( CFF_Index  idx,
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Byte**  pbytes )
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx->bytes == 0 )
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = idx->stream;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_RELEASE( *pbytes );
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* get an entry from Name INDEX */
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_String* )
583aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  cff_index_get_name( CFF_Font  font,
584aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                      FT_UInt   element )
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
586aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    CFF_Index   idx = &font->name_index;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory   memory = idx->stream->memory;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*    bytes;
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong    byte_len;
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_String*  name = 0;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_access_element( idx, element, &bytes, &byte_len );
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( name, byte_len + 1 ) )
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( name, bytes, byte_len );
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      name[byte_len] = 0;
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_forget_element( idx, &bytes );
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return name;
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
610aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* get an entry from String INDEX */
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_String* )
612aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  cff_index_get_string( CFF_Font  font,
613aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                        FT_UInt   element )
614aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
615aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return ( element < font->num_strings )
616aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich             ? (FT_String*)font->strings[element]
617aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich             : NULL;
618aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
619aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
620aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
621aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_LOCAL_DEF( FT_String* )
622aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  cff_index_get_sid_string( CFF_Font  font,
623aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                            FT_UInt   sid )
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* value 0xFFFFU indicates a missing dictionary entry */
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sid == 0xFFFFU )
627aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return NULL;
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is not a standard string, return it */
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sid > 390 )
631aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return cff_index_get_string( font, sid - 391 );
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* CID-keyed CFF fonts don't have glyph names */
634aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !font->psnames )
635aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return NULL;
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
637aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /* this is a standard string */
638aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return (FT_String *)font->psnames->adobe_std_strings( sid );
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***   FD Select table support                                         ***/
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Stream     stream )
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( fdselect->data )
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_RELEASE( fdselect->data );
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->data_size   = 0;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->format      = 0;
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->range_count = 0;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt       num_glyphs,
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Stream     stream,
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong      offset )
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   format;
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   num_ranges;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read format */
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->format      = format;
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->cache_count = 0;   /* clear cache */
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( format )
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 0:     /* format 0, that's simple */
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fdselect->data_size = num_glyphs;
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Load_Data;
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 3:     /* format 3, a tad more complex */
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_USHORT( num_ranges ) )
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
6929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      if ( !num_ranges )
6939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      {
6949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
6959c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        error = FT_THROW( Invalid_File_Format );
6969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        goto Exit;
6979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      }
6989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fdselect->data_size = num_ranges * 3 + 2;
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Load_Data:
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:    /* hmm... that's wrong */
707727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_File_Format );
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Byte )
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_fd_select_get( CFF_FDSelect  fdselect,
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt       glyph_index )
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte  fd = 0;
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( fdselect->format )
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 0:
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fd = fdselect->data[glyph_index];
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 3:
7299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      /* first, compare to the cache */
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        fdselect->cache_count )
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        fd = fdselect->cache_fd;
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      /* then, look up the ranges array */
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  p       = fdselect->data;
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  p_limit = p + fdselect->data_size;
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte   fd2;
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt   first, limit;
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        first = FT_NEXT_USHORT( p );
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        do
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( glyph_index < first )
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          fd2   = *p++;
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit = FT_NEXT_USHORT( p );
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( glyph_index < limit )
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fd = fd2;
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* update cache */
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fdselect->cache_first = first;
7609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod            fdselect->cache_count = limit - first;
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fdselect->cache_fd    = fd2;
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          first = limit;
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        } while ( p < p_limit );
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ;
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return fd;
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***   CFF font support                                                ***/
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_compute_cids( CFF_Charset  charset,
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_UInt      num_glyphs,
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Memory    memory )
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
791727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error   = FT_Err_Ok;
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    i;
793295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Long    j;
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  max_cid = 0;
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( charset->max_cid > 0 )
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < num_glyphs; i++ )
8017f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    {
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charset->sids[i] > max_cid )
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max_cid = charset->sids[i];
8047f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    }
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
8067f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
809295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* When multiple GIDs map to the same CID, we choose the lowest */
810295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* GID.  This is not described in any spec, but it matches the  */
811295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* behaviour of recent Acroread versions.                       */
812295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    for ( j = num_glyphs - 1; j >= 0 ; j-- )
813295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      charset->cids[charset->sids[j]] = (FT_UShort)j;
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->max_cid    = max_cid;
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->num_glyphs = num_glyphs;
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_UInt )
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_cid_to_gindex( CFF_Charset  charset,
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_UInt      cid )
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
8307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    if ( cid <= charset->max_cid )
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = charset->cids[cid];
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_free_cids( CFF_Charset  charset,
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Memory    memory )
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( charset->cids );
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->max_cid = 0;
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_done( CFF_Charset  charset,
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream    stream )
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_charset_free_cids( charset, memory );
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( charset->sids );
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->format = 0;
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->offset = 0;
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_load( CFF_Charset  charset,
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt      num_glyphs,
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream    stream,
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong     base_offset,
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong     offset,
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Bool      invert )
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
870727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_Err_Ok;
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  glyph_sid;
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the the offset is greater than 2, we have to parse the */
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* charset table.                                            */
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( offset > 2 )
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  j;
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->offset = base_offset + offset;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Get the format of the table. */
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( charset->offset ) ||
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_BYTE( charset->format )   )
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Allocate memory for sids. */
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* assign the .notdef glyph */
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->sids[0] = 0;
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( charset->format )
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 0 )
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = 1; j < num_glyphs; j++ )
9047f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner            charset->sids[j] = FT_GET_USHORT();
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_EXIT();
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  nleft;
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  i;
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          j = 1;
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( j < num_glyphs )
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the first glyph sid of the range. */
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( FT_READ_USHORT( glyph_sid ) )
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the number of glyphs in the range.  */
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( charset->format == 2 )
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( FT_READ_USHORT( nleft ) )
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( FT_READ_BYTE( nleft ) )
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
937295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            /* try to rescue some of the SIDs if `nleft' is too large */
9387f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner            if ( glyph_sid > 0xFFFFL - nleft )
939aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            {
9407f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner              FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
9417f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                         " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
9427f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner              nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
943295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            }
944295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Fill in the range of sids -- `nleft + 1' glyphs. */
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              charset->sids[j] = glyph_sid;
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
953295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
954727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_File_Format );
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* CFF specification intimates the following:                   */
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                              */
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* In order to use a predefined charset, the following must be  */
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* true: The charset constructed for the glyphs in the font's   */
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* charstrings dictionary must match the predefined charset in  */
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* the first num_glyphs.                                        */
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->offset = offset;  /* record charset type */
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( (FT_UInt)offset )
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 229 )
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
976295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     "predefined charset (Adobe ISO-Latin)\n" ));
977727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error = FT_THROW( Invalid_File_Format );
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Allocate memory for sids. */
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Copy the predefined charset into the allocated memory. */
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 166 )
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
994295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     "predefined charset (Adobe Expert)\n" ));
995727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error = FT_THROW( Invalid_File_Format );
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Allocate memory for sids. */
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Copy the predefined charset into the allocated memory.     */
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 87 )
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1012295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     "predefined charset (Adobe Expert Subset)\n" ));
1013727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          error = FT_THROW( Invalid_File_Format );
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Allocate memory for sids. */
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Copy the predefined charset into the allocated memory.     */
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1027727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_File_Format );
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( invert )
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_charset_compute_cids( charset, num_glyphs, memory );
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Clean up if there was an error. */
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( charset->sids );
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( charset->cids );
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->format = 0;
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->offset = 0;
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->sids   = 0;
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_encoding_done( CFF_Encoding  encoding )
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    encoding->format = 0;
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    encoding->offset = 0;
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    encoding->count  = 0;
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_encoding_load( CFF_Encoding  encoding,
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     CFF_Charset   charset,
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt       num_glyphs,
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream     stream,
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong      base_offset,
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong      offset )
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1068727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error = FT_Err_Ok;
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    count;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    j;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  glyph_sid;
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    glyph_code;
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check for charset->sids.  If we do not have this, we fail. */
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charset->sids )
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1078727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_File_Format );
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Zero out the code to gid/sid mappings. */
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( j = 0; j < 256; j++ )
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      encoding->sids [j] = 0;
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      encoding->codes[j] = 0;
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the first encoded glyph index is 1.  Hence, we read the character  */
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* code (`glyph_code') at index j and make the assignment:            */
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*    encoding->codes[glyph_code] = j + 1                             */
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We also make the assignment:                                       */
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This gives us both a code to GID and a code to SID mapping.        */
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( offset > 1 )
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      encoding->offset = base_offset + offset;
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we need to parse the table to determine its size */
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( encoding->offset ) ||
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_BYTE( encoding->format )   ||
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_BYTE( count )              )
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( encoding->format & 0x7F )
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  p;
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* By convention, GID 0 is always ".notdef" and is never */
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* coded in the font.  Hence, the number of codes found  */
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* in the table is `count+1'.                            */
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /*                                                       */
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          encoding->count = count + 1;
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_FRAME_ENTER( count ) )
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p = (FT_Byte*)stream->cursor;
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = 1; j <= count; j++ )
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            glyph_code = *p++;
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Make sure j is not too big. */
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( j < num_glyphs )
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              /* Assign code to GID mapping. */
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->codes[glyph_code] = (FT_UShort)j;
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              /* Assign code to SID mapping. */
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->sids[glyph_code] = charset->sids[j];
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_EXIT();
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  nleft;
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  i = 1;
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  k;
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          encoding->count = 0;
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Parse the Format1 ranges. */
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = 0;  j < count; j++, i += nleft )
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the first glyph code of the range. */
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( FT_READ_BYTE( glyph_code ) )
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the number of codes in the range. */
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( FT_READ_BYTE( nleft ) )
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Increment nleft, so we read `nleft + 1' codes/sids. */
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            nleft++;
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* compute max number of character codes */
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( (FT_UInt)nleft > encoding->count )
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->count = nleft;
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Fill in the range of codes/sids. */
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( k = i; k < nleft + i; k++, glyph_code++ )
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              /* Make sure k is not too big. */
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( k < num_glyphs && glyph_code < 256 )
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                /* Assign code to GID mapping. */
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                encoding->codes[glyph_code] = (FT_UShort)k;
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                /* Assign code to SID mapping. */
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                encoding->sids[glyph_code] = charset->sids[k];
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* simple check; one never knows what can be found in a font */
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( encoding->count > 256 )
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->count = 256;
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1197295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1198727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_File_Format );
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Parse supplemental encodings, if any. */
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( encoding->format & 0x80 )
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt  gindex;
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* count supplements */
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_READ_BYTE( count ) )
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( j = 0; j < count; j++ )
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Read supplemental glyph code. */
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_READ_BYTE( glyph_code ) )
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Read the SID associated with this glyph code. */
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_READ_USHORT( glyph_sid ) )
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Assign code to SID mapping. */
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          encoding->sids[glyph_code] = glyph_sid;
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* First, look up GID which has been assigned to */
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* SID glyph_sid.                                */
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( gindex = 0; gindex < num_glyphs; gindex++ )
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( charset->sids[gindex] == glyph_sid )
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->codes[glyph_code] = (FT_UShort)gindex;
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* We take into account the fact a CFF font can use a predefined */
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* encoding without containing all of the glyphs encoded by this */
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* encoding (see the note at the end of section 12 in the CFF    */
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* specification).                                               */
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( (FT_UInt)offset )
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* First, copy the code to SID mapping. */
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Populate;
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* First, copy the code to SID mapping. */
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Populate:
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Construct code to GID mapping from code to SID mapping */
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* and charset.                                           */
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        encoding->count = 0;
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = cff_charset_compute_cids( charset, num_glyphs,
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          stream->memory );
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( j = 0; j < 256; j++ )
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  sid = encoding->sids[j];
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  gid = 0;
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( sid )
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            gid = cff_charset_cid_to_gindex( charset, sid );
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( gid != 0 )
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->codes[j] = (FT_UShort)gid;
1279bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            encoding->count    = j + 1;
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->codes[j] = 0;
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->sids [j] = 0;
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1290295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1291727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_File_Format );
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Clean up if there was an error. */
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_subfont_load( CFF_SubFont  font,
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    CFF_Index    idx,
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt      font_index,
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream    stream,
1308295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    FT_ULong     base_offset,
1309295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    FT_Library   library )
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_ParserRec    parser;
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*         dict = NULL;
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         dict_len;
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  top  = &font->font_dict;
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_Private      priv = &font->private_dict;
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1319295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set defaults */
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( top, sizeof ( *top ) );
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1324727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    top->underline_position  = -( 100L << 16 );
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->underline_thickness = 50L << 16;
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->charstring_type     = 2;
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->font_matrix.xx      = 0x10000L;
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->font_matrix.yy      = 0x10000L;
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_count           = 8720;
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we use the implementation specific SID value 0xFFFF to indicate */
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* missing entries                                                 */
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->version             = 0xFFFFU;
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->notice              = 0xFFFFU;
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->copyright           = 0xFFFFU;
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->full_name           = 0xFFFFU;
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->family_name         = 0xFFFFU;
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->weight              = 0xFFFFU;
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->embedded_postscript = 0xFFFFU;
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_registry        = 0xFFFFU;
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_ordering        = 0xFFFFU;
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_font_name       = 0xFFFFU;
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1347bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
1348bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " top dictionary:\n" ));
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_parser_run( &parser, dict, dict + dict_len );
1350bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_forget_element( idx, &dict );
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is a CID font, we stop there */
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( top->cid_registry != 0xFFFFU )
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* parse the private dictionary, if any */
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( top->private_offset && top->private_size )
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* set defaults */
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_ZERO( priv, sizeof ( *priv ) );
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->blue_shift       = 7;
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->blue_fuzz        = 1;
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->lenIV            = -1;
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1373295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_FRAME_ENTER( font->font_dict.private_size )                 )
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1379bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " private dictionary:\n" ));
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_parser_run( &parser,
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              (FT_Byte*)stream->cursor,
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              (FT_Byte*)stream->limit );
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_EXIT();
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* ensure that `num_blue_values' is even */
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->num_blue_values &= ~1;
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the local subrs, if any */
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( priv->local_subrs_offset )
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           priv->local_subrs_offset ) )
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_init( &font->local_subrs_index, stream, 1 );
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_get_pointers( &font->local_subrs_index,
1403aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                      &font->local_subrs, NULL );
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_subfont_done( FT_Memory    memory,
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    CFF_SubFont  subfont )
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( subfont )
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cff_index_done( &subfont->local_subrs_index );
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( subfont->local_subrs );
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1426295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  cff_font_load( FT_Library library,
1427295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 FT_Stream  stream,
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Int     face_index,
142977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                 CFF_Font   font,
143077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                 FT_Bool    pure_cff )
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  cff_header_fields[] =
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  CFF_FontRec
1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 4 ),
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( version_major ),
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( version_minor ),
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( header_size ),
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( absolute_offsize ),
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory = stream->memory;
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         base_offset;
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict;
1449aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    CFF_IndexRec     string_index;
1450727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Int           subfont_index;
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( font );
1454aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ZERO( &string_index );
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    font->stream = stream;
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    font->memory = memory;
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dict         = &font->top_font.font_dict;
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base_offset  = FT_STREAM_POS();
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read CFF font header */
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check format */
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( font->version_major   != 1 ||
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         font->header_size      < 4 ||
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         font->absolute_offsize > 4 )
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
147041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      FT_TRACE2(( "  not a CFF font header\n" ));
1471727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Unknown_File_Format );
1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* skip the rest of the header */
1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the name, top dict, string and global subrs index */
1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1481aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 0 ) )                  ||
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1483aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 0 ) )                  ||
1484aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_SET_ERROR( cff_index_init( &string_index,
1485aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 1 ) )                  ||
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1487aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 1 ) )                  ||
1488aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_SET_ERROR( cff_index_get_pointers( &string_index,
1489aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                               &font->strings,
1490aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                               &font->string_pool ) ) )
1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1493aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    font->num_strings = string_index.count;
1494aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( pure_cff )
1496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
1497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* well, we don't really forget the `disabled' fonts... */
1498727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      subfont_index = face_index;
1499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( subfont_index >= (FT_Int)font->name_index.count )
1501727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
1502727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_ERROR(( "cff_font_load:"
1503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   " invalid subfont index for pure CFF font (%d)\n",
1504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   subfont_index ));
1505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Argument );
1506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Exit;
1507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
1508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      font->num_faces = font->name_index.count;
1510727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
1511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    else
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      subfont_index = 0;
1514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( font->name_index.count > 1 )
1516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
1517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_ERROR(( "cff_font_load:"
1518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   " invalid CFF font with multiple subfonts\n"
1519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   "              "
1520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   " in SFNT wrapper\n" ));
1521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_File_Format );
1522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Exit;
1523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in case of a font format check, simply exit now */
1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index < 0 )
1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, parse the top-level font dictionary */
1531bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE4(( "parsing top-level\n" ));
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_subfont_load( &font->top_font,
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              &font->font_dict_index,
1534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                              subfont_index,
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              stream,
1536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                              base_offset,
1537295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                              library );
1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_init( &font->charstrings_index, stream, 0 );
1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, check for a CID font */
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dict->cid_registry != 0xFFFFU )
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      CFF_IndexRec  fd_index;
1552aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      CFF_SubFont   sub = NULL;
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt       idx;
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* this is a CID-keyed font, we must now allocate a table of */
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* sub-fonts, then load each of them separately              */
1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_init( &fd_index, stream, 0 );
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fd_index.count > CFF_MAX_CID_FONTS )
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1567295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail_CID;
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate & read each font dict independently */
1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      font->num_subfonts = fd_index.count;
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail_CID;
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* set up pointer table */
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( idx = 0; idx < fd_index.count; idx++ )
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        font->subfonts[idx] = sub + idx;
1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now load each subfont independently */
1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( idx = 0; idx < fd_index.count; idx++ )
1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sub = font->subfonts[idx];
1584bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE4(( "parsing subfont %u\n", idx ));
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = cff_subfont_load( sub, &fd_index, idx,
1586295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  stream, base_offset, library );
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail_CID;
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now load the FD Select array */
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Load_FD_Select( &font->fd_select,
1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  font->charstrings_index.count,
1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  stream,
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  base_offset + dict->cid_fd_select_offset );
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Fail_CID:
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cff_index_done( &fd_index );
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      font->num_subfonts = 0;
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the charstrings index now */
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dict->charstrings_offset == 0 )
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1609295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
1610727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_File_Format );
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1614aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    font->num_glyphs = font->charstrings_index.count;
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_get_pointers( &font->global_subrs_index,
1617aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                    &font->global_subrs, NULL );
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the Charset and Encoding tables if available */
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( font->num_glyphs > 0 )
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
162577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                base_offset, dict->charset_offset, invert );
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* CID-keyed CFFs don't have an encoding */
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dict->cid_registry == 0xFFFFU )
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = cff_encoding_load( &font->encoding,
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   &font->charset,
1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   font->num_glyphs,
1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   stream,
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   base_offset,
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   dict->encoding_offset );
1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get the font name (/CIDFontName for CID-keyed fonts, */
1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* /FontName otherwise)                                 */
1649727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    font->font_name = cff_index_get_name( font, subfont_index );
1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1652aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    cff_index_done( &string_index );
1653aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_font_done( CFF_Font  font )
1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = font->memory;
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    idx;
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->global_subrs_index );
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->font_dict_index );
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->name_index );
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->charstrings_index );
1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* release font dictionaries, but only if working with */
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* a CID keyed CFF font                                */
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( font->num_subfonts > 0 )
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( idx = 0; idx < font->num_subfonts; idx++ )
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cff_subfont_done( memory, font->subfonts[idx] );
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* the subfonts array has been allocated as a single block */
1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( font->subfonts[0] );
1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_encoding_done( &font->encoding );
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_charset_done( &font->charset, font->stream );
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_subfont_done( memory, &font->top_font );
1685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_Done_FD_Select( &font->fd_select, font->stream );
1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1688aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->font_info );
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( font->font_name );
1691aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->global_subrs );
1692aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->strings );
1693aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->string_pool );
1694727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1695727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( font->cf2_instance.finalizer )
1696727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
1697727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      font->cf2_instance.finalizer( font->cf2_instance.data );
1698727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_FREE( font->cf2_instance.data );
1699727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1704