195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org/***************************************************************************/ 295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org/* */ 301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* cffload.c */ 401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* */ 501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* OpenType and CFF data/program tables loader (body). */ 6eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org/* */ 7eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org/* Copyright 1996-2013 by */ 801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* */ 1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* This file is part of the FreeType project, and may only be used, */ 11abf28c9e0d607e293a9d790300090e557be6b41ejoi@chromium.org/* modified, and distributed under the terms of the FreeType project */ 1201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* this file you indicate that you have read the license and */ 14b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org/* understand and accept it fully. */ 1501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/* */ 1601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org/***************************************************************************/ 17eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 18eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 19b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org#include "../../include/ft2build.h" 2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include "../../include/freetype/internal/ftdebug.h" 2101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include "../../include/freetype/internal/ftobjs.h" 2277cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#include "../../include/freetype/internal/ftstream.h" 2377cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#include "../../include/freetype/tttags.h" 2477cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#include "../../include/freetype/t1tables.h" 2577cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 2677cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#include "cffload.h" 2777cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#include "cffparse.h" 2877cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 2977cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#include "cfferrs.h" 3077cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 3177cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 3277cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org#if 1 3377cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 3477cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org static const FT_UShort cff_isoadobe_charset[229] = 3577cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org { 3677cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 0, 1, 2, 3, 4, 5, 6, 7, 3701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 8, 9, 10, 11, 12, 13, 14, 15, 38eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 16, 17, 18, 19, 20, 21, 22, 23, 3901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 24, 25, 26, 27, 28, 29, 30, 31, 4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 32, 33, 34, 35, 36, 37, 38, 39, 4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 40, 41, 42, 43, 44, 45, 46, 47, 4201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 48, 49, 50, 51, 52, 53, 54, 55, 4301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 56, 57, 58, 59, 60, 61, 62, 63, 44eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 64, 65, 66, 67, 68, 69, 70, 71, 45b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org 72, 73, 74, 75, 76, 77, 78, 79, 4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 80, 81, 82, 83, 84, 85, 86, 87, 4701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 88, 89, 90, 91, 92, 93, 94, 95, 4801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 96, 97, 98, 99, 100, 101, 102, 103, 4901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 104, 105, 106, 107, 108, 109, 110, 111, 5001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 112, 113, 114, 115, 116, 117, 118, 119, 5101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 120, 121, 122, 123, 124, 125, 126, 127, 5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 128, 129, 130, 131, 132, 133, 134, 135, 5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 136, 137, 138, 139, 140, 141, 142, 143, 5401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 144, 145, 146, 147, 148, 149, 150, 151, 5501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 152, 153, 154, 155, 156, 157, 158, 159, 5601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 160, 161, 162, 163, 164, 165, 166, 167, 5701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 168, 169, 170, 171, 172, 173, 174, 175, 5801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 176, 177, 178, 179, 180, 181, 182, 183, 5901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 184, 185, 186, 187, 188, 189, 190, 191, 606740fffb81bff917e8f43523e922baaed7929824joi@chromium.org 192, 193, 194, 195, 196, 197, 198, 199, 616740fffb81bff917e8f43523e922baaed7929824joi@chromium.org 200, 201, 202, 203, 204, 205, 206, 207, 626740fffb81bff917e8f43523e922baaed7929824joi@chromium.org 208, 209, 210, 211, 212, 213, 214, 215, 636740fffb81bff917e8f43523e922baaed7929824joi@chromium.org 216, 217, 218, 219, 220, 221, 222, 223, 646740fffb81bff917e8f43523e922baaed7929824joi@chromium.org 224, 225, 226, 227, 228 656740fffb81bff917e8f43523e922baaed7929824joi@chromium.org }; 6601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 6701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org static const FT_UShort cff_expert_charset[166] = 6801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 6901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 1, 229, 230, 231, 232, 233, 234, 7001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 235, 236, 237, 238, 13, 14, 15, 99, 7101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 239, 240, 241, 242, 243, 244, 245, 246, 7201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 247, 248, 27, 28, 249, 250, 251, 252, 7301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 253, 254, 255, 256, 257, 258, 259, 260, 7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 261, 262, 263, 264, 265, 266, 109, 110, 7583717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 267, 268, 269, 270, 271, 272, 273, 274, 7683717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 275, 276, 277, 278, 279, 280, 281, 282, 7783717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 283, 284, 285, 286, 287, 288, 289, 290, 78eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 291, 292, 293, 294, 295, 296, 297, 298, 7901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 299, 300, 301, 302, 303, 304, 305, 306, 8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 307, 308, 309, 310, 311, 312, 313, 314, 8183717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 315, 316, 317, 318, 158, 155, 163, 319, 8283717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 320, 321, 322, 323, 324, 325, 326, 150, 8383717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 164, 169, 327, 328, 329, 330, 331, 332, 8483717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 333, 334, 335, 336, 337, 338, 339, 340, 8583717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 341, 342, 343, 344, 345, 346, 347, 348, 8683717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 349, 350, 351, 352, 353, 354, 355, 356, 8783717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 357, 358, 359, 360, 361, 362, 363, 364, 8883717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 365, 366, 367, 368, 369, 370, 371, 372, 8983717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 373, 374, 375, 376, 377, 378 9001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org }; 9101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 9201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org static const FT_UShort cff_expertsubset_charset[87] = 9301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 940b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 0, 1, 231, 232, 235, 236, 237, 238, 950b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 13, 14, 15, 99, 239, 240, 241, 242, 960b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 243, 244, 245, 246, 247, 248, 27, 28, 970b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 249, 250, 251, 253, 254, 255, 256, 257, 980b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 258, 259, 260, 261, 262, 263, 264, 265, 990b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 266, 109, 110, 267, 268, 269, 270, 272, 1000b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 300, 301, 302, 305, 314, 315, 158, 155, 1010b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 163, 320, 321, 322, 323, 324, 325, 326, 1020b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 150, 164, 169, 327, 328, 329, 330, 331, 1030b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 332, 333, 334, 335, 336, 337, 338, 339, 1040b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 340, 341, 342, 343, 344, 345, 346 1050b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org }; 1060b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 1070b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org static const FT_UShort cff_standard_encoding[256] = 108ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org { 1090b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 1100b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 1110b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 1120b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 1130b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 1, 2, 3, 4, 5, 6, 7, 8, 1140b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 9, 10, 11, 12, 13, 14, 15, 16, 1150b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 17, 18, 19, 20, 21, 22, 23, 24, 1160b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 25, 26, 27, 28, 29, 30, 31, 32, 1170b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 33, 34, 35, 36, 37, 38, 39, 40, 1180b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 41, 42, 43, 44, 45, 46, 47, 48, 1190b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 49, 50, 51, 52, 53, 54, 55, 56, 1200b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 57, 58, 59, 60, 61, 62, 63, 64, 1210b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 65, 66, 67, 68, 69, 70, 71, 72, 1220b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 73, 74, 75, 76, 77, 78, 79, 80, 1230b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 81, 82, 83, 84, 85, 86, 87, 88, 1240b961d0af2fe00a650a882b13752e46c8aef3710benrg@chromium.org 89, 90, 91, 92, 93, 94, 95, 0, 12577cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 12601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 12783717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 12883717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 12983717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 96, 97, 98, 99, 100, 101, 102, 13083717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 103, 104, 105, 106, 107, 108, 109, 110, 13183717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 111, 112, 113, 114, 0, 115, 116, 13283717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 117, 118, 119, 120, 121, 122, 0, 123, 13383717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 124, 125, 126, 127, 128, 129, 130, 13483717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 131, 0, 132, 133, 0, 134, 135, 136, 13583717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 137, 0, 0, 0, 0, 0, 0, 0, 13683717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 13783717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 138, 0, 139, 0, 0, 0, 0, 13883717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 140, 141, 142, 143, 0, 0, 0, 0, 13983717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 0, 144, 0, 0, 0, 145, 0, 0, 14083717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org 146, 147, 148, 149, 0, 0, 0, 0 14183717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org }; 14201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 143eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org static const FT_UShort cff_expert_encoding[256] = 14401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 14501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 14601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 14701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 14801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 14901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 1, 229, 230, 0, 231, 232, 233, 234, 15001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 235, 236, 237, 238, 13, 14, 15, 99, 15101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 239, 240, 241, 242, 243, 244, 245, 246, 15201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 247, 248, 27, 28, 249, 250, 251, 252, 15301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 253, 254, 255, 256, 257, 0, 0, 15401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 258, 0, 0, 259, 260, 261, 262, 15501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 263, 264, 265, 0, 266, 109, 15601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 110, 267, 268, 269, 0, 270, 271, 272, 15701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 273, 274, 275, 276, 277, 278, 279, 280, 15801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 281, 282, 283, 284, 285, 286, 287, 288, 15901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 289, 290, 291, 292, 293, 294, 295, 296, 16001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 297, 298, 299, 300, 301, 302, 303, 0, 16101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 16201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 163eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 16401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 0, 0, 0, 0, 0, 0, 0, 16501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 0, 304, 305, 306, 0, 0, 307, 308, 16601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 309, 310, 311, 0, 312, 0, 0, 312, 167eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 0, 0, 314, 315, 0, 0, 316, 317, 16801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 318, 0, 0, 0, 158, 155, 163, 319, 16901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 320, 321, 322, 323, 324, 325, 0, 0, 170b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org 326, 150, 164, 169, 327, 328, 329, 330, 17101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 331, 332, 333, 334, 335, 336, 337, 338, 17201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 339, 340, 341, 342, 343, 344, 345, 346, 173783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org 347, 348, 349, 350, 351, 352, 353, 354, 174abf28c9e0d607e293a9d790300090e557be6b41ejoi@chromium.org 355, 356, 357, 358, 359, 360, 361, 362, 17501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 363, 364, 365, 366, 367, 368, 369, 370, 17601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 371, 372, 373, 374, 375, 376, 377, 378 17701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org }; 17801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 17901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#endif /* 1 */ 18001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 18101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 1820dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org FT_LOCAL_DEF( FT_UShort ) 18301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org cff_get_standard_encoding( FT_UInt charcode ) 184bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org { 185db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode] 18601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org : 0 ); 18701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 18801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 18901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 19001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /*************************************************************************/ 19101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* */ 19201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 19301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 19401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* messages during execution. */ 19501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* */ 19601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#undef FT_COMPONENT 19701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define FT_COMPONENT trace_cffload 1980dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 19977cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 20001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* read an offset from the index's stream current position */ 20101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org static FT_ULong 20201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org cff_index_read_offset( CFF_Index idx, 203db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org FT_Error *errorp ) 204db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org { 20501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_Error error; 20601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_Stream stream = idx->stream; 20701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_Byte tmp[4]; 208b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org FT_ULong result = 0; 20901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 21001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 21101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( !FT_STREAM_READ( tmp, idx->off_size ) ) 21201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 21301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_Int nn; 21401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 21501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 21601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org for ( nn = 0; nn < idx->off_size; nn++ ) 21701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org result = ( result << 8 ) | tmp[nn]; 21801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 21901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 22001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org *errorp = error; 22101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org return result; 22201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 22301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 22401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 22501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org static FT_Error 226eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org cff_index_init( CFF_Index idx, 22701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_Stream stream, 228eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_Bool load ) 22901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 23001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_Error error; 231ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_Memory memory = stream->memory; 232ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_UShort count; 233ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 234ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 235cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org FT_MEM_ZERO( idx, sizeof ( *idx ) ); 236cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org 237ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org idx->stream = stream; 238ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org idx->start = FT_STREAM_POS(); 239ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org if ( !FT_READ_USHORT( count ) && 240ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org count > 0 ) 241ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org { 242ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_Byte offsize; 243ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_ULong size; 244ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 24501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 24601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* there is at least one element; read the offset size, */ 24701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* then access the offset table to compute the index's total size */ 24801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( FT_READ_BYTE( offsize ) ) 24901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org goto Exit; 25001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 251eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org if ( offsize < 1 || offsize > 4 ) 25201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 25301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org error = FT_THROW( Invalid_Table ); 25401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org goto Exit; 255eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org } 25601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 25701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org idx->count = count; 25801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org idx->off_size = offsize; 259eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org size = (FT_ULong)( count + 1 ) * offsize; 26001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 26101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org idx->data_offset = idx->start + 3 + size; 26201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 263eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org if ( FT_STREAM_SKIP( size - offsize ) ) 264eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org goto Exit; 26501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 26601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org size = cff_index_read_offset( idx, &error ); 26701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( error ) 268eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org goto Exit; 26901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 27001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( size == 0 ) 27101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 27201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org error = FT_THROW( Invalid_Table ); 27301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org goto Exit; 27401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 27501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 27601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org idx->data_size = --size; 277eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 27801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( load ) 27901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 28001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* load the data */ 28101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( FT_FRAME_EXTRACT( size, idx->bytes ) ) 282eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org goto Exit; 28301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 284eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org else 28501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 28601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* skip the data */ 28701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( FT_STREAM_SKIP( size ) ) 28801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org goto Exit; 28901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 29001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 291eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 292eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org Exit: 29301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( error ) 29401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_FREE( idx->offsets ); 295bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org 296bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org return error; 297bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org } 298bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org 299bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org 300bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org static void 301bd79a1642abbe801db78778a59cdafc10e70bcccjoi@chromium.org cff_index_done( CFF_Index idx ) 302db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org { 303db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org if ( idx->stream ) 304db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org { 305db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org FT_Stream stream = idx->stream; 306db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org FT_Memory memory = stream->memory; 307db2e077842c311c22eb33a13cc9eb9fadb7def5ajoi@chromium.org 308eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 309eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org if ( idx->bytes ) 310eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_FRAME_RELEASE( idx->bytes ); 311eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 312eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_FREE( idx->offsets ); 313eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_MEM_ZERO( idx, sizeof ( *idx ) ); 31483717e82a9b5e0c629ff4f1078d50503ffd2ae75benrg@chromium.org } 315eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org } 316eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 317eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 318ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org static FT_Error 319ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org cff_index_load_offsets( CFF_Index idx ) 320c5a84104bae5837c1be2e879b343af5140baea35benrg@chromium.org { 321ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_Error error = FT_Err_Ok; 322ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_Stream stream = idx->stream; 323ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org FT_Memory memory = stream->memory; 324ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 325ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 326ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org if ( idx->count > 0 && idx->offsets == NULL ) 327ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org { 328c5a84104bae5837c1be2e879b343af5140baea35benrg@chromium.org FT_Byte offsize = idx->off_size; 329ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_ULong data_size; 330eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_Byte* p; 3310dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org FT_Byte* p_end; 332eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_ULong* poff; 3330dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 3340dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 3350dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org data_size = (FT_ULong)( idx->count + 1 ) * offsize; 3360dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 3370dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || 3380dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org FT_STREAM_SEEK( idx->start + 3 ) || 339eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org FT_FRAME_ENTER( data_size ) ) 3400dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org goto Exit; 3410dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 3420dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org poff = idx->offsets; 3430dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org p = (FT_Byte*)stream->cursor; 3445a132756a9c06c4242c1b2a678435fc618a92dcbsergeyu@chromium.org p_end = p + data_size; 3455a132756a9c06c4242c1b2a678435fc618a92dcbsergeyu@chromium.org 3465a132756a9c06c4242c1b2a678435fc618a92dcbsergeyu@chromium.org switch ( offsize ) 3475a132756a9c06c4242c1b2a678435fc618a92dcbsergeyu@chromium.org { 3480dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org case 1: 3490dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org for ( ; p < p_end; p++, poff++ ) 3500dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org poff[0] = p[0]; 35101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org break; 352eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 35301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org case 2: 354eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org for ( ; p < p_end; p += 2, poff++ ) 35501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org poff[0] = FT_PEEK_USHORT( p ); 35601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org break; 357ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 358ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org case 3: 35901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org for ( ; p < p_end; p += 3, poff++ ) 36001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org poff[0] = FT_PEEK_OFF3( p ); 361ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org break; 362ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 363ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org default: 364ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org for ( ; p < p_end; p += 4, poff++ ) 365ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org poff[0] = FT_PEEK_ULONG( p ); 36677cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org } 367eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 368ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_FRAME_EXIT(); 369ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org } 370ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 37101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org Exit: 372783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org if ( error ) 373ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org FT_FREE( idx->offsets ); 37477cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 375ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org return error; 37677cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org } 37777cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 37877cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 37977cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org /* Allocate a table containing pointers to an index's elements. */ 380cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org /* The `pool' argument makes this function convert the index */ 381eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org /* entries to C-style strings (this is, NULL-terminated). */ 382783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org static FT_Error 383783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org cff_index_get_pointers( CFF_Index idx, 384783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_Byte*** table, 385783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_Byte** pool ) 386783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org { 387783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_Error error = FT_Err_Ok; 388783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_Memory memory = idx->stream->memory; 389783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org 390ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org FT_Byte** t = NULL; 391ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org FT_Byte* new_bytes = NULL; 392ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org 393ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org 39401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org *table = NULL; 39501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 39601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( idx->offsets == NULL ) 397783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org { 398783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org error = cff_index_load_offsets( idx ); 399abf28c9e0d607e293a9d790300090e557be6b41ejoi@chromium.org if ( error ) 400abf28c9e0d607e293a9d790300090e557be6b41ejoi@chromium.org goto Exit; 401abf28c9e0d607e293a9d790300090e557be6b41ejoi@chromium.org } 402783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org 403783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org if ( idx->count > 0 && 404783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org !FT_NEW_ARRAY( t, idx->count + 1 ) && 405783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org ( !pool || !FT_ALLOC( new_bytes, 406783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org idx->data_size + idx->count ) ) ) 407783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org { 408783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_ULong n, cur_offset; 409783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_ULong extra = 0; 410783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org FT_Byte* org_bytes = idx->bytes; 411783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org 412783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org 413783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org /* at this point, `idx->offsets' can't be NULL */ 414783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org cur_offset = idx->offsets[0] - 1; 415783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org 416783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org /* sanity check */ 417783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org if ( cur_offset >= idx->data_size ) 41801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 4190dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org FT_TRACE0(( "cff_index_get_pointers:" 420eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org " invalid first offset value %d set to zero\n", 4210dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org cur_offset )); 422eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org cur_offset = 0; 42301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 42401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 42501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( !pool ) 42601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org t[0] = org_bytes + cur_offset; 42701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org else 4280dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org t[0] = new_bytes + cur_offset; 4290dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 4300dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org for ( n = 1; n <= idx->count; n++ ) 4310dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org { 4320dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org FT_ULong next_offset = idx->offsets[n] - 1; 4330dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 4340dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 43501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* empty slot + two sanity checks for invalid offset tables */ 436ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org if ( next_offset == 0 || 43701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org next_offset < cur_offset || 438625ae8faf7992cf919dfc6323d18dc4b6aed04fdjochen@chromium.org ( next_offset >= idx->data_size && n < idx->count ) ) 439625ae8faf7992cf919dfc6323d18dc4b6aed04fdjochen@chromium.org next_offset = cur_offset; 440625ae8faf7992cf919dfc6323d18dc4b6aed04fdjochen@chromium.org 441625ae8faf7992cf919dfc6323d18dc4b6aed04fdjochen@chromium.org if ( !pool ) 442625ae8faf7992cf919dfc6323d18dc4b6aed04fdjochen@chromium.org t[n] = org_bytes + next_offset; 443625ae8faf7992cf919dfc6323d18dc4b6aed04fdjochen@chromium.org else 44401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 44501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org t[n] = new_bytes + next_offset + extra; 4460dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org 4470dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org if ( next_offset != cur_offset ) 4480dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org { 4490dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); 45001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org t[n][0] = '\0'; 45101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org t[n] += 1; 45201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org extra++; 45301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 45401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 45501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 45601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org cur_offset = next_offset; 4570dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org } 4580dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org *table = t; 45901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 46001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( pool ) 46101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org *pool = new_bytes; 46201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 46301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 46401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org Exit: 46501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org return error; 4660dc1eef9854b5a4102aee7b7acae978eec2e4df9joi@chromium.org } 46701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 468ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 469ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_LOCAL_DEF( FT_Error ) 470ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org cff_index_access_element( CFF_Index idx, 47177cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org FT_UInt element, 472ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_Byte** pbytes, 473ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_ULong* pbyte_len ) 474ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org { 4751eddb32f808ac5930f24b1954b5c949b273a3869joi@chromium.org FT_Error error = FT_Err_Ok; 47677cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 47777cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org 478ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org if ( idx && idx->count > element ) 479ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org { 480ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org /* compute start and end offsets */ 481ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_Stream stream = idx->stream; 482ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_ULong off1, off2 = 0; 4831eddb32f808ac5930f24b1954b5c949b273a3869joi@chromium.org 484ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 485ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org /* load offsets from file or the offset table */ 4861eddb32f808ac5930f24b1954b5c949b273a3869joi@chromium.org if ( !idx->offsets ) 487ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org { 488ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org FT_ULong pos = element * idx->off_size; 489ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 490ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org 49177cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) 49201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org goto Exit; 49301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 494eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org off1 = cff_index_read_offset( idx, &error ); 49501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( error ) 49601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org goto Exit; 497eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org 49801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( off1 != 0 ) 49901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 50001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org do 50101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 50201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org element++; 503cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org off2 = cff_index_read_offset( idx, &error ); 50401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org } 50501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org while ( off2 == 0 && element < idx->count ); 506eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org } 507eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org } 50801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org else /* use offsets table */ 50901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 51001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org off1 = idx->offsets[element]; 51101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( off1 ) 512cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org { 513eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org do 514b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org { 515cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org element++; 516cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org off2 = idx->offsets[element]; 517cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org 518cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org } while ( off2 == 0 && element < idx->count ); 519cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org } 520eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org } 52101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org 522eda8d69f7c49419eef6e96a1cd42af26a864d794joi@chromium.org /* XXX: should check off2 does not exceed the end of this entry; */ 52301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org /* at present, only truncate off2 at the end of this stream */ 52401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org if ( off2 > stream->size + 1 || 52501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org idx->data_offset > stream->size - off2 + 1 ) 52601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org { 52701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org FT_ERROR(( "cff_index_access_element:" 528cb59a41015e4a21a5bd865f5646e19d99a3d03aajoi@chromium.org " offset to next entry (%d)" 52901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org " exceeds the end of stream (%d)\n", 53001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org off2, stream->size - idx->data_offset + 1 )); 531 off2 = stream->size - idx->data_offset + 1; 532 } 533 534 /* access element */ 535 if ( off1 && off2 > off1 ) 536 { 537 *pbyte_len = off2 - off1; 538 539 if ( idx->bytes ) 540 { 541 /* this index was completely loaded in memory, that's easy */ 542 *pbytes = idx->bytes + off1 - 1; 543 } 544 else 545 { 546 /* this index is still on disk/file, access it through a frame */ 547 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) || 548 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) ) 549 goto Exit; 550 } 551 } 552 else 553 { 554 /* empty index element */ 555 *pbytes = 0; 556 *pbyte_len = 0; 557 } 558 } 559 else 560 error = FT_THROW( Invalid_Argument ); 561 562 Exit: 563 return error; 564 } 565 566 567 FT_LOCAL_DEF( void ) 568 cff_index_forget_element( CFF_Index idx, 569 FT_Byte** pbytes ) 570 { 571 if ( idx->bytes == 0 ) 572 { 573 FT_Stream stream = idx->stream; 574 575 576 FT_FRAME_RELEASE( *pbytes ); 577 } 578 } 579 580 581 /* get an entry from Name INDEX */ 582 FT_LOCAL_DEF( FT_String* ) 583 cff_index_get_name( CFF_Font font, 584 FT_UInt element ) 585 { 586 CFF_Index idx = &font->name_index; 587 FT_Memory memory = idx->stream->memory; 588 FT_Byte* bytes; 589 FT_ULong byte_len; 590 FT_Error error; 591 FT_String* name = 0; 592 593 594 error = cff_index_access_element( idx, element, &bytes, &byte_len ); 595 if ( error ) 596 goto Exit; 597 598 if ( !FT_ALLOC( name, byte_len + 1 ) ) 599 { 600 FT_MEM_COPY( name, bytes, byte_len ); 601 name[byte_len] = 0; 602 } 603 cff_index_forget_element( idx, &bytes ); 604 605 Exit: 606 return name; 607 } 608 609 610 /* get an entry from String INDEX */ 611 FT_LOCAL_DEF( FT_String* ) 612 cff_index_get_string( CFF_Font font, 613 FT_UInt element ) 614 { 615 return ( element < font->num_strings ) 616 ? (FT_String*)font->strings[element] 617 : NULL; 618 } 619 620 621 FT_LOCAL_DEF( FT_String* ) 622 cff_index_get_sid_string( CFF_Font font, 623 FT_UInt sid ) 624 { 625 /* value 0xFFFFU indicates a missing dictionary entry */ 626 if ( sid == 0xFFFFU ) 627 return NULL; 628 629 /* if it is not a standard string, return it */ 630 if ( sid > 390 ) 631 return cff_index_get_string( font, sid - 391 ); 632 633 /* CID-keyed CFF fonts don't have glyph names */ 634 if ( !font->psnames ) 635 return NULL; 636 637 /* this is a standard string */ 638 return (FT_String *)font->psnames->adobe_std_strings( sid ); 639 } 640 641 642 /*************************************************************************/ 643 /*************************************************************************/ 644 /*** ***/ 645 /*** FD Select table support ***/ 646 /*** ***/ 647 /*************************************************************************/ 648 /*************************************************************************/ 649 650 651 static void 652 CFF_Done_FD_Select( CFF_FDSelect fdselect, 653 FT_Stream stream ) 654 { 655 if ( fdselect->data ) 656 FT_FRAME_RELEASE( fdselect->data ); 657 658 fdselect->data_size = 0; 659 fdselect->format = 0; 660 fdselect->range_count = 0; 661 } 662 663 664 static FT_Error 665 CFF_Load_FD_Select( CFF_FDSelect fdselect, 666 FT_UInt num_glyphs, 667 FT_Stream stream, 668 FT_ULong offset ) 669 { 670 FT_Error error; 671 FT_Byte format; 672 FT_UInt num_ranges; 673 674 675 /* read format */ 676 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) 677 goto Exit; 678 679 fdselect->format = format; 680 fdselect->cache_count = 0; /* clear cache */ 681 682 switch ( format ) 683 { 684 case 0: /* format 0, that's simple */ 685 fdselect->data_size = num_glyphs; 686 goto Load_Data; 687 688 case 3: /* format 3, a tad more complex */ 689 if ( FT_READ_USHORT( num_ranges ) ) 690 goto Exit; 691 692 fdselect->data_size = num_ranges * 3 + 2; 693 694 Load_Data: 695 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) 696 goto Exit; 697 break; 698 699 default: /* hmm... that's wrong */ 700 error = FT_THROW( Invalid_File_Format ); 701 } 702 703 Exit: 704 return error; 705 } 706 707 708 FT_LOCAL_DEF( FT_Byte ) 709 cff_fd_select_get( CFF_FDSelect fdselect, 710 FT_UInt glyph_index ) 711 { 712 FT_Byte fd = 0; 713 714 715 switch ( fdselect->format ) 716 { 717 case 0: 718 fd = fdselect->data[glyph_index]; 719 break; 720 721 case 3: 722 /* first, compare to cache */ 723 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) < 724 fdselect->cache_count ) 725 { 726 fd = fdselect->cache_fd; 727 break; 728 } 729 730 /* then, lookup the ranges array */ 731 { 732 FT_Byte* p = fdselect->data; 733 FT_Byte* p_limit = p + fdselect->data_size; 734 FT_Byte fd2; 735 FT_UInt first, limit; 736 737 738 first = FT_NEXT_USHORT( p ); 739 do 740 { 741 if ( glyph_index < first ) 742 break; 743 744 fd2 = *p++; 745 limit = FT_NEXT_USHORT( p ); 746 747 if ( glyph_index < limit ) 748 { 749 fd = fd2; 750 751 /* update cache */ 752 fdselect->cache_first = first; 753 fdselect->cache_count = limit-first; 754 fdselect->cache_fd = fd2; 755 break; 756 } 757 first = limit; 758 759 } while ( p < p_limit ); 760 } 761 break; 762 763 default: 764 ; 765 } 766 767 return fd; 768 } 769 770 771 /*************************************************************************/ 772 /*************************************************************************/ 773 /*** ***/ 774 /*** CFF font support ***/ 775 /*** ***/ 776 /*************************************************************************/ 777 /*************************************************************************/ 778 779 static FT_Error 780 cff_charset_compute_cids( CFF_Charset charset, 781 FT_UInt num_glyphs, 782 FT_Memory memory ) 783 { 784 FT_Error error = FT_Err_Ok; 785 FT_UInt i; 786 FT_Long j; 787 FT_UShort max_cid = 0; 788 789 790 if ( charset->max_cid > 0 ) 791 goto Exit; 792 793 for ( i = 0; i < num_glyphs; i++ ) 794 { 795 if ( charset->sids[i] > max_cid ) 796 max_cid = charset->sids[i]; 797 } 798 799 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) ) 800 goto Exit; 801 802 /* When multiple GIDs map to the same CID, we choose the lowest */ 803 /* GID. This is not described in any spec, but it matches the */ 804 /* behaviour of recent Acroread versions. */ 805 for ( j = num_glyphs - 1; j >= 0 ; j-- ) 806 charset->cids[charset->sids[j]] = (FT_UShort)j; 807 808 charset->max_cid = max_cid; 809 charset->num_glyphs = num_glyphs; 810 811 Exit: 812 return error; 813 } 814 815 816 FT_LOCAL_DEF( FT_UInt ) 817 cff_charset_cid_to_gindex( CFF_Charset charset, 818 FT_UInt cid ) 819 { 820 FT_UInt result = 0; 821 822 823 if ( cid <= charset->max_cid ) 824 result = charset->cids[cid]; 825 826 return result; 827 } 828 829 830 static void 831 cff_charset_free_cids( CFF_Charset charset, 832 FT_Memory memory ) 833 { 834 FT_FREE( charset->cids ); 835 charset->max_cid = 0; 836 } 837 838 839 static void 840 cff_charset_done( CFF_Charset charset, 841 FT_Stream stream ) 842 { 843 FT_Memory memory = stream->memory; 844 845 846 cff_charset_free_cids( charset, memory ); 847 848 FT_FREE( charset->sids ); 849 charset->format = 0; 850 charset->offset = 0; 851 } 852 853 854 static FT_Error 855 cff_charset_load( CFF_Charset charset, 856 FT_UInt num_glyphs, 857 FT_Stream stream, 858 FT_ULong base_offset, 859 FT_ULong offset, 860 FT_Bool invert ) 861 { 862 FT_Memory memory = stream->memory; 863 FT_Error error = FT_Err_Ok; 864 FT_UShort glyph_sid; 865 866 867 /* If the the offset is greater than 2, we have to parse the */ 868 /* charset table. */ 869 if ( offset > 2 ) 870 { 871 FT_UInt j; 872 873 874 charset->offset = base_offset + offset; 875 876 /* Get the format of the table. */ 877 if ( FT_STREAM_SEEK( charset->offset ) || 878 FT_READ_BYTE( charset->format ) ) 879 goto Exit; 880 881 /* Allocate memory for sids. */ 882 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 883 goto Exit; 884 885 /* assign the .notdef glyph */ 886 charset->sids[0] = 0; 887 888 switch ( charset->format ) 889 { 890 case 0: 891 if ( num_glyphs > 0 ) 892 { 893 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) ) 894 goto Exit; 895 896 for ( j = 1; j < num_glyphs; j++ ) 897 charset->sids[j] = FT_GET_USHORT(); 898 899 FT_FRAME_EXIT(); 900 } 901 break; 902 903 case 1: 904 case 2: 905 { 906 FT_UInt nleft; 907 FT_UInt i; 908 909 910 j = 1; 911 912 while ( j < num_glyphs ) 913 { 914 /* Read the first glyph sid of the range. */ 915 if ( FT_READ_USHORT( glyph_sid ) ) 916 goto Exit; 917 918 /* Read the number of glyphs in the range. */ 919 if ( charset->format == 2 ) 920 { 921 if ( FT_READ_USHORT( nleft ) ) 922 goto Exit; 923 } 924 else 925 { 926 if ( FT_READ_BYTE( nleft ) ) 927 goto Exit; 928 } 929 930 /* try to rescue some of the SIDs if `nleft' is too large */ 931 if ( glyph_sid > 0xFFFFL - nleft ) 932 { 933 FT_ERROR(( "cff_charset_load: invalid SID range trimmed" 934 " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid )); 935 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid ); 936 } 937 938 /* Fill in the range of sids -- `nleft + 1' glyphs. */ 939 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ ) 940 charset->sids[j] = glyph_sid; 941 } 942 } 943 break; 944 945 default: 946 FT_ERROR(( "cff_charset_load: invalid table format\n" )); 947 error = FT_THROW( Invalid_File_Format ); 948 goto Exit; 949 } 950 } 951 else 952 { 953 /* Parse default tables corresponding to offset == 0, 1, or 2. */ 954 /* CFF specification intimates the following: */ 955 /* */ 956 /* In order to use a predefined charset, the following must be */ 957 /* true: The charset constructed for the glyphs in the font's */ 958 /* charstrings dictionary must match the predefined charset in */ 959 /* the first num_glyphs. */ 960 961 charset->offset = offset; /* record charset type */ 962 963 switch ( (FT_UInt)offset ) 964 { 965 case 0: 966 if ( num_glyphs > 229 ) 967 { 968 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 969 "predefined charset (Adobe ISO-Latin)\n" )); 970 error = FT_THROW( Invalid_File_Format ); 971 goto Exit; 972 } 973 974 /* Allocate memory for sids. */ 975 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 976 goto Exit; 977 978 /* Copy the predefined charset into the allocated memory. */ 979 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs ); 980 981 break; 982 983 case 1: 984 if ( num_glyphs > 166 ) 985 { 986 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 987 "predefined charset (Adobe Expert)\n" )); 988 error = FT_THROW( Invalid_File_Format ); 989 goto Exit; 990 } 991 992 /* Allocate memory for sids. */ 993 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 994 goto Exit; 995 996 /* Copy the predefined charset into the allocated memory. */ 997 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs ); 998 999 break; 1000 1001 case 2: 1002 if ( num_glyphs > 87 ) 1003 { 1004 FT_ERROR(( "cff_charset_load: implicit charset larger than\n" 1005 "predefined charset (Adobe Expert Subset)\n" )); 1006 error = FT_THROW( Invalid_File_Format ); 1007 goto Exit; 1008 } 1009 1010 /* Allocate memory for sids. */ 1011 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) ) 1012 goto Exit; 1013 1014 /* Copy the predefined charset into the allocated memory. */ 1015 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs ); 1016 1017 break; 1018 1019 default: 1020 error = FT_THROW( Invalid_File_Format ); 1021 goto Exit; 1022 } 1023 } 1024 1025 /* we have to invert the `sids' array for subsetted CID-keyed fonts */ 1026 if ( invert ) 1027 error = cff_charset_compute_cids( charset, num_glyphs, memory ); 1028 1029 Exit: 1030 /* Clean up if there was an error. */ 1031 if ( error ) 1032 { 1033 FT_FREE( charset->sids ); 1034 FT_FREE( charset->cids ); 1035 charset->format = 0; 1036 charset->offset = 0; 1037 charset->sids = 0; 1038 } 1039 1040 return error; 1041 } 1042 1043 1044 static void 1045 cff_encoding_done( CFF_Encoding encoding ) 1046 { 1047 encoding->format = 0; 1048 encoding->offset = 0; 1049 encoding->count = 0; 1050 } 1051 1052 1053 static FT_Error 1054 cff_encoding_load( CFF_Encoding encoding, 1055 CFF_Charset charset, 1056 FT_UInt num_glyphs, 1057 FT_Stream stream, 1058 FT_ULong base_offset, 1059 FT_ULong offset ) 1060 { 1061 FT_Error error = FT_Err_Ok; 1062 FT_UInt count; 1063 FT_UInt j; 1064 FT_UShort glyph_sid; 1065 FT_UInt glyph_code; 1066 1067 1068 /* Check for charset->sids. If we do not have this, we fail. */ 1069 if ( !charset->sids ) 1070 { 1071 error = FT_THROW( Invalid_File_Format ); 1072 goto Exit; 1073 } 1074 1075 /* Zero out the code to gid/sid mappings. */ 1076 for ( j = 0; j < 256; j++ ) 1077 { 1078 encoding->sids [j] = 0; 1079 encoding->codes[j] = 0; 1080 } 1081 1082 /* Note: The encoding table in a CFF font is indexed by glyph index; */ 1083 /* the first encoded glyph index is 1. Hence, we read the character */ 1084 /* code (`glyph_code') at index j and make the assignment: */ 1085 /* */ 1086 /* encoding->codes[glyph_code] = j + 1 */ 1087 /* */ 1088 /* We also make the assignment: */ 1089 /* */ 1090 /* encoding->sids[glyph_code] = charset->sids[j + 1] */ 1091 /* */ 1092 /* This gives us both a code to GID and a code to SID mapping. */ 1093 1094 if ( offset > 1 ) 1095 { 1096 encoding->offset = base_offset + offset; 1097 1098 /* we need to parse the table to determine its size */ 1099 if ( FT_STREAM_SEEK( encoding->offset ) || 1100 FT_READ_BYTE( encoding->format ) || 1101 FT_READ_BYTE( count ) ) 1102 goto Exit; 1103 1104 switch ( encoding->format & 0x7F ) 1105 { 1106 case 0: 1107 { 1108 FT_Byte* p; 1109 1110 1111 /* By convention, GID 0 is always ".notdef" and is never */ 1112 /* coded in the font. Hence, the number of codes found */ 1113 /* in the table is `count+1'. */ 1114 /* */ 1115 encoding->count = count + 1; 1116 1117 if ( FT_FRAME_ENTER( count ) ) 1118 goto Exit; 1119 1120 p = (FT_Byte*)stream->cursor; 1121 1122 for ( j = 1; j <= count; j++ ) 1123 { 1124 glyph_code = *p++; 1125 1126 /* Make sure j is not too big. */ 1127 if ( j < num_glyphs ) 1128 { 1129 /* Assign code to GID mapping. */ 1130 encoding->codes[glyph_code] = (FT_UShort)j; 1131 1132 /* Assign code to SID mapping. */ 1133 encoding->sids[glyph_code] = charset->sids[j]; 1134 } 1135 } 1136 1137 FT_FRAME_EXIT(); 1138 } 1139 break; 1140 1141 case 1: 1142 { 1143 FT_UInt nleft; 1144 FT_UInt i = 1; 1145 FT_UInt k; 1146 1147 1148 encoding->count = 0; 1149 1150 /* Parse the Format1 ranges. */ 1151 for ( j = 0; j < count; j++, i += nleft ) 1152 { 1153 /* Read the first glyph code of the range. */ 1154 if ( FT_READ_BYTE( glyph_code ) ) 1155 goto Exit; 1156 1157 /* Read the number of codes in the range. */ 1158 if ( FT_READ_BYTE( nleft ) ) 1159 goto Exit; 1160 1161 /* Increment nleft, so we read `nleft + 1' codes/sids. */ 1162 nleft++; 1163 1164 /* compute max number of character codes */ 1165 if ( (FT_UInt)nleft > encoding->count ) 1166 encoding->count = nleft; 1167 1168 /* Fill in the range of codes/sids. */ 1169 for ( k = i; k < nleft + i; k++, glyph_code++ ) 1170 { 1171 /* Make sure k is not too big. */ 1172 if ( k < num_glyphs && glyph_code < 256 ) 1173 { 1174 /* Assign code to GID mapping. */ 1175 encoding->codes[glyph_code] = (FT_UShort)k; 1176 1177 /* Assign code to SID mapping. */ 1178 encoding->sids[glyph_code] = charset->sids[k]; 1179 } 1180 } 1181 } 1182 1183 /* simple check; one never knows what can be found in a font */ 1184 if ( encoding->count > 256 ) 1185 encoding->count = 256; 1186 } 1187 break; 1188 1189 default: 1190 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1191 error = FT_THROW( Invalid_File_Format ); 1192 goto Exit; 1193 } 1194 1195 /* Parse supplemental encodings, if any. */ 1196 if ( encoding->format & 0x80 ) 1197 { 1198 FT_UInt gindex; 1199 1200 1201 /* count supplements */ 1202 if ( FT_READ_BYTE( count ) ) 1203 goto Exit; 1204 1205 for ( j = 0; j < count; j++ ) 1206 { 1207 /* Read supplemental glyph code. */ 1208 if ( FT_READ_BYTE( glyph_code ) ) 1209 goto Exit; 1210 1211 /* Read the SID associated with this glyph code. */ 1212 if ( FT_READ_USHORT( glyph_sid ) ) 1213 goto Exit; 1214 1215 /* Assign code to SID mapping. */ 1216 encoding->sids[glyph_code] = glyph_sid; 1217 1218 /* First, look up GID which has been assigned to */ 1219 /* SID glyph_sid. */ 1220 for ( gindex = 0; gindex < num_glyphs; gindex++ ) 1221 { 1222 if ( charset->sids[gindex] == glyph_sid ) 1223 { 1224 encoding->codes[glyph_code] = (FT_UShort)gindex; 1225 break; 1226 } 1227 } 1228 } 1229 } 1230 } 1231 else 1232 { 1233 /* We take into account the fact a CFF font can use a predefined */ 1234 /* encoding without containing all of the glyphs encoded by this */ 1235 /* encoding (see the note at the end of section 12 in the CFF */ 1236 /* specification). */ 1237 1238 switch ( (FT_UInt)offset ) 1239 { 1240 case 0: 1241 /* First, copy the code to SID mapping. */ 1242 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 ); 1243 goto Populate; 1244 1245 case 1: 1246 /* First, copy the code to SID mapping. */ 1247 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 ); 1248 1249 Populate: 1250 /* Construct code to GID mapping from code to SID mapping */ 1251 /* and charset. */ 1252 1253 encoding->count = 0; 1254 1255 error = cff_charset_compute_cids( charset, num_glyphs, 1256 stream->memory ); 1257 if ( error ) 1258 goto Exit; 1259 1260 for ( j = 0; j < 256; j++ ) 1261 { 1262 FT_UInt sid = encoding->sids[j]; 1263 FT_UInt gid = 0; 1264 1265 1266 if ( sid ) 1267 gid = cff_charset_cid_to_gindex( charset, sid ); 1268 1269 if ( gid != 0 ) 1270 { 1271 encoding->codes[j] = (FT_UShort)gid; 1272 encoding->count = j + 1; 1273 } 1274 else 1275 { 1276 encoding->codes[j] = 0; 1277 encoding->sids [j] = 0; 1278 } 1279 } 1280 break; 1281 1282 default: 1283 FT_ERROR(( "cff_encoding_load: invalid table format\n" )); 1284 error = FT_THROW( Invalid_File_Format ); 1285 goto Exit; 1286 } 1287 } 1288 1289 Exit: 1290 1291 /* Clean up if there was an error. */ 1292 return error; 1293 } 1294 1295 1296 static FT_Error 1297 cff_subfont_load( CFF_SubFont font, 1298 CFF_Index idx, 1299 FT_UInt font_index, 1300 FT_Stream stream, 1301 FT_ULong base_offset, 1302 FT_Library library ) 1303 { 1304 FT_Error error; 1305 CFF_ParserRec parser; 1306 FT_Byte* dict = NULL; 1307 FT_ULong dict_len; 1308 CFF_FontRecDict top = &font->font_dict; 1309 CFF_Private priv = &font->private_dict; 1310 1311 1312 cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); 1313 1314 /* set defaults */ 1315 FT_MEM_ZERO( top, sizeof ( *top ) ); 1316 1317 top->underline_position = -( 100L << 16 ); 1318 top->underline_thickness = 50L << 16; 1319 top->charstring_type = 2; 1320 top->font_matrix.xx = 0x10000L; 1321 top->font_matrix.yy = 0x10000L; 1322 top->cid_count = 8720; 1323 1324 /* we use the implementation specific SID value 0xFFFF to indicate */ 1325 /* missing entries */ 1326 top->version = 0xFFFFU; 1327 top->notice = 0xFFFFU; 1328 top->copyright = 0xFFFFU; 1329 top->full_name = 0xFFFFU; 1330 top->family_name = 0xFFFFU; 1331 top->weight = 0xFFFFU; 1332 top->embedded_postscript = 0xFFFFU; 1333 1334 top->cid_registry = 0xFFFFU; 1335 top->cid_ordering = 0xFFFFU; 1336 top->cid_font_name = 0xFFFFU; 1337 1338 error = cff_index_access_element( idx, font_index, &dict, &dict_len ); 1339 if ( !error ) 1340 { 1341 FT_TRACE4(( " top dictionary:\n" )); 1342 error = cff_parser_run( &parser, dict, dict + dict_len ); 1343 } 1344 1345 cff_index_forget_element( idx, &dict ); 1346 1347 if ( error ) 1348 goto Exit; 1349 1350 /* if it is a CID font, we stop there */ 1351 if ( top->cid_registry != 0xFFFFU ) 1352 goto Exit; 1353 1354 /* parse the private dictionary, if any */ 1355 if ( top->private_offset && top->private_size ) 1356 { 1357 /* set defaults */ 1358 FT_MEM_ZERO( priv, sizeof ( *priv ) ); 1359 1360 priv->blue_shift = 7; 1361 priv->blue_fuzz = 1; 1362 priv->lenIV = -1; 1363 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); 1364 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); 1365 1366 cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); 1367 1368 if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || 1369 FT_FRAME_ENTER( font->font_dict.private_size ) ) 1370 goto Exit; 1371 1372 FT_TRACE4(( " private dictionary:\n" )); 1373 error = cff_parser_run( &parser, 1374 (FT_Byte*)stream->cursor, 1375 (FT_Byte*)stream->limit ); 1376 FT_FRAME_EXIT(); 1377 if ( error ) 1378 goto Exit; 1379 1380 /* ensure that `num_blue_values' is even */ 1381 priv->num_blue_values &= ~1; 1382 } 1383 1384 /* read the local subrs, if any */ 1385 if ( priv->local_subrs_offset ) 1386 { 1387 if ( FT_STREAM_SEEK( base_offset + top->private_offset + 1388 priv->local_subrs_offset ) ) 1389 goto Exit; 1390 1391 error = cff_index_init( &font->local_subrs_index, stream, 1 ); 1392 if ( error ) 1393 goto Exit; 1394 1395 error = cff_index_get_pointers( &font->local_subrs_index, 1396 &font->local_subrs, NULL ); 1397 if ( error ) 1398 goto Exit; 1399 } 1400 1401 Exit: 1402 return error; 1403 } 1404 1405 1406 static void 1407 cff_subfont_done( FT_Memory memory, 1408 CFF_SubFont subfont ) 1409 { 1410 if ( subfont ) 1411 { 1412 cff_index_done( &subfont->local_subrs_index ); 1413 FT_FREE( subfont->local_subrs ); 1414 } 1415 } 1416 1417 1418 FT_LOCAL_DEF( FT_Error ) 1419 cff_font_load( FT_Library library, 1420 FT_Stream stream, 1421 FT_Int face_index, 1422 CFF_Font font, 1423 FT_Bool pure_cff ) 1424 { 1425 static const FT_Frame_Field cff_header_fields[] = 1426 { 1427#undef FT_STRUCTURE 1428#define FT_STRUCTURE CFF_FontRec 1429 1430 FT_FRAME_START( 4 ), 1431 FT_FRAME_BYTE( version_major ), 1432 FT_FRAME_BYTE( version_minor ), 1433 FT_FRAME_BYTE( header_size ), 1434 FT_FRAME_BYTE( absolute_offsize ), 1435 FT_FRAME_END 1436 }; 1437 1438 FT_Error error; 1439 FT_Memory memory = stream->memory; 1440 FT_ULong base_offset; 1441 CFF_FontRecDict dict; 1442 CFF_IndexRec string_index; 1443 FT_Int subfont_index; 1444 1445 1446 FT_ZERO( font ); 1447 FT_ZERO( &string_index ); 1448 1449 font->stream = stream; 1450 font->memory = memory; 1451 dict = &font->top_font.font_dict; 1452 base_offset = FT_STREAM_POS(); 1453 1454 /* read CFF font header */ 1455 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) 1456 goto Exit; 1457 1458 /* check format */ 1459 if ( font->version_major != 1 || 1460 font->header_size < 4 || 1461 font->absolute_offsize > 4 ) 1462 { 1463 FT_TRACE2(( " not a CFF font header\n" )); 1464 error = FT_THROW( Unknown_File_Format ); 1465 goto Exit; 1466 } 1467 1468 /* skip the rest of the header */ 1469 if ( FT_STREAM_SKIP( font->header_size - 4 ) ) 1470 goto Exit; 1471 1472 /* read the name, top dict, string and global subrs index */ 1473 if ( FT_SET_ERROR( cff_index_init( &font->name_index, 1474 stream, 0 ) ) || 1475 FT_SET_ERROR( cff_index_init( &font->font_dict_index, 1476 stream, 0 ) ) || 1477 FT_SET_ERROR( cff_index_init( &string_index, 1478 stream, 1 ) ) || 1479 FT_SET_ERROR( cff_index_init( &font->global_subrs_index, 1480 stream, 1 ) ) || 1481 FT_SET_ERROR( cff_index_get_pointers( &string_index, 1482 &font->strings, 1483 &font->string_pool ) ) ) 1484 goto Exit; 1485 1486 font->num_strings = string_index.count; 1487 1488 if ( pure_cff ) 1489 { 1490 /* well, we don't really forget the `disabled' fonts... */ 1491 subfont_index = face_index; 1492 1493 if ( subfont_index >= (FT_Int)font->name_index.count ) 1494 { 1495 FT_ERROR(( "cff_font_load:" 1496 " invalid subfont index for pure CFF font (%d)\n", 1497 subfont_index )); 1498 error = FT_THROW( Invalid_Argument ); 1499 goto Exit; 1500 } 1501 1502 font->num_faces = font->name_index.count; 1503 } 1504 else 1505 { 1506 subfont_index = 0; 1507 1508 if ( font->name_index.count > 1 ) 1509 { 1510 FT_ERROR(( "cff_font_load:" 1511 " invalid CFF font with multiple subfonts\n" 1512 " " 1513 " in SFNT wrapper\n" )); 1514 error = FT_THROW( Invalid_File_Format ); 1515 goto Exit; 1516 } 1517 } 1518 1519 /* in case of a font format check, simply exit now */ 1520 if ( face_index < 0 ) 1521 goto Exit; 1522 1523 /* now, parse the top-level font dictionary */ 1524 FT_TRACE4(( "parsing top-level\n" )); 1525 error = cff_subfont_load( &font->top_font, 1526 &font->font_dict_index, 1527 subfont_index, 1528 stream, 1529 base_offset, 1530 library ); 1531 if ( error ) 1532 goto Exit; 1533 1534 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) 1535 goto Exit; 1536 1537 error = cff_index_init( &font->charstrings_index, stream, 0 ); 1538 if ( error ) 1539 goto Exit; 1540 1541 /* now, check for a CID font */ 1542 if ( dict->cid_registry != 0xFFFFU ) 1543 { 1544 CFF_IndexRec fd_index; 1545 CFF_SubFont sub = NULL; 1546 FT_UInt idx; 1547 1548 1549 /* this is a CID-keyed font, we must now allocate a table of */ 1550 /* sub-fonts, then load each of them separately */ 1551 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) 1552 goto Exit; 1553 1554 error = cff_index_init( &fd_index, stream, 0 ); 1555 if ( error ) 1556 goto Exit; 1557 1558 if ( fd_index.count > CFF_MAX_CID_FONTS ) 1559 { 1560 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); 1561 goto Fail_CID; 1562 } 1563 1564 /* allocate & read each font dict independently */ 1565 font->num_subfonts = fd_index.count; 1566 if ( FT_NEW_ARRAY( sub, fd_index.count ) ) 1567 goto Fail_CID; 1568 1569 /* set up pointer table */ 1570 for ( idx = 0; idx < fd_index.count; idx++ ) 1571 font->subfonts[idx] = sub + idx; 1572 1573 /* now load each subfont independently */ 1574 for ( idx = 0; idx < fd_index.count; idx++ ) 1575 { 1576 sub = font->subfonts[idx]; 1577 FT_TRACE4(( "parsing subfont %u\n", idx )); 1578 error = cff_subfont_load( sub, &fd_index, idx, 1579 stream, base_offset, library ); 1580 if ( error ) 1581 goto Fail_CID; 1582 } 1583 1584 /* now load the FD Select array */ 1585 error = CFF_Load_FD_Select( &font->fd_select, 1586 font->charstrings_index.count, 1587 stream, 1588 base_offset + dict->cid_fd_select_offset ); 1589 1590 Fail_CID: 1591 cff_index_done( &fd_index ); 1592 1593 if ( error ) 1594 goto Exit; 1595 } 1596 else 1597 font->num_subfonts = 0; 1598 1599 /* read the charstrings index now */ 1600 if ( dict->charstrings_offset == 0 ) 1601 { 1602 FT_ERROR(( "cff_font_load: no charstrings offset\n" )); 1603 error = FT_THROW( Invalid_File_Format ); 1604 goto Exit; 1605 } 1606 1607 font->num_glyphs = font->charstrings_index.count; 1608 1609 error = cff_index_get_pointers( &font->global_subrs_index, 1610 &font->global_subrs, NULL ); 1611 1612 if ( error ) 1613 goto Exit; 1614 1615 /* read the Charset and Encoding tables if available */ 1616 if ( font->num_glyphs > 0 ) 1617 { 1618 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); 1619 1620 1621 error = cff_charset_load( &font->charset, font->num_glyphs, stream, 1622 base_offset, dict->charset_offset, invert ); 1623 if ( error ) 1624 goto Exit; 1625 1626 /* CID-keyed CFFs don't have an encoding */ 1627 if ( dict->cid_registry == 0xFFFFU ) 1628 { 1629 error = cff_encoding_load( &font->encoding, 1630 &font->charset, 1631 font->num_glyphs, 1632 stream, 1633 base_offset, 1634 dict->encoding_offset ); 1635 if ( error ) 1636 goto Exit; 1637 } 1638 } 1639 1640 /* get the font name (/CIDFontName for CID-keyed fonts, */ 1641 /* /FontName otherwise) */ 1642 font->font_name = cff_index_get_name( font, subfont_index ); 1643 1644 Exit: 1645 cff_index_done( &string_index ); 1646 1647 return error; 1648 } 1649 1650 1651 FT_LOCAL_DEF( void ) 1652 cff_font_done( CFF_Font font ) 1653 { 1654 FT_Memory memory = font->memory; 1655 FT_UInt idx; 1656 1657 1658 cff_index_done( &font->global_subrs_index ); 1659 cff_index_done( &font->font_dict_index ); 1660 cff_index_done( &font->name_index ); 1661 cff_index_done( &font->charstrings_index ); 1662 1663 /* release font dictionaries, but only if working with */ 1664 /* a CID keyed CFF font */ 1665 if ( font->num_subfonts > 0 ) 1666 { 1667 for ( idx = 0; idx < font->num_subfonts; idx++ ) 1668 cff_subfont_done( memory, font->subfonts[idx] ); 1669 1670 /* the subfonts array has been allocated as a single block */ 1671 FT_FREE( font->subfonts[0] ); 1672 } 1673 1674 cff_encoding_done( &font->encoding ); 1675 cff_charset_done( &font->charset, font->stream ); 1676 1677 cff_subfont_done( memory, &font->top_font ); 1678 1679 CFF_Done_FD_Select( &font->fd_select, font->stream ); 1680 1681 FT_FREE( font->font_info ); 1682 1683 FT_FREE( font->font_name ); 1684 FT_FREE( font->global_subrs ); 1685 FT_FREE( font->strings ); 1686 FT_FREE( font->string_pool ); 1687 1688 if ( font->cf2_instance.finalizer ) 1689 { 1690 font->cf2_instance.finalizer( font->cf2_instance.data ); 1691 FT_FREE( font->cf2_instance.data ); 1692 } 1693 } 1694 1695 1696/* END */ 1697