cffload.c revision 049d6fea481044fcc000e7782e5bc7046fc70844
19258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org/***************************************************************************/
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*                                                                         */
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  cffload.c                                                              */
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*                                                                         */
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*    OpenType and CFF data/program tables loader (body).                  */
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*                                                                         */
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*                                                                         */
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  This file is part of the FreeType project, and may only be used,       */
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  modified, and distributed under the terms of the FreeType project      */
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  this file you indicate that you have read the license and              */
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*  understand and accept it fully.                                        */
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/*                                                                         */
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/***************************************************************************/
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <ft2build.h>
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include FT_INTERNAL_DEBUG_H
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include FT_INTERNAL_OBJECTS_H
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include FT_INTERNAL_STREAM_H
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include FT_SERVICE_POSTSCRIPT_CMAPS_H
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include FT_TRUETYPE_TAGS_H
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include FT_TYPE1_TABLES_H
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "cffload.h"
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "cffparse.h"
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "cfferrs.h"
311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
33ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#if 1
349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  static const FT_UShort  cff_isoadobe_charset[229] =
3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org  {
3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org      0,   1,   2,   3,   4,   5,   6,   7,
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      8,   9,  10,  11,  12,  13,  14,  15,
38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org     16,  17,  18,  19,  20,  21,  22,  23,
39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org     24,  25,  26,  27,  28,  29,  30,  31,
40a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org     32,  33,  34,  35,  36,  37,  38,  39,
41a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org     40,  41,  42,  43,  44,  45,  46,  47,
4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     48,  49,  50,  51,  52,  53,  54,  55,
4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen     56,  57,  58,  59,  60,  61,  62,  63,
4468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org     64,  65,  66,  67,  68,  69,  70,  71,
4568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org     72,  73,  74,  75,  76,  77,  78,  79,
46c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org     80,  81,  82,  83,  84,  85,  86,  87,
4768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org     88,  89,  90,  91,  92,  93,  94,  95,
48c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org     96,  97,  98,  99, 100, 101, 102, 103,
49c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org    104, 105, 106, 107, 108, 109, 110, 111,
50bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    112, 113, 114, 115, 116, 117, 118, 119,
51bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    120, 121, 122, 123, 124, 125, 126, 127,
5268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org    128, 129, 130, 131, 132, 133, 134, 135,
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    136, 137, 138, 139, 140, 141, 142, 143,
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    144, 145, 146, 147, 148, 149, 150, 151,
559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    152, 153, 154, 155, 156, 157, 158, 159,
569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    160, 161, 162, 163, 164, 165, 166, 167,
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    168, 169, 170, 171, 172, 173, 174, 175,
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    176, 177, 178, 179, 180, 181, 182, 183,
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    184, 185, 186, 187, 188, 189, 190, 191,
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    192, 193, 194, 195, 196, 197, 198, 199,
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    200, 201, 202, 203, 204, 205, 206, 207,
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    208, 209, 210, 211, 212, 213, 214, 215,
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    216, 217, 218, 219, 220, 221, 222, 223,
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    224, 225, 226, 227, 228
658bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  };
668bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
678bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  static const FT_UShort  cff_expert_charset[166] =
687be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  {
6941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org      0,   1, 229, 230, 231, 232, 233, 234,
7041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    235, 236, 237, 238,  13,  14,  15,  99,
7141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    239, 240, 241, 242, 243, 244, 245, 246,
7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    247, 248,  27,  28, 249, 250, 251, 252,
7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    253, 254, 255, 256, 257, 258, 259, 260,
7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    261, 262, 263, 264, 265, 266, 109, 110,
7541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    267, 268, 269, 270, 271, 272, 273, 274,
7641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    275, 276, 277, 278, 279, 280, 281, 282,
777be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    283, 284, 285, 286, 287, 288, 289, 290,
787be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    291, 292, 293, 294, 295, 296, 297, 298,
7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    299, 300, 301, 302, 303, 304, 305, 306,
808bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    307, 308, 309, 310, 311, 312, 313, 314,
81cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    315, 316, 317, 318, 158, 155, 163, 319,
82cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    320, 321, 322, 323, 324, 325, 326, 150,
83cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    164, 169, 327, 328, 329, 330, 331, 332,
84cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    333, 334, 335, 336, 337, 338, 339, 340,
85a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    341, 342, 343, 344, 345, 346, 347, 348,
86a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    349, 350, 351, 352, 353, 354, 355, 356,
877be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    357, 358, 359, 360, 361, 362, 363, 364,
887be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    365, 366, 367, 368, 369, 370, 371, 372,
897be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    373, 374, 375, 376, 377, 378
907be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  };
917be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
9241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  static const FT_UShort  cff_expertsubset_charset[87] =
9341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  {
947be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   1, 231, 232, 235, 236, 237, 238,
957be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org     13,  14,  15,  99, 239, 240, 241, 242,
9641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org    243, 244, 245, 246, 247, 248,  27,  28,
97cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    249, 250, 251, 253, 254, 255, 256, 257,
98cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    258, 259, 260, 261, 262, 263, 264, 265,
99cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    266, 109, 110, 267, 268, 269, 270, 272,
100cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    300, 301, 302, 305, 314, 315, 158, 155,
101cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    163, 320, 321, 322, 323, 324, 325, 326,
102cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    150, 164, 169, 327, 328, 329, 330, 331,
103cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    332, 333, 334, 335, 336, 337, 338, 339,
104cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org    340, 341, 342, 343, 344, 345, 346
105cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  };
106cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org
107cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  static const FT_UShort  cff_standard_encoding[256] =
108cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org  {
109cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
110cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
111cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
112cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
113cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org      1,   2,   3,   4,   5,   6,   7,   8,
114cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org      9,  10,  11,  12,  13,  14,  15,  16,
115cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org     17,  18,  19,  20,  21,  22,  23,  24,
116cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org     25,  26,  27,  28,  29,  30,  31,  32,
117cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org     33,  34,  35,  36,  37,  38,  39,  40,
118c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org     41,  42,  43,  44,  45,  46,  47,  48,
119cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org     49,  50,  51,  52,  53,  54,  55,  56,
120a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org     57,  58,  59,  60,  61,  62,  63,  64,
12141826e77311db718135ef6517b846933dfd275f3ager@chromium.org     65,  66,  67,  68,  69,  70,  71,  72,
12241826e77311db718135ef6517b846933dfd275f3ager@chromium.org     73,  74,  75,  76,  77,  78,  79,  80,
12341826e77311db718135ef6517b846933dfd275f3ager@chromium.org     81,  82,  83,  84,  85,  86,  87,  88,
124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org     89,  90,  91,  92,  93,  94,  95,   0,
125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1267be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1277be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      0,  96,  97,  98,  99, 100, 101, 102,
1307be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    103, 104, 105, 106, 107, 108, 109, 110,
1317be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0, 111, 112, 113, 114,   0, 115, 116,
1327be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    117, 118, 119, 120, 121, 122,   0, 123,
133bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      0, 124, 125, 126, 127, 128, 129, 130,
1347be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    131,   0, 132, 133,   0, 134, 135, 136,
1357be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    137,   0,   0,   0,   0,   0,   0,   0,
1360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      0, 138,   0, 139,   0,   0,   0,   0,
1380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    140, 141, 142, 143,   0,   0,   0,   0,
1390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      0, 144,   0,   0,   0, 145,   0,   0,
1400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    146, 147, 148, 149,   0,   0,   0,   0
1410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  };
1420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  static const FT_UShort  cff_expert_encoding[256] =
1440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  {
1450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
146bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1477be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1487be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1497be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      1, 229, 230,   0, 231, 232, 233, 234,
1507be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    235, 236, 237, 238,  13,  14,  15,  99,
1517be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    239, 240, 241, 242, 243, 244, 245, 246,
1527be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    247, 248,  27,  28, 249, 250, 251, 252,
1537be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0, 253, 254, 255, 256, 257,   0,   0,
1547be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0, 258,   0,   0, 259, 260, 261, 262,
1557be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0, 263, 264, 265,   0, 266, 109,
156bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    110, 267, 268, 269,   0, 270, 271, 272,
1577be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    273, 274, 275, 276, 277, 278, 279, 280,
1587be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    281, 282, 283, 284, 285, 286, 287, 288,
1597be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    289, 290, 291, 292, 293, 294, 295, 296,
160bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    297, 298, 299, 300, 301, 302, 303,   0,
1617be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1627be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1637be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1647be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0,   0,   0,   0,   0,   0,   0,   0,
1657be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      0, 304, 305, 306,   0,   0, 307, 308,
166a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    309, 310, 311,   0, 312,   0,   0, 312,
167bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org      0,   0, 314, 315,   0,   0, 316, 317,
168bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    318,   0,   0,   0, 158, 155, 163, 319,
169bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    320, 321, 322, 323, 324, 325,   0,   0,
1707be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    326, 150, 164, 169, 327, 328, 329, 330,
171bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    331, 332, 333, 334, 335, 336, 337, 338,
1727be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    339, 340, 341, 342, 343, 344, 345, 346,
1737be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    347, 348, 349, 350, 351, 352, 353, 354,
1747be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    355, 356, 357, 358, 359, 360, 361, 362,
1757be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    363, 364, 365, 366, 367, 368, 369, 370,
1767be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    371, 372, 373, 374, 375, 376, 377, 378
1777be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  };
17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif /* 1 */
17983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
18083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
18183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  FT_LOCAL_DEF( FT_UShort )
18283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  cff_get_standard_encoding( FT_UInt  charcode )
18383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  {
18483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
18583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                       : 0 );
18683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
187bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
188bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
189bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  /*************************************************************************/
190bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  /*                                                                       */
19168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
19268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
193bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  /* messages during execution.                                            */
194bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  /*                                                                       */
19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef  FT_COMPONENT
19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define FT_COMPONENT  trace_cffload
197a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
198a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
199a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /* read an offset from the index's stream current position */
200a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static FT_ULong
20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  cff_index_read_offset( CFF_Index  idx,
20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                         FT_Error  *errorp )
20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  {
20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    FT_Error   error;
20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    FT_Stream  stream = idx->stream;
20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    FT_Byte    tmp[4];
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    FT_ULong   result = 0;
20843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    {
21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      FT_Int  nn;
2130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      for ( nn = 0; nn < idx->off_size; nn++ )
2160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        result = ( result << 8 ) | tmp[nn];
2170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
2180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2190c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    *errorp = error;
2200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    return result;
2210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
2220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2230c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2240c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  static FT_Error
2250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  cff_index_init( CFF_Index  idx,
2260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                  FT_Stream  stream,
2270c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                  FT_Bool    load )
2280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  {
2290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_Error   error;
2300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_Memory  memory = stream->memory;
2310c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_UShort  count;
2320c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2330c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2340c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_MEM_ZERO( idx, sizeof ( *idx ) );
2350c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2360c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    idx->stream = stream;
2370c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    idx->start  = FT_STREAM_POS();
2380c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if ( !FT_READ_USHORT( count ) &&
2390c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org         count > 0                )
2400c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    {
2410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_Byte   offsize;
2420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_ULong  size;
2430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2450c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* there is at least one element; read the offset size,           */
2460c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* then access the offset table to compute the index's total size */
2470c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      if ( FT_READ_BYTE( offsize ) )
2480c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        goto Exit;
2490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      if ( offsize < 1 || offsize > 4 )
2510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      {
2520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        error = FT_Err_Invalid_Table;
2530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        goto Exit;
2540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      }
2550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      idx->count    = count;
2570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      idx->off_size = offsize;
2580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      size          = (FT_ULong)( count + 1 ) * offsize;
2590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      idx->data_offset = idx->start + 3 + size;
2610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      if ( FT_STREAM_SKIP( size - offsize ) )
2630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        goto Exit;
264a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
265a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      size = cff_index_read_offset( idx, &error );
266a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( error )
267a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
268a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
269a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( size == 0 )
270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        error = CFF_Err_Invalid_Table;
272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      idx->data_size = --size;
276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( load )
278a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
279a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        /* load the data */
280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
281a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          goto Exit;
282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      else
284a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
285a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        /* skip the data */
286a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( FT_STREAM_SKIP( size ) )
287a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          goto Exit;
2888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      }
289a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
29038e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org
291a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
292a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( error )
293a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FREE( idx->offsets );
294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
2950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    return error;
2960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
2970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
2990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  static void
3000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  cff_index_done( CFF_Index  idx )
3010c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  {
3020c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if ( idx->stream )
3030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    {
3040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_Stream  stream = idx->stream;
3050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_Memory  memory = stream->memory;
3060c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3070c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3080c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      if ( idx->bytes )
3090c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        FT_FRAME_RELEASE( idx->bytes );
3100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3110c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_FREE( idx->offsets );
3120c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_MEM_ZERO( idx, sizeof ( *idx ) );
3130c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    }
3140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
3150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  static FT_Error
3180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  cff_index_load_offsets( CFF_Index  idx )
3190c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  {
3200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_Error   error  = 0;
3210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_Stream  stream = idx->stream;
3220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_Memory  memory = stream->memory;
3230c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3240c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
3250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    if ( idx->count > 0 && idx->offsets == NULL )
3260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    {
3270c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      FT_Byte    offsize = idx->off_size;
328a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_ULong   data_size;
329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_Byte*   p;
330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_Byte*   p_end;
331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_ULong*  poff;
332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      data_size = (FT_ULong)( idx->count + 1 ) * offsize;
335a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
336a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           FT_STREAM_SEEK( idx->start + 3 )             ||
338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           FT_FRAME_ENTER( data_size )                  )
339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      poff   = idx->offsets;
342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      p      = (FT_Byte*)stream->cursor;
343a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      p_end  = p + data_size;
344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      switch ( offsize )
346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 1:
348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        for ( ; p < p_end; p++, poff++ )
349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          poff[0] = p[0];
350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 2:
353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        for ( ; p < p_end; p += 2, poff++ )
354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          poff[0] = FT_PEEK_USHORT( p );
355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 3:
358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        for ( ; p < p_end; p += 3, poff++ )
359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          poff[0] = FT_PEEK_OFF3( p );
360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
3623291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      default:
363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        for ( ; p < p_end; p += 4, poff++ )
364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          poff[0] = FT_PEEK_ULONG( p );
365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
366a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FRAME_EXIT();
368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
371a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( error )
372a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FREE( idx->offsets );
373a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
374a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return error;
375a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
376a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
377a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
378a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /* allocate a table containing pointers to an index's elements */
379a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static FT_Error
380a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_index_get_pointers( CFF_Index   idx,
381a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                          FT_Byte***  table )
382a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
383a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Error   error  = CFF_Err_Ok;
384a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Memory  memory = idx->stream->memory;
385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_ULong   n, offset, old_offset;
386a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Byte**  t;
387a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
388a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
389a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    *table = 0;
390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( idx->offsets == NULL )
392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = cff_index_load_offsets( idx );
394a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( error )
395a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
396a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
397a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
398a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
399a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
400a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      old_offset = 1;
401a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      for ( n = 0; n <= idx->count; n++ )
402a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
403a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        offset = idx->offsets[n];
404a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( !offset )
405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          offset = old_offset;
406a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        /* two sanity checks for invalid offset tables */
408a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        else if ( offset < old_offset )
409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          offset = old_offset;
410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        else if ( offset - 1 >= idx->data_size && n < idx->count )
412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          offset = old_offset;
413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        t[n] = idx->bytes + offset - 1;
415a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
416a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        old_offset = offset;
417a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
418a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      *table = t;
419a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
420a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
421a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return error;
423ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
424a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FT_LOCAL_DEF( FT_Error )
427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_index_access_element( CFF_Index  idx,
428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            FT_UInt    element,
429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            FT_Byte**  pbytes,
430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            FT_ULong*  pbyte_len )
431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Error  error = CFF_Err_Ok;
433a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
434a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( idx && idx->count > element )
436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
437a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* compute start and end offsets */
438a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_Stream  stream = idx->stream;
439a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_ULong   off1, off2 = 0;
440a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
441a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
442a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* load offsets from file or the offset table */
443a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( !idx->offsets )
444a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
445a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_ULong  pos = element * idx->off_size;
446a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
447a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
448a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
449a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          goto Exit;
4508bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
451a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        off1 = cff_index_read_offset( idx, &error );
452a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( error )
45337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          goto Exit;
454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( off1 != 0 )
456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          do
458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          {
4598bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            element++;
460a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            off2 = cff_index_read_offset( idx, &error );
461a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          }
462a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          while ( off2 == 0 && element < idx->count );
4633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        }
4648bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      }
4658bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      else   /* use offsets table */
466a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
467a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        off1 = idx->offsets[element];
468a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( off1 )
469a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
470a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          do
471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          {
472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            element++;
473a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            off2 = idx->offsets[element];
474a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
475a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          } while ( off2 == 0 && element < idx->count );
476a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
477a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
478a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
479a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* access element */
480a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( off1 && off2 > off1 )
481a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
48237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        *pbyte_len = off2 - off1;
483a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
484a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( idx->bytes )
485a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
486a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          /* this index was completely loaded in memory, that's easy */
487a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          *pbytes = idx->bytes + off1 - 1;
488a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
489a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        else
490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          /* this index is still on disk/file, access it through a frame */
492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
493a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
4948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            goto Exit;
4958bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        }
4968bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      }
4978bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      else
4988bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      {
4998bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        /* empty index element */
500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        *pbytes    = 0;
501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        *pbyte_len = 0;
502a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
504a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    else
505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = CFF_Err_Invalid_Argument;
506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
508a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return error;
509a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
510a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FT_LOCAL_DEF( void )
513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_index_forget_element( CFF_Index  idx,
514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                            FT_Byte**  pbytes )
515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( idx->bytes == 0 )
517a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_Stream  stream = idx->stream;
519a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
520a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
521a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FRAME_RELEASE( *pbytes );
522a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
523a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
524a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
525a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
526a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FT_LOCAL_DEF( FT_String* )
527a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_index_get_name( CFF_Index  idx,
528a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                      FT_UInt    element )
529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Memory   memory = idx->stream->memory;
531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Byte*    bytes;
532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_ULong    byte_len;
533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Error    error;
534a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_String*  name = 0;
535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
537a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    error = cff_index_access_element( idx, element, &bytes, &byte_len );
538a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( error )
539a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      goto Exit;
540a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
541a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( !FT_ALLOC( name, byte_len + 1 ) )
542a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
543a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_MEM_COPY( name, bytes, byte_len );
544a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      name[byte_len] = 0;
545a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
54637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    cff_index_forget_element( idx, &bytes );
54737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
54837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  Exit:
54937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    return name;
55037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
55137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
55237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
553245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  FT_LOCAL_DEF( FT_String* )
554245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  cff_index_get_sid_string( CFF_Index           idx,
55537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                            FT_UInt             sid,
55637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                            FT_Service_PsCMaps  psnames )
55737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  {
558245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    /* value 0xFFFFU indicates a missing dictionary entry */
559245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    if ( sid == 0xFFFFU )
56037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      return 0;
56137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
56237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    /* if it is not a standard string, return it */
56337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if ( sid > 390 )
56437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      return cff_index_get_name( idx, sid - 391 );
56537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
566245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    /* CID-keyed CFF fonts don't have glyph names */
567245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    if ( !psnames )
56837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      return 0;
56937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
57037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    /* that's a standard string, fetch a copy from the PSName module */
57137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    {
57237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      FT_String*   name       = 0;
57337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      const char*  adobe_name = psnames->adobe_std_strings( sid );
57437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
57537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
57637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      if ( adobe_name )
57737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      {
57837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        FT_Memory  memory = idx->stream->memory;
57937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        FT_Error   error;
58037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
58137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
58237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        (void)FT_STRDUP( name, adobe_name );
58337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
58437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        FT_UNUSED( error );
58537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
58637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
58737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      return name;
58837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    }
58937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
59037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
59137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
592245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  /*************************************************************************/
593245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  /*************************************************************************/
594245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  /***                                                                   ***/
59537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  /***   FD Select table support                                         ***/
59637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  /***                                                                   ***/
59737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  /*************************************************************************/
598a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  /*************************************************************************/
599a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
6000c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
60137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  static void
602a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
603a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                      FT_Stream     stream )
604ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  {
60537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if ( fdselect->data )
606ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      FT_FRAME_RELEASE( fdselect->data );
607ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
608a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    fdselect->data_size   = 0;
609a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    fdselect->format      = 0;
610a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    fdselect->range_count = 0;
611a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
612a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
614a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static FT_Error
61537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
61637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                      FT_UInt       num_glyphs,
61737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                      FT_Stream     stream,
61837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                      FT_ULong      offset )
6193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  {
62037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    FT_Error  error;
62137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    FT_Byte   format;
62237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    FT_UInt   num_ranges;
62337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
62437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
62537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    /* read format */
62637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
62737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      goto Exit;
62837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
62937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    fdselect->format      = format;
630245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    fdselect->cache_count = 0;   /* clear cache */
631245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
6328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    switch ( format )
6338bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    {
6348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    case 0:     /* format 0, that's simple */
6353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      fdselect->data_size = num_glyphs;
6363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      goto Load_Data;
6373291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
6383291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    case 3:     /* format 3, a tad more complex */
6393291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      if ( FT_READ_USHORT( num_ranges ) )
6403291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        goto Exit;
641a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
642a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      fdselect->data_size = num_ranges * 3 + 2;
643a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
644a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    Load_Data:
645a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
646a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
647a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      break;
648a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
649a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    default:    /* hmm... that's wrong */
650a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = CFF_Err_Invalid_File_Format;
651a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
652a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
653a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
654a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return error;
655a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
6560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
6570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
6580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  FT_LOCAL_DEF( FT_Byte )
6590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  cff_fd_select_get( CFF_FDSelect  fdselect,
6600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                     FT_UInt       glyph_index )
6610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  {
6620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    FT_Byte  fd = 0;
6630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
6640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
6650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    switch ( fdselect->format )
6660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    {
6670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    case 0:
6680c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      fd = fdselect->data[glyph_index];
6690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      break;
6700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
6710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org    case 3:
6720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* first, compare to cache */
6730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
6740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                        fdselect->cache_count )
675a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
676ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        fd = fdselect->cache_fd;
6770c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        break;
6780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      }
6793291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
680a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* then, lookup the ranges array */
681a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
682a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_Byte*  p       = fdselect->data;
683a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_Byte*  p_limit = p + fdselect->data_size;
684a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_Byte   fd2;
685a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_UInt   first, limit;
686a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
687a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
688a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        first = FT_NEXT_USHORT( p );
689a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        do
690a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
691a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          if ( glyph_index < first )
692a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            break;
693a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
694a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          fd2   = *p++;
6953291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org          limit = FT_NEXT_USHORT( p );
696a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
697a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          if ( glyph_index < limit )
698a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          {
6990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org            fd = fd2;
700a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
701a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            /* update cache */
702a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            fdselect->cache_first = first;
7030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org            fdselect->cache_count = limit-first;
7043291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org            fdselect->cache_fd    = fd2;
7053291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org            break;
7063291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org          }
7073291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org          first = limit;
7083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7093291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        } while ( p < p_limit );
7103291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      }
7113291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      break;
7123291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    default:
7143291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      ;
7153291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    }
7163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    return fd;
7183291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
7193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /*************************************************************************/
7223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /*************************************************************************/
7233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /***                                                                   ***/
7243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /***   CFF font support                                                ***/
7253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /***                                                                   ***/
7263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /*************************************************************************/
7273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  /*************************************************************************/
7283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  static FT_Error
7303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  cff_charset_compute_cids( CFF_Charset  charset,
7313291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org                            FT_UInt      num_glyphs,
7323291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org                            FT_Memory    memory )
7333291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  {
7343291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    FT_Error   error   = FT_Err_Ok;
7353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    FT_UInt    i;
7363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    FT_UShort  max_cid = 0;
737a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
738a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
739a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( charset->max_cid > 0 )
740a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      goto Exit;
741a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
742a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    for ( i = 0; i < num_glyphs; i++ )
743a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( charset->sids[i] > max_cid )
744a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        max_cid = charset->sids[i];
745a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    max_cid++;
746a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
747a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
748a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      goto Exit;
749a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
750a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    for ( i = 0; i < num_glyphs; i++ )
751a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      charset->cids[charset->sids[i]] = (FT_UShort)i;
752a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
753a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    charset->max_cid    = max_cid;
7548bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    charset->num_glyphs = num_glyphs;
755a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
756a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
757a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return error;
7583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
7593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
761a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FT_LOCAL_DEF( FT_UInt )
7628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  cff_charset_cid_to_gindex( CFF_Charset  charset,
763a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             FT_UInt      cid )
764ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  {
765ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    FT_UInt  result = 0;
766ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
7673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7683291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    if ( cid < charset->max_cid )
7693291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      result = charset->cids[cid];
7703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
7713291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    return result;
7723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  }
773ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
774ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
7753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  static void
7763291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  cff_charset_free_cids( CFF_Charset  charset,
7773291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org                         FT_Memory    memory )
7783291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  {
7793291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    FT_FREE( charset->cids );
780a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    charset->max_cid = 0;
781ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
782a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
783a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static void
78537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  cff_charset_done( CFF_Charset  charset,
78637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                    FT_Stream    stream )
787245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org  {
788245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    FT_Memory  memory = stream->memory;
789245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
790245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
79137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    cff_charset_free_cids( charset, memory );
7928bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
7938bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_FREE( charset->sids );
7948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    charset->format = 0;
795a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    charset->offset = 0;
7960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  }
797a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
798a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
799a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static FT_Error
800a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_charset_load( CFF_Charset  charset,
801a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    FT_UInt      num_glyphs,
802a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    FT_Stream    stream,
803a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    FT_ULong     base_offset,
804a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    FT_ULong     offset,
805a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    FT_Bool      invert )
806a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
807a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Memory  memory = stream->memory;
808ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    FT_Error   error  = CFF_Err_Ok;
809a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_UShort  glyph_sid;
810a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
811a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
812a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* If the the offset is greater than 2, we have to parse the */
813ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    /* charset table.                                            */
814ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    if ( offset > 2 )
815a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
8163291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      FT_UInt  j;
8173291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
8183291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
8193291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      charset->offset = base_offset + offset;
8203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
8213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      /* Get the format of the table. */
8223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      if ( FT_STREAM_SEEK( charset->offset ) ||
8233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org           FT_READ_BYTE( charset->format )   )
8243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        goto Exit;
825a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
826a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* Allocate memory for sids. */
827a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
828a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
829a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
830a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* assign the .notdef glyph */
831a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      charset->sids[0] = 0;
832a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
833a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      switch ( charset->format )
834a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      {
835a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 0:
836a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( num_glyphs > 0 )
8378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        {
838a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
839a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            goto Exit;
840a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
8418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          for ( j = 1; j < num_glyphs; j++ )
842a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            charset->sids[j] = FT_GET_USHORT();
843a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
844a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          FT_FRAME_EXIT();
845a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
846a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
847ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
848a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case 1:
849a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case 2:
850a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        {
85137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          FT_UInt  nleft;
85237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          FT_UInt  i;
853245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
854245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
855a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          j = 1;
85638e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org
8578bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          while ( j < num_glyphs )
8588bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          {
8598bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            /* Read the first glyph sid of the range. */
8608bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            if ( FT_READ_USHORT( glyph_sid ) )
8618bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org              goto Exit;
8628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
8638bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            /* Read the number of glyphs in the range.  */
8640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org            if ( charset->format == 2 )
86537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com            {
86637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com              if ( FT_READ_USHORT( nleft ) )
867381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org                goto Exit;
868381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org            }
869381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org            else
870381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org            {
871381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org              if ( FT_READ_BYTE( nleft ) )
87237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                goto Exit;
873381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org            }
874381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
875381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org            /* Fill in the range of sids -- `nleft + 1' glyphs. */
87637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
87737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com              charset->sids[j] = glyph_sid;
87837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          }
8793291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        }
88037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        break;
88137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
88237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      default:
883a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
884a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        error = CFF_Err_Invalid_File_Format;
885a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
886a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
887ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    }
888ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    else
889ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    {
890ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
891ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      /* CFF specification intimates the following:                   */
892ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      /*                                                              */
893ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      /* In order to use a predefined charset, the following must be  */
8940c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* true: The charset constructed for the glyphs in the font's   */
8950c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* charstrings dictionary must match the predefined charset in  */
8960c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* the first num_glyphs.                                        */
8970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
8980c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      charset->offset = offset;  /* record charset type */
8990c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
900ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      switch ( (FT_UInt)offset )
901ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      {
902ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      case 0:
903ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if ( num_glyphs > 229 )
904ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        {
905ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
906ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                     "predefined charset (Adobe ISO-Latin)!\n" ));
907ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          error = CFF_Err_Invalid_File_Format;
908ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          goto Exit;
909ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
910ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
911ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        /* Allocate memory for sids. */
912ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
913ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          goto Exit;
914ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
915ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        /* Copy the predefined charset into the allocated memory. */
916ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
917ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        break;
919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      case 1:
921ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if ( num_glyphs > 166 )
922ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        {
923245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
924245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                     "predefined charset (Adobe Expert)!\n" ));
9250c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org          error = CFF_Err_Invalid_File_Format;
926ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          goto Exit;
927ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
9280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
929ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        /* Allocate memory for sids. */
930ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
931ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          goto Exit;
932ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
933ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        /* Copy the predefined charset into the allocated memory.     */
934ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
935ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
936a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
937a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
938a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 2:
939a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if ( num_glyphs > 87 )
9408bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        {
941a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
942a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                     "predefined charset (Adobe Expert Subset)!\n" ));
943a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          error = CFF_Err_Invalid_File_Format;
944a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          goto Exit;
945a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
946a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
947ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        /* Allocate memory for sids. */
948a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          goto Exit;
950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
95137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        /* Copy the predefined charset into the allocated memory.     */
95237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
953245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
954245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        break;
95537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
95637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      default:
957a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        error = CFF_Err_Invalid_File_Format;
9580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        goto Exit;
959a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
960a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
961a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
962a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
963a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( invert )
964a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = cff_charset_compute_cids( charset, num_glyphs, memory );
965a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
966a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Exit:
9678bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    /* Clean up if there was an error. */
968a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( error )
969a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
970ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      FT_FREE( charset->sids );
971a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      FT_FREE( charset->cids );
972a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      charset->format = 0;
973a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      charset->offset = 0;
97437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      charset->sids   = 0;
97537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    }
976245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
977245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    return error;
97837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  }
97937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
98037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
981a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static void
982a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_encoding_done( CFF_Encoding  encoding )
983a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
984a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    encoding->format = 0;
985a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    encoding->offset = 0;
986a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    encoding->count  = 0;
9878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
9888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
989ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
990ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  static FT_Error
991ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  cff_encoding_load( CFF_Encoding  encoding,
992ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                     CFF_Charset   charset,
9938bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                     FT_UInt       num_glyphs,
9948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                     FT_Stream     stream,
995ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                     FT_ULong      base_offset,
996ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                     FT_ULong      offset )
997ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  {
998ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    FT_Error   error = CFF_Err_Ok;
9998bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_UInt    count;
10008bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_UInt    j;
10018bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_UShort  glyph_sid;
10028bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_UInt    glyph_code;
1003ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1004ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
10058bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    /* Check for charset->sids.  If we do not have this, we fail. */
10068bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if ( !charset->sids )
10078bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    {
1008a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = CFF_Err_Invalid_File_Format;
1009a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      goto Exit;
1010a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
1011a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1012a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* Zero out the code to gid/sid mappings. */
1013a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    for ( j = 0; j < 256; j++ )
1014a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
1015a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      encoding->sids [j] = 0;
1016a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      encoding->codes[j] = 0;
1017a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
1018a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1019a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1020a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* the first encoded glyph index is 1.  Hence, we read the character  */
1021a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* code (`glyph_code') at index j and make the assignment:            */
1022a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /*                                                                    */
1023a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /*    encoding->codes[glyph_code] = j + 1                             */
1024a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /*                                                                    */
1025a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* We also make the assignment:                                       */
1026a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /*                                                                    */
1027a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1028a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /*                                                                    */
1029a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* This gives us both a code to GID and a code to SID mapping.        */
1030a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1031a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( offset > 1 )
1032a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
1033a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      encoding->offset = base_offset + offset;
1034a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1035a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      /* we need to parse the table to determine its size */
1036a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( FT_STREAM_SEEK( encoding->offset ) ||
1037a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           FT_READ_BYTE( encoding->format )   ||
1038a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           FT_READ_BYTE( count )              )
1039a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
104037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
104137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      switch ( encoding->format & 0x7F )
104237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      {
1043a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 0:
1044a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
10458bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          FT_Byte*  p;
10468bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1047a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1048245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          /* By convention, GID 0 is always ".notdef" and is never */
1049a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          /* coded in the font.  Hence, the number of codes found  */
1050a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          /* in the table is `count+1'.                            */
1051a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          /*                                                       */
1052a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          encoding->count = count + 1;
1053a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1054ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          if ( FT_FRAME_ENTER( count ) )
1055a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            goto Exit;
1056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1057a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          p = (FT_Byte*)stream->cursor;
1058ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1059ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          for ( j = 1; j <= count; j++ )
1060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          {
1061a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            glyph_code = *p++;
106237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
106337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com            /* Make sure j is not too big. */
1064245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org            if ( j < num_glyphs )
1065245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org            {
1066a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org              /* Assign code to GID mapping. */
1067a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org              encoding->codes[glyph_code] = (FT_UShort)j;
1068a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1069245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org              /* Assign code to SID mapping. */
1070245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org              encoding->sids[glyph_code] = charset->sids[j];
1071a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            }
1072ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          }
1073a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
10748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          FT_FRAME_EXIT();
10755ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        }
10768bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        break;
10778bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1078a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      case 1:
1079a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        {
108037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          FT_UInt  nleft;
1081a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          FT_UInt  i = 1;
10825ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org          FT_UInt  k;
10833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
1084a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1085ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          encoding->count = 0;
10863291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
108737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          /* Parse the Format1 ranges. */
108837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          for ( j = 0;  j < count; j++, i += nleft )
108937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          {
109037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com            /* Read the first glyph code of the range. */
1091a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            if ( FT_READ_BYTE( glyph_code ) )
1092245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org              goto Exit;
1093245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
1094245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org            /* Read the number of codes in the range. */
1095a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            if ( FT_READ_BYTE( nleft ) )
1096a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org              goto Exit;
1097a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1098a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            /* Increment nleft, so we read `nleft + 1' codes/sids. */
1099ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            nleft++;
1100ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1101ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            /* compute max number of character codes */
1102ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            if ( (FT_UInt)nleft > encoding->count )
1103ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org              encoding->count = nleft;
1104ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
1105ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            /* Fill in the range of codes/sids. */
1106ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            for ( k = i; k < nleft + i; k++, glyph_code++ )
1107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org            {
1108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org              /* Make sure k is not too big. */
1109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org              if ( k < num_glyphs && glyph_code < 256 )
1110ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org              {
1111ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                /* Assign code to GID mapping. */
1112245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org                encoding->codes[glyph_code] = (FT_UShort)k;
1113245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
1114ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                /* Assign code to SID mapping. */
1115ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                encoding->sids[glyph_code] = charset->sids[k];
1116ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org              }
1117ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            }
1118ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          }
1119ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
11200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org          /* simple check; one never knows what can be found in a font */
1121ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          if ( encoding->count > 256 )
1122ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            encoding->count = 256;
1123ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
11248bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        break;
11258bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
112637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      default:
112737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
112837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        error = CFF_Err_Invalid_File_Format;
112937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        goto Exit;
113037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
113137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
113237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      /* Parse supplemental encodings, if any. */
1133ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      if ( encoding->format & 0x80 )
1134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      {
1135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        FT_UInt  gindex;
1136a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
113737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
113837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        /* count supplements */
1139245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        if ( FT_READ_BYTE( count ) )
1140245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org          goto Exit;
11410c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
11428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        for ( j = 0; j < count; j++ )
114337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        {
114437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          /* Read supplemental glyph code. */
114537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          if ( FT_READ_BYTE( glyph_code ) )
114637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com            goto Exit;
114737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
114837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          /* Read the SID associated with this glyph code. */
114937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          if ( FT_READ_USHORT( glyph_sid ) )
115037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com            goto Exit;
115137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
115237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          /* Assign code to SID mapping. */
115337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          encoding->sids[glyph_code] = glyph_sid;
115437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
115537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          /* First, look up GID which has been assigned to */
115637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          /* SID glyph_sid.                                */
115737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          for ( gindex = 0; gindex < num_glyphs; gindex++ )
115837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          {
11598bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            if ( charset->sids[gindex] == glyph_sid )
11608bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            {
11618bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org              encoding->codes[glyph_code] = (FT_UShort)gindex;
11628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org              break;
11638bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            }
11643291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org          }
11653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        }
11663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      }
11673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    }
11683291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    else
11693291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    {
11703291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      /* We take into account the fact a CFF font can use a predefined */
11713291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      /* encoding without containing all of the glyphs encoded by this */
11723291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      /* encoding (see the note at the end of section 12 in the CFF    */
11733291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      /* specification).                                               */
11748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1175245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      switch ( (FT_UInt)offset )
1176245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      {
1177245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      case 0:
1178245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        /* First, copy the code to SID mapping. */
1179245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1180245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org        goto Populate;
11818bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
11828bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      case 1:
11838bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        /* First, copy the code to SID mapping. */
11848bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
11858bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
11863291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      Populate:
11878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        /* Construct code to GID mapping from code to SID mapping */
11888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        /* and charset.                                           */
11898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
11908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        encoding->count = 0;
11918bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
11928bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        error = cff_charset_compute_cids( charset, num_glyphs,
11933291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org                                          stream->memory );
11948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        if ( error )
11958bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          goto Exit;
1196ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
11978bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        for ( j = 0; j < 256; j++ )
1198ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        {
11998bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          FT_UInt  sid = encoding->sids[j];
1200ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          FT_UInt  gid = 0;
1201ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
12028bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1203ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          if ( sid )
12048bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            gid = cff_charset_cid_to_gindex( charset, sid );
12058bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1206ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          if ( gid != 0 )
12078bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          {
12088bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            encoding->codes[j] = (FT_UShort)gid;
12098bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1210ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            if ( encoding->count < j + 1 )
12118bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org              encoding->count = j + 1;
12128bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          }
12138bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          else
12148bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          {
12158bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            encoding->codes[j] = 0;
12168bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            encoding->sids [j] = 0;
12178bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          }
12188bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        }
12198bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        break;
12203291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      default:
12223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
12233291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        error = CFF_Err_Invalid_File_Format;
12243291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        goto Exit;
12253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      }
12263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    }
12273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  Exit:
12293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
1230ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    /* Clean up if there was an error. */
12318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    return error;
12328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
12338bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
12348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
12358bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  static FT_Error
12363291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  cff_subfont_load( CFF_SubFont  font,
12378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    CFF_Index    idx,
12388bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    FT_UInt      font_index,
12398bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    FT_Stream    stream,
12408bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    FT_ULong     base_offset )
124137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  {
124237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    FT_Error         error;
1243245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    CFF_ParserRec    parser;
1244381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    FT_Byte*         dict = NULL;
1245245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    FT_ULong         dict_len;
1246245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    CFF_FontRecDict  top  = &font->font_dict;
12473291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    CFF_Private      priv = &font->private_dict;
12483291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12493291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12503291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );
1251ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
12528bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    /* set defaults */
12538bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_MEM_ZERO( top, sizeof ( *top ) );
12543291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12553291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    top->underline_position  = -100L << 16;
12563291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    top->underline_thickness = 50L << 16;
12573291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    top->charstring_type     = 2;
12583291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    top->font_matrix.xx      = 0x10000L;
12593291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    top->font_matrix.yy      = 0x10000L;
12603291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    top->cid_count           = 8720;
12613291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12623291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    /* we use the implementation specific SID value 0xFFFF to indicate */
12633291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    /* missing entries                                                 */
12648bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    top->version             = 0xFFFFU;
126537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    top->notice              = 0xFFFFU;
126637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    top->copyright           = 0xFFFFU;
126737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    top->full_name           = 0xFFFFU;
126837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    top->family_name         = 0xFFFFU;
126937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    top->weight              = 0xFFFFU;
1270245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    top->embedded_postscript = 0xFFFFU;
1271245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
12728bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    top->cid_registry        = 0xFFFFU;
1273245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    top->cid_ordering        = 0xFFFFU;
1274245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    top->cid_font_name       = 0xFFFFU;
12758bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
12768bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
12778bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if ( !error )
127837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      error = cff_parser_run( &parser, dict, dict + dict_len );
127937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1280381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org    cff_index_forget_element( idx, &dict );
128137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
128237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    if ( error )
12833291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      goto Exit;
12843291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12853291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    /* if it is a CID font, we stop there */
12863291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org    if ( top->cid_registry != 0xFFFFU )
12873291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      goto Exit;
12883291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org
12898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    /* parse the private dictionary, if any */
12908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if ( top->private_offset && top->private_size )
12918bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    {
12928bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      /* set defaults */
12938bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      FT_MEM_ZERO( priv, sizeof ( *priv ) );
12948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
12958bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      priv->blue_shift       = 7;
12968bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      priv->blue_fuzz        = 1;
12970c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      priv->lenIV            = -1;
129837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1299381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
130037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
130137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
130237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1303ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1304ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org           FT_FRAME_ENTER( font->font_dict.private_size )                 )
13058bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        goto Exit;
13068bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13078bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      error = cff_parser_run( &parser,
13088bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                              (FT_Byte*)stream->cursor,
1309ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org                              (FT_Byte*)stream->limit );
1310ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      FT_FRAME_EXIT();
1311ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      if ( error )
13128bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        goto Exit;
13138bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1314ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      /* ensure that `num_blue_values' is even */
1315ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      priv->num_blue_values &= ~1;
13168bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    }
13178bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13188bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    /* read the local subrs, if any */
13198bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if ( priv->local_subrs_offset )
13208bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    {
132137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
132237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                           priv->local_subrs_offset ) )
132337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        goto Exit;
1324381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1325245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org      error = cff_index_init( &font->local_subrs_index, stream, 1 );
13268bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      if ( error )
132737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        goto Exit;
132837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1329a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      font->num_local_subrs = font->local_subrs_index.count;
1330a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = cff_index_get_pointers( &font->local_subrs_index,
1331a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                      &font->local_subrs );
1332a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( error )
1333a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
1334a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
1335a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
133637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  Exit:
1337a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    return error;
1338a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
1339a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1340a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1341a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  static void
1342a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_subfont_done( FT_Memory    memory,
1343a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                    CFF_SubFont  subfont )
1344a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
1345a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( subfont )
1346a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
1347a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      cff_index_done( &subfont->local_subrs_index );
1348a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FREE( subfont->local_subrs );
1349a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
1350a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
1351a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1352a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1353a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  FT_LOCAL_DEF( FT_Error )
1354a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  cff_font_load( FT_Stream  stream,
1355a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                 FT_Int     face_index,
1356a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                 CFF_Font   font )
1357a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  {
1358a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    static const FT_Frame_Field  cff_header_fields[] =
1359a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
1360a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#undef  FT_STRUCTURE
1361a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define FT_STRUCTURE  CFF_FontRec
1362a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1363a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FRAME_START( 4 ),
1364a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_FRAME_BYTE( version_major ),
1365a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_FRAME_BYTE( version_minor ),
13665ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org        FT_FRAME_BYTE( header_size ),
1367a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        FT_FRAME_BYTE( absolute_offsize ),
1368a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_FRAME_END
1369a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    };
1370a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1371a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    FT_Error         error;
13728bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_Memory        memory = stream->memory;
13738bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_ULong         base_offset;
13748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    CFF_FontRecDict  dict;
13758bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13768bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13778bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    FT_ZERO( font );
13788bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    font->stream = stream;
13808bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    font->memory = memory;
13818bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    dict         = &font->top_font.font_dict;
13828bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    base_offset  = FT_STREAM_POS();
13838bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
138437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    /* read CFF font header */
1385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
138638e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org      goto Exit;
138738e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org
138838e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org    /* check format */
138938e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org    if ( font->version_major   != 1 ||
1390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org         font->header_size      < 4 ||
1391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org         font->absolute_offsize > 4 )
1392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    {
1393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      FT_TRACE2(( "[not a CFF font header!]\n" ));
1394a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = CFF_Err_Unknown_File_Format;
1395a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      goto Exit;
139637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    }
1397a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1398755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org    /* skip the rest of the header */
1399755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1400755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org      goto Exit;
1401755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org
1402755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org    /* read the name, top dict, string and global subrs index */
1403755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1404755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org                                       stream, 0 ) )              ||
1405755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1406a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                       stream, 0 ) )              ||
1407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org         FT_SET_ERROR( cff_index_init( &font->string_index,
140838e4c715e3a3df4ef11ccd3b86525be8f686ecb5ager@chromium.org                                       stream, 0 ) )              ||
1409755c5b1cc880bc54405d2652f934a941e8fcda4asgjesse@chromium.org         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                       stream, 1 ) )              )
141137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      goto Exit;
1412a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1413a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* well, we don't really forget the `disabled' fonts... */
1414a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    font->num_faces = font->name_index.count;
14158bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if ( face_index >= (FT_Int)font->num_faces )
14168bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    {
14178bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
14188bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                 face_index ));
141937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      error = CFF_Err_Invalid_Argument;
1420245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org    }
14218bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1422a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* in case of a font format check, simply exit now */
14238bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if ( face_index < 0 )
142437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      goto Exit;
1425245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org
1426a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    /* now, parse the top-level font dictionary */
1427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    error = cff_subfont_load( &font->top_font,
1428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                              &font->font_dict_index,
1429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                              face_index,
1430a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                              stream,
1431a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                              base_offset );
1432a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if ( error )
14337be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      goto Exit;
14347be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
14357be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1436ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      goto Exit;
14377be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
14387be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    error = cff_index_init( &font->charstrings_index, stream, 0 );
14397be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    if ( error )
14407be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      goto Exit;
14417be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
14427be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    /* now, check for a CID font */
14437be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    if ( dict->cid_registry != 0xFFFFU )
14447be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org    {
14457be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      CFF_IndexRec  fd_index;
14467be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      CFF_SubFont   sub;
14477be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      FT_UInt       idx;
14487be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
14497be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org
14507be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      /* this is a CID-keyed font, we must now allocate a table of */
14517be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org      /* sub-fonts, then load each of them separately              */
14528bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1453a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        goto Exit;
1454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1455a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      error = cff_index_init( &fd_index, stream, 0 );
1456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      if ( error )
14570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        goto Exit;
14580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
145944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org      if ( fd_index.count > CFF_MAX_CID_FONTS )
14600c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      {
1461ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
14620c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        goto Fail_CID;
14630c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      }
1464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
14650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* allocate & read each font dict independently */
14660c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      font->num_subfonts = fd_index.count;
14670c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1468ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        goto Fail_CID;
14690c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
14700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* set up pointer table */
14710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      for ( idx = 0; idx < fd_index.count; idx++ )
14720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        font->subfonts[idx] = sub + idx;
14730c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
14740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* now load each subfont independently */
14750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      for ( idx = 0; idx < fd_index.count; idx++ )
14760c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      {
14770c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        sub = font->subfonts[idx];
14780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org        error = cff_subfont_load( sub, &fd_index, idx,
1479ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                  stream, base_offset );
1480ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        if ( error )
14810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org          goto Fail_CID;
14820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      }
14830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
14840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      /* now load the FD Select array */
14850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org      error = CFF_Load_FD_Select( &font->fd_select,
14860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                                  font->charstrings_index.count,
14870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                                  stream,
14880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org                                  base_offset + dict->cid_fd_select_offset );
14890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
149043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Fail_CID:
149143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      cff_index_done( &fd_index );
149243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1493      if ( error )
1494        goto Exit;
1495    }
1496    else
1497      font->num_subfonts = 0;
1498
1499    /* read the charstrings index now */
1500    if ( dict->charstrings_offset == 0 )
1501    {
1502      FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
1503      error = CFF_Err_Unknown_File_Format;
1504      goto Exit;
1505    }
1506
1507    /* explicit the global subrs */
1508    font->num_global_subrs = font->global_subrs_index.count;
1509    font->num_glyphs       = font->charstrings_index.count;
1510
1511    error = cff_index_get_pointers( &font->global_subrs_index,
1512                                    &font->global_subrs ) ;
1513
1514    if ( error )
1515      goto Exit;
1516
1517    /* read the Charset and Encoding tables if available */
1518    if ( font->num_glyphs > 0 )
1519    {
1520      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU );
1521
1522
1523      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1524                                base_offset, dict->charset_offset, invert );
1525      if ( error )
1526        goto Exit;
1527
1528      /* CID-keyed CFFs don't have an encoding */
1529      if ( dict->cid_registry == 0xFFFFU )
1530      {
1531        error = cff_encoding_load( &font->encoding,
1532                                   &font->charset,
1533                                   font->num_glyphs,
1534                                   stream,
1535                                   base_offset,
1536                                   dict->encoding_offset );
1537        if ( error )
1538          goto Exit;
1539      }
1540      else
1541        /* CID-keyed fonts only need CIDs */
1542        FT_FREE( font->charset.sids );
1543    }
1544
1545    /* get the font name (/CIDFontName for CID-keyed fonts, */
1546    /* /FontName otherwise)                                 */
1547    font->font_name = cff_index_get_name( &font->name_index, face_index );
1548
1549  Exit:
1550    return error;
1551  }
1552
1553
1554  FT_LOCAL_DEF( void )
1555  cff_font_done( CFF_Font  font )
1556  {
1557    FT_Memory  memory = font->memory;
1558    FT_UInt    idx;
1559
1560
1561    cff_index_done( &font->global_subrs_index );
1562    cff_index_done( &font->string_index );
1563    cff_index_done( &font->font_dict_index );
1564    cff_index_done( &font->name_index );
1565    cff_index_done( &font->charstrings_index );
1566
1567    /* release font dictionaries, but only if working with */
1568    /* a CID keyed CFF font                                */
1569    if ( font->num_subfonts > 0 )
1570    {
1571      for ( idx = 0; idx < font->num_subfonts; idx++ )
1572        cff_subfont_done( memory, font->subfonts[idx] );
1573
1574      /* the subfonts array has been allocated as a single block */
1575      FT_FREE( font->subfonts[0] );
1576    }
1577
1578    cff_encoding_done( &font->encoding );
1579    cff_charset_done( &font->charset, font->stream );
1580
1581    cff_subfont_done( memory, &font->top_font );
1582
1583    CFF_Done_FD_Select( &font->fd_select, font->stream );
1584
1585    if (font->font_info != NULL)
1586    {
1587      FT_FREE( font->font_info->version );
1588      FT_FREE( font->font_info->notice );
1589      FT_FREE( font->font_info->full_name );
1590      FT_FREE( font->font_info->family_name );
1591      FT_FREE( font->font_info->weight );
1592      FT_FREE( font->font_info );
1593    }
1594
1595    FT_FREE( font->registry );
1596    FT_FREE( font->ordering );
1597
1598    FT_FREE( font->global_subrs );
1599    FT_FREE( font->font_name );
1600  }
1601
1602
1603/* END */
1604