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/*                                                                         */
7bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly/*  Copyright 1996-2011 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      {
253aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        error = CFF_Err_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      {
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = CFF_Err_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  {
32177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error  = CFF_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  {
387aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Error   error     = CFF_Err_Ok;
388aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Memory  memory    = idx->stream->memory;
389aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte**  t = NULL;
390aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Byte*   new_bytes = NULL;
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
393aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    *table = NULL;
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx->offsets == NULL )
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_load_offsets( idx );
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
402aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( idx->count > 0                                        &&
403aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !FT_NEW_ARRAY( t, idx->count + 1 )                    &&
404aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         ( !pool || !FT_ALLOC( new_bytes,
405aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                               idx->data_size + idx->count ) ) )
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
407aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ULong  n, cur_offset;
408aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ULong  extra = 0;
409aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_Byte*  org_bytes = idx->bytes;
410aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
411aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
412aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* at this point, `idx->offsets' can't be NULL */
413aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      cur_offset = idx->offsets[0] - 1;
414aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
415aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* sanity check */
416aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( cur_offset >= idx->data_size )
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
418aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_TRACE0(( "cff_index_get_pointers:"
419aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                    " invalid first offset value %d set to zero\n",
420aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                    cur_offset ));
421aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        cur_offset = 0;
422aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( !pool )
425aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        t[0] = org_bytes + cur_offset;
426aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
427aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        t[0] = new_bytes + cur_offset;
428aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
429aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      for ( n = 1; n <= idx->count; n++ )
430aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
431aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_ULong  next_offset = idx->offsets[n] - 1;
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* empty slot + two sanity checks for invalid offset tables */
435aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( next_offset == 0                                    ||
436aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich             next_offset < cur_offset                            ||
437aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich             ( next_offset >= idx->data_size && n < idx->count ) )
438aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          next_offset = cur_offset;
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( !pool )
441aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          t[n] = org_bytes + next_offset;
442aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        else
443aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
444aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          t[n] = new_bytes + next_offset + extra;
445aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
446aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( next_offset != cur_offset )
447aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
448aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
449aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            t[n][0] = '\0';
450aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            t[n]   += 1;
451aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            extra++;
452aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
453aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
454aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
455aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        cur_offset = next_offset;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *table = t;
458aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
459aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( pool )
460aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        *pool = new_bytes;
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_access_element( CFF_Index  idx,
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_UInt    element,
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Byte**  pbytes,
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_ULong*  pbyte_len )
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = CFF_Err_Ok;
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx && idx->count > element )
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute start and end offsets */
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = idx->stream;
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong   off1, off2 = 0;
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* load offsets from file or the offset table */
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !idx->offsets )
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ULong  pos = element * idx->off_size;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        off1 = cff_index_read_offset( idx, &error );
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( off1 != 0 )
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          do
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            element++;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            off2 = cff_index_read_offset( idx, &error );
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( off2 == 0 && element < idx->count );
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else   /* use offsets table */
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        off1 = idx->offsets[element];
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( off1 )
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          do
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            element++;
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            off2 = idx->offsets[element];
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          } while ( off2 == 0 && element < idx->count );
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
5217f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* XXX: should check off2 does not exceed the end of this entry; */
5227f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /*      at present, only truncate off2 at the end of this stream */
5237f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( off2 > stream->size + 1                    ||
5247f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner           idx->data_offset > stream->size - off2 + 1 )
5257f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
5267f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        FT_ERROR(( "cff_index_access_element:"
5277f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                   " offset to next entry (%d)"
5287f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                   " exceeds the end of stream (%d)\n",
5297f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                   off2, stream->size - idx->data_offset + 1 ));
5307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        off2 = stream->size - idx->data_offset + 1;
5317f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      }
5327f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* access element */
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( off1 && off2 > off1 )
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *pbyte_len = off2 - off1;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( idx->bytes )
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* this index was completely loaded in memory, that's easy */
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *pbytes = idx->bytes + off1 - 1;
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* this index is still on disk/file, access it through a frame */
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* empty index element */
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *pbytes    = 0;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *pbyte_len = 0;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Invalid_Argument;
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_index_forget_element( CFF_Index  idx,
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Byte**  pbytes )
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( idx->bytes == 0 )
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = idx->stream;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_RELEASE( *pbytes );
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* get an entry from Name INDEX */
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_String* )
582aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  cff_index_get_name( CFF_Font  font,
583aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                      FT_UInt   element )
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
585aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    CFF_Index   idx = &font->name_index;
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory   memory = idx->stream->memory;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*    bytes;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong    byte_len;
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_String*  name = 0;
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_access_element( idx, element, &bytes, &byte_len );
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( name, byte_len + 1 ) )
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( name, bytes, byte_len );
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      name[byte_len] = 0;
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_forget_element( idx, &bytes );
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return name;
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
609aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* get an entry from String INDEX */
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_String* )
611aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  cff_index_get_string( CFF_Font  font,
612aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                        FT_UInt   element )
613aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
614aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return ( element < font->num_strings )
615aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich             ? (FT_String*)font->strings[element]
616aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich             : NULL;
617aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
618aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
619aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
620aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_LOCAL_DEF( FT_String* )
621aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  cff_index_get_sid_string( CFF_Font  font,
622aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                            FT_UInt   sid )
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* value 0xFFFFU indicates a missing dictionary entry */
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sid == 0xFFFFU )
626aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return NULL;
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is not a standard string, return it */
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sid > 390 )
630aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return cff_index_get_string( font, sid - 391 );
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* CID-keyed CFF fonts don't have glyph names */
633aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !font->psnames )
634aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return NULL;
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
636aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /* this is a standard string */
637aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return (FT_String *)font->psnames->adobe_std_strings( sid );
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
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  /***   FD Select table support                                         ***/
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
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  static void
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Stream     stream )
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( fdselect->data )
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_RELEASE( fdselect->data );
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->data_size   = 0;
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->format      = 0;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->range_count = 0;
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt       num_glyphs,
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Stream     stream,
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong      offset )
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte   format;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   num_ranges;
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read format */
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->format      = format;
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fdselect->cache_count = 0;   /* clear cache */
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( format )
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 0:     /* format 0, that's simple */
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fdselect->data_size = num_glyphs;
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Load_Data;
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 3:     /* format 3, a tad more complex */
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_USHORT( num_ranges ) )
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fdselect->data_size = num_ranges * 3 + 2;
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Load_Data:
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:    /* hmm... that's wrong */
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Invalid_File_Format;
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Byte )
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_fd_select_get( CFF_FDSelect  fdselect,
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt       glyph_index )
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte  fd = 0;
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( fdselect->format )
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 0:
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      fd = fdselect->data[glyph_index];
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case 3:
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* first, compare to cache */
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        fdselect->cache_count )
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        fd = fdselect->cache_fd;
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* then, lookup the ranges array */
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  p       = fdselect->data;
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte*  p_limit = p + fdselect->data_size;
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Byte   fd2;
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt   first, limit;
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        first = FT_NEXT_USHORT( p );
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        do
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( glyph_index < first )
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          fd2   = *p++;
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit = FT_NEXT_USHORT( p );
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( glyph_index < limit )
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fd = fd2;
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* update cache */
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fdselect->cache_first = first;
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fdselect->cache_count = limit-first;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            fdselect->cache_fd    = fd2;
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          first = limit;
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        } while ( p < p_limit );
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ;
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return fd;
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***   CFF font support                                                ***/
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /***                                                                   ***/
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_compute_cids( CFF_Charset  charset,
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_UInt      num_glyphs,
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Memory    memory )
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
783aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Error   error   = CFF_Err_Ok;
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    i;
785295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Long    j;
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  max_cid = 0;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( charset->max_cid > 0 )
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < num_glyphs; i++ )
7937f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    {
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charset->sids[i] > max_cid )
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max_cid = charset->sids[i];
7967f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    }
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7987f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
801295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* When multiple GIDs map to the same CID, we choose the lowest */
802295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* GID.  This is not described in any spec, but it matches the  */
803295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* behaviour of recent Acroread versions.                       */
804295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    for ( j = num_glyphs - 1; j >= 0 ; j-- )
805295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      charset->cids[charset->sids[j]] = (FT_UShort)j;
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->max_cid    = max_cid;
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->num_glyphs = num_glyphs;
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_UInt )
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_cid_to_gindex( CFF_Charset  charset,
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_UInt      cid )
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
8227f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    if ( cid <= charset->max_cid )
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = charset->cids[cid];
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_free_cids( CFF_Charset  charset,
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Memory    memory )
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( charset->cids );
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->max_cid = 0;
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_done( CFF_Charset  charset,
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream    stream )
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_charset_free_cids( charset, memory );
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( charset->sids );
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->format = 0;
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    charset->offset = 0;
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_charset_load( CFF_Charset  charset,
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt      num_glyphs,
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream    stream,
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong     base_offset,
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong     offset,
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Bool      invert )
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error  = CFF_Err_Ok;
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  glyph_sid;
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the the offset is greater than 2, we have to parse the */
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* charset table.                                            */
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( offset > 2 )
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  j;
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->offset = base_offset + offset;
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Get the format of the table. */
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( charset->offset ) ||
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_BYTE( charset->format )   )
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Allocate memory for sids. */
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* assign the .notdef glyph */
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->sids[0] = 0;
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( charset->format )
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 0 )
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = 1; j < num_glyphs; j++ )
8967f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner            charset->sids[j] = FT_GET_USHORT();
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_EXIT();
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  nleft;
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  i;
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          j = 1;
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( j < num_glyphs )
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the first glyph sid of the range. */
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( FT_READ_USHORT( glyph_sid ) )
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the number of glyphs in the range.  */
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( charset->format == 2 )
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( FT_READ_USHORT( nleft ) )
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( FT_READ_BYTE( nleft ) )
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
929295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            /* try to rescue some of the SIDs if `nleft' is too large */
9307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner            if ( glyph_sid > 0xFFFFL - nleft )
931aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            {
9327f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner              FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
9337f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                         " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
9347f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner              nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
935295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            }
936295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Fill in the range of sids -- `nleft + 1' glyphs. */
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              charset->sids[j] = glyph_sid;
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
945295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = CFF_Err_Invalid_File_Format;
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* CFF specification intimates the following:                   */
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                              */
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* In order to use a predefined charset, the following must be  */
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* true: The charset constructed for the glyphs in the font's   */
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* charstrings dictionary must match the predefined charset in  */
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* the first num_glyphs.                                        */
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->offset = offset;  /* record charset type */
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( (FT_UInt)offset )
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 229 )
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
968295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     "predefined charset (Adobe ISO-Latin)\n" ));
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = CFF_Err_Invalid_File_Format;
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Allocate memory for sids. */
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Copy the predefined charset into the allocated memory. */
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 166 )
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
986295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     "predefined charset (Adobe Expert)\n" ));
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = CFF_Err_Invalid_File_Format;
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Allocate memory for sids. */
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Copy the predefined charset into the allocated memory.     */
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 2:
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( num_glyphs > 87 )
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1004295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     "predefined charset (Adobe Expert Subset)\n" ));
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = CFF_Err_Invalid_File_Format;
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Allocate memory for sids. */
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Copy the predefined charset into the allocated memory.     */
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = CFF_Err_Invalid_File_Format;
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( invert )
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_charset_compute_cids( charset, num_glyphs, memory );
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Clean up if there was an error. */
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( charset->sids );
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( charset->cids );
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->format = 0;
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->offset = 0;
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      charset->sids   = 0;
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_encoding_done( CFF_Encoding  encoding )
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    encoding->format = 0;
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    encoding->offset = 0;
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    encoding->count  = 0;
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_encoding_load( CFF_Encoding  encoding,
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     CFF_Charset   charset,
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt       num_glyphs,
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream     stream,
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong      base_offset,
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong      offset )
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = CFF_Err_Ok;
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    count;
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    j;
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort  glyph_sid;
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    glyph_code;
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check for charset->sids.  If we do not have this, we fail. */
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charset->sids )
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Invalid_File_Format;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Zero out the code to gid/sid mappings. */
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( j = 0; j < 256; j++ )
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      encoding->sids [j] = 0;
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      encoding->codes[j] = 0;
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the first encoded glyph index is 1.  Hence, we read the character  */
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* code (`glyph_code') at index j and make the assignment:            */
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*    encoding->codes[glyph_code] = j + 1                             */
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We also make the assignment:                                       */
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This gives us both a code to GID and a code to SID mapping.        */
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( offset > 1 )
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      encoding->offset = base_offset + offset;
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we need to parse the table to determine its size */
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( encoding->offset ) ||
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_BYTE( encoding->format )   ||
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_BYTE( count )              )
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( encoding->format & 0x7F )
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Byte*  p;
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* By convention, GID 0 is always ".notdef" and is never */
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* coded in the font.  Hence, the number of codes found  */
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* in the table is `count+1'.                            */
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /*                                                       */
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          encoding->count = count + 1;
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_FRAME_ENTER( count ) )
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          p = (FT_Byte*)stream->cursor;
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = 1; j <= count; j++ )
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            glyph_code = *p++;
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Make sure j is not too big. */
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( j < num_glyphs )
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              /* Assign code to GID mapping. */
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->codes[glyph_code] = (FT_UShort)j;
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              /* Assign code to SID mapping. */
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->sids[glyph_code] = charset->sids[j];
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FRAME_EXIT();
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  nleft;
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  i = 1;
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  k;
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          encoding->count = 0;
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Parse the Format1 ranges. */
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = 0;  j < count; j++, i += nleft )
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the first glyph code of the range. */
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( FT_READ_BYTE( glyph_code ) )
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Read the number of codes in the range. */
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( FT_READ_BYTE( nleft ) )
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Increment nleft, so we read `nleft + 1' codes/sids. */
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            nleft++;
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* compute max number of character codes */
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( (FT_UInt)nleft > encoding->count )
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->count = nleft;
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* Fill in the range of codes/sids. */
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( k = i; k < nleft + i; k++, glyph_code++ )
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              /* Make sure k is not too big. */
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( k < num_glyphs && glyph_code < 256 )
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              {
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                /* Assign code to GID mapping. */
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                encoding->codes[glyph_code] = (FT_UShort)k;
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                /* Assign code to SID mapping. */
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                encoding->sids[glyph_code] = charset->sids[k];
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              }
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* simple check; one never knows what can be found in a font */
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( encoding->count > 256 )
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->count = 256;
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1189295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = CFF_Err_Invalid_File_Format;
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Parse supplemental encodings, if any. */
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( encoding->format & 0x80 )
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt  gindex;
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* count supplements */
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_READ_BYTE( count ) )
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( j = 0; j < count; j++ )
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Read supplemental glyph code. */
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_READ_BYTE( glyph_code ) )
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Read the SID associated with this glyph code. */
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_READ_USHORT( glyph_sid ) )
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Assign code to SID mapping. */
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          encoding->sids[glyph_code] = glyph_sid;
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* First, look up GID which has been assigned to */
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* SID glyph_sid.                                */
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( gindex = 0; gindex < num_glyphs; gindex++ )
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( charset->sids[gindex] == glyph_sid )
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              encoding->codes[glyph_code] = (FT_UShort)gindex;
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              break;
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* We take into account the fact a CFF font can use a predefined */
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* encoding without containing all of the glyphs encoded by this */
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* encoding (see the note at the end of section 12 in the CFF    */
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* specification).                                               */
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( (FT_UInt)offset )
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 0:
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* First, copy the code to SID mapping. */
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Populate;
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case 1:
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* First, copy the code to SID mapping. */
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Populate:
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Construct code to GID mapping from code to SID mapping */
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* and charset.                                           */
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        encoding->count = 0;
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = cff_charset_compute_cids( charset, num_glyphs,
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          stream->memory );
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( j = 0; j < 256; j++ )
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  sid = encoding->sids[j];
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt  gid = 0;
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( sid )
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            gid = cff_charset_cid_to_gindex( charset, sid );
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( gid != 0 )
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->codes[j] = (FT_UShort)gid;
1271bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly            encoding->count    = j + 1;
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->codes[j] = 0;
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            encoding->sids [j] = 0;
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      default:
1282295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = CFF_Err_Invalid_File_Format;
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Clean up if there was an error. */
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_subfont_load( CFF_SubFont  font,
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    CFF_Index    idx,
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt      font_index,
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream    stream,
1300295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    FT_ULong     base_offset,
1301295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    FT_Library   library )
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_ParserRec    parser;
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*         dict = NULL;
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         dict_len;
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  top  = &font->font_dict;
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_Private      priv = &font->private_dict;
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1311295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set defaults */
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( top, sizeof ( *top ) );
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->underline_position  = -100L << 16;
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->underline_thickness = 50L << 16;
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->charstring_type     = 2;
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->font_matrix.xx      = 0x10000L;
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->font_matrix.yy      = 0x10000L;
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_count           = 8720;
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we use the implementation specific SID value 0xFFFF to indicate */
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* missing entries                                                 */
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->version             = 0xFFFFU;
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->notice              = 0xFFFFU;
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->copyright           = 0xFFFFU;
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->full_name           = 0xFFFFU;
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->family_name         = 0xFFFFU;
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->weight              = 0xFFFFU;
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->embedded_postscript = 0xFFFFU;
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_registry        = 0xFFFFU;
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_ordering        = 0xFFFFU;
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top->cid_font_name       = 0xFFFFU;
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1339bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
1340bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " top dictionary:\n" ));
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_parser_run( &parser, dict, dict + dict_len );
1342bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_forget_element( idx, &dict );
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is a CID font, we stop there */
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( top->cid_registry != 0xFFFFU )
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* parse the private dictionary, if any */
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( top->private_offset && top->private_size )
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* set defaults */
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_ZERO( priv, sizeof ( *priv ) );
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->blue_shift       = 7;
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->blue_fuzz        = 1;
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->lenIV            = -1;
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1365295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_FRAME_ENTER( font->font_dict.private_size )                 )
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1371bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_TRACE4(( " private dictionary:\n" ));
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_parser_run( &parser,
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              (FT_Byte*)stream->cursor,
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              (FT_Byte*)stream->limit );
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_EXIT();
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* ensure that `num_blue_values' is even */
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      priv->num_blue_values &= ~1;
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the local subrs, if any */
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( priv->local_subrs_offset )
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           priv->local_subrs_offset ) )
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_init( &font->local_subrs_index, stream, 1 );
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_get_pointers( &font->local_subrs_index,
1395aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                      &font->local_subrs, NULL );
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_subfont_done( FT_Memory    memory,
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    CFF_SubFont  subfont )
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( subfont )
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cff_index_done( &subfont->local_subrs_index );
1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( subfont->local_subrs );
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1418295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  cff_font_load( FT_Library library,
1419295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 FT_Stream  stream,
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Int     face_index,
142177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                 CFF_Font   font,
142277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                 FT_Bool    pure_cff )
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  cff_header_fields[] =
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  CFF_FontRec
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 4 ),
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( version_major ),
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( version_minor ),
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( header_size ),
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE( absolute_offsize ),
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory = stream->memory;
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         base_offset;
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_FontRecDict  dict;
1441aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    CFF_IndexRec     string_index;
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( font );
1445aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ZERO( &string_index );
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    font->stream = stream;
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    font->memory = memory;
1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dict         = &font->top_font.font_dict;
1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base_offset  = FT_STREAM_POS();
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read CFF font header */
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check format */
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( font->version_major   != 1 ||
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         font->header_size      < 4 ||
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         font->absolute_offsize > 4 )
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
146141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      FT_TRACE2(( "  not a CFF font header\n" ));
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Unknown_File_Format;
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* skip the rest of the header */
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the name, top dict, string and global subrs index */
1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1472aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 0 ) )                  ||
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1474aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 0 ) )                  ||
1475aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_SET_ERROR( cff_index_init( &string_index,
1476aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 1 ) )                  ||
1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1478aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                       stream, 1 ) )                  ||
1479aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_SET_ERROR( cff_index_get_pointers( &string_index,
1480aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                               &font->strings,
1481aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                               &font->string_pool ) ) )
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1484aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    font->num_strings = string_index.count;
1485aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* well, we don't really forget the `disabled' fonts... */
1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    font->num_faces = font->name_index.count;
1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= (FT_Int)font->num_faces )
1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 face_index ));
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Err_Invalid_Argument;
1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in case of a font format check, simply exit now */
1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index < 0 )
1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, parse the top-level font dictionary */
1500bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE4(( "parsing top-level\n" ));
1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_subfont_load( &font->top_font,
1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              &font->font_dict_index,
1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              face_index,
1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              stream,
1505295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                              base_offset,
1506295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                              library );
1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_init( &font->charstrings_index, stream, 0 );
1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now, check for a CID font */
1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dict->cid_registry != 0xFFFFU )
1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      CFF_IndexRec  fd_index;
1521aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      CFF_SubFont   sub = NULL;
1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt       idx;
1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* this is a CID-keyed font, we must now allocate a table of */
1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* sub-fonts, then load each of them separately              */
1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_index_init( &fd_index, stream, 0 );
1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( fd_index.count > CFF_MAX_CID_FONTS )
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail_CID;
1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate & read each font dict independently */
1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      font->num_subfonts = fd_index.count;
1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail_CID;
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* set up pointer table */
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( idx = 0; idx < fd_index.count; idx++ )
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        font->subfonts[idx] = sub + idx;
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now load each subfont independently */
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( idx = 0; idx < fd_index.count; idx++ )
1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        sub = font->subfonts[idx];
1553bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE4(( "parsing subfont %u\n", idx ));
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = cff_subfont_load( sub, &fd_index, idx,
1555295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  stream, base_offset, library );
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail_CID;
1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now load the FD Select array */
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = CFF_Load_FD_Select( &font->fd_select,
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  font->charstrings_index.count,
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  stream,
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  base_offset + dict->cid_fd_select_offset );
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Fail_CID:
1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cff_index_done( &fd_index );
1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      font->num_subfonts = 0;
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the charstrings index now */
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dict->charstrings_offset == 0 )
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1578295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
157941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      error = CFF_Err_Invalid_File_Format;
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1583aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    font->num_glyphs = font->charstrings_index.count;
1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = cff_index_get_pointers( &font->global_subrs_index,
1586aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                    &font->global_subrs, NULL );
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the Charset and Encoding tables if available */
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( font->num_glyphs > 0 )
1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
159477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                base_offset, dict->charset_offset, invert );
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* CID-keyed CFFs don't have an encoding */
1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dict->cid_registry == 0xFFFFU )
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = cff_encoding_load( &font->encoding,
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   &font->charset,
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   font->num_glyphs,
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   stream,
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   base_offset,
1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   dict->encoding_offset );
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get the font name (/CIDFontName for CID-keyed fonts, */
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* /FontName otherwise)                                 */
1618aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    font->font_name = cff_index_get_name( font, face_index );
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1621aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    cff_index_done( &string_index );
1622aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  cff_font_done( CFF_Font  font )
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = font->memory;
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    idx;
1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->global_subrs_index );
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->font_dict_index );
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->name_index );
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_index_done( &font->charstrings_index );
1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* release font dictionaries, but only if working with */
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* a CID keyed CFF font                                */
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( font->num_subfonts > 0 )
1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( idx = 0; idx < font->num_subfonts; idx++ )
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cff_subfont_done( memory, font->subfonts[idx] );
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* the subfonts array has been allocated as a single block */
1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( font->subfonts[0] );
1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_encoding_done( &font->encoding );
1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_charset_done( &font->charset, font->stream );
1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cff_subfont_done( memory, &font->top_font );
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    CFF_Done_FD_Select( &font->fd_select, font->stream );
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1657aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->font_info );
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( font->font_name );
1660aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->global_subrs );
1661aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->strings );
1662aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_FREE( font->string_pool );
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1667