From bc5e6d289ed40efec2b0e03427e8fc2947bf53e3 Mon Sep 17 00:00:00 2001 From: dsinclair Date: Tue, 4 Oct 2016 11:08:49 -0700 Subject: Move core/fpdfapi/fpdf_font to core/fpdfapi/font BUG=pdfium:603 Review-Url: https://codereview.chromium.org/2392773003 --- BUILD.gn | 46 +- core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp | 2 +- core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp | 2 +- core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp | 2 +- core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp | 2 +- core/fpdfapi/cmaps/fpdf_cmaps.cpp | 2 +- core/fpdfapi/font/cpdf_cidfont.cpp | 852 ++++++++++ core/fpdfapi/font/cpdf_cidfont.h | 91 ++ core/fpdfapi/font/cpdf_font.cpp | 476 ++++++ core/fpdfapi/font/cpdf_font.h | 132 ++ core/fpdfapi/font/cpdf_fontencoding.cpp | 1818 +++++++++++++++++++++ core/fpdfapi/font/cpdf_fontencoding.h | 61 + core/fpdfapi/font/cpdf_simplefont.cpp | 216 +++ core/fpdfapi/font/cpdf_simplefont.h | 49 + core/fpdfapi/font/cpdf_truetypefont.cpp | 223 +++ core/fpdfapi/font/cpdf_truetypefont.h | 30 + core/fpdfapi/font/cpdf_type1font.cpp | 398 +++++ core/fpdfapi/font/cpdf_type1font.h | 35 + core/fpdfapi/font/cpdf_type3char.cpp | 38 + core/fpdfapi/font/cpdf_type3char.h | 35 + core/fpdfapi/font/cpdf_type3font.cpp | 159 ++ core/fpdfapi/font/cpdf_type3font.h | 59 + core/fpdfapi/font/font_int.h | 204 +++ core/fpdfapi/font/fpdf_font.cpp | 317 ++++ core/fpdfapi/font/fpdf_font_cid.cpp | 783 +++++++++ core/fpdfapi/font/fpdf_font_cid_unittest.cpp | 70 + core/fpdfapi/font/fpdf_font_unittest.cpp | 30 + core/fpdfapi/font/ttgsubtable.cpp | 502 ++++++ core/fpdfapi/font/ttgsubtable.h | 301 ++++ core/fpdfapi/fpdf_font/cpdf_cidfont.cpp | 852 ---------- core/fpdfapi/fpdf_font/cpdf_cidfont.h | 91 -- core/fpdfapi/fpdf_font/cpdf_font.cpp | 476 ------ core/fpdfapi/fpdf_font/cpdf_font.h | 132 -- core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp | 1818 --------------------- core/fpdfapi/fpdf_font/cpdf_fontencoding.h | 61 - core/fpdfapi/fpdf_font/cpdf_simplefont.cpp | 216 --- core/fpdfapi/fpdf_font/cpdf_simplefont.h | 49 - core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp | 223 --- core/fpdfapi/fpdf_font/cpdf_truetypefont.h | 30 - core/fpdfapi/fpdf_font/cpdf_type1font.cpp | 398 ----- core/fpdfapi/fpdf_font/cpdf_type1font.h | 35 - core/fpdfapi/fpdf_font/cpdf_type3char.cpp | 39 - core/fpdfapi/fpdf_font/cpdf_type3char.h | 35 - core/fpdfapi/fpdf_font/cpdf_type3font.cpp | 159 -- core/fpdfapi/fpdf_font/cpdf_type3font.h | 59 - core/fpdfapi/fpdf_font/font_int.h | 204 --- core/fpdfapi/fpdf_font/fpdf_font.cpp | 317 ---- core/fpdfapi/fpdf_font/fpdf_font_cid.cpp | 784 --------- core/fpdfapi/fpdf_font/fpdf_font_cid_unittest.cpp | 70 - core/fpdfapi/fpdf_font/fpdf_font_unittest.cpp | 30 - core/fpdfapi/fpdf_font/ttgsubtable.cpp | 502 ------ core/fpdfapi/fpdf_font/ttgsubtable.h | 301 ---- core/fpdfapi/fpdf_page/cpdf_pagemodule.h | 2 +- core/fpdfapi/fpdf_page/cpdf_textobject.cpp | 4 +- core/fpdfapi/fpdf_page/cpdf_textstate.cpp | 2 +- core/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 4 +- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 4 +- core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp | 2 +- core/fpdfapi/fpdf_parser/cpdf_document.cpp | 2 +- core/fpdfapi/fpdf_render/cpdf_type3cache.cpp | 4 +- core/fpdfapi/fpdf_render/cpdf_type3cache.h | 2 +- core/fpdfapi/fpdf_render/fpdf_render.cpp | 4 +- core/fpdfapi/fpdf_render/fpdf_render_text.cpp | 8 +- core/fpdfdoc/cpdf_interform.cpp | 4 +- core/fpdfdoc/cpdf_variabletext.cpp | 2 +- core/fpdfdoc/cpvt_fontmap.cpp | 2 +- core/fpdfdoc/cpvt_generateap.cpp | 2 +- core/fpdftext/cpdf_textpage.cpp | 2 +- core/fxge/ge/cfx_font.cpp | 2 +- core/fxge/ge/cfx_unicodeencodingex.cpp | 2 +- fpdfsdk/formfiller/DEPS | 2 +- fpdfsdk/formfiller/cba_fontmap.cpp | 2 +- fpdfsdk/fxedit/DEPS | 2 +- fpdfsdk/fxedit/fxet_ap.cpp | 2 +- fpdfsdk/fxedit/fxet_edit.cpp | 2 +- fpdfsdk/javascript/DEPS | 2 +- fpdfsdk/javascript/Document.cpp | 2 +- fpdfsdk/javascript/Field.cpp | 2 +- fpdfsdk/pdfwindow/DEPS | 2 +- fpdfsdk/pdfwindow/PWL_Edit.cpp | 2 +- fpdfsdk/pdfwindow/PWL_FontMap.cpp | 4 +- xfa/fxfa/app/DEPS | 2 +- xfa/fxfa/app/xfa_fontmgr.cpp | 2 +- 83 files changed, 6948 insertions(+), 6950 deletions(-) create mode 100644 core/fpdfapi/font/cpdf_cidfont.cpp create mode 100644 core/fpdfapi/font/cpdf_cidfont.h create mode 100644 core/fpdfapi/font/cpdf_font.cpp create mode 100644 core/fpdfapi/font/cpdf_font.h create mode 100644 core/fpdfapi/font/cpdf_fontencoding.cpp create mode 100644 core/fpdfapi/font/cpdf_fontencoding.h create mode 100644 core/fpdfapi/font/cpdf_simplefont.cpp create mode 100644 core/fpdfapi/font/cpdf_simplefont.h create mode 100644 core/fpdfapi/font/cpdf_truetypefont.cpp create mode 100644 core/fpdfapi/font/cpdf_truetypefont.h create mode 100644 core/fpdfapi/font/cpdf_type1font.cpp create mode 100644 core/fpdfapi/font/cpdf_type1font.h create mode 100644 core/fpdfapi/font/cpdf_type3char.cpp create mode 100644 core/fpdfapi/font/cpdf_type3char.h create mode 100644 core/fpdfapi/font/cpdf_type3font.cpp create mode 100644 core/fpdfapi/font/cpdf_type3font.h create mode 100644 core/fpdfapi/font/font_int.h create mode 100644 core/fpdfapi/font/fpdf_font.cpp create mode 100644 core/fpdfapi/font/fpdf_font_cid.cpp create mode 100644 core/fpdfapi/font/fpdf_font_cid_unittest.cpp create mode 100644 core/fpdfapi/font/fpdf_font_unittest.cpp create mode 100644 core/fpdfapi/font/ttgsubtable.cpp create mode 100644 core/fpdfapi/font/ttgsubtable.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_cidfont.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_cidfont.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_font.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_font.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_fontencoding.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_simplefont.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_simplefont.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_truetypefont.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_type1font.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_type1font.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_type3char.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_type3char.h delete mode 100644 core/fpdfapi/fpdf_font/cpdf_type3font.cpp delete mode 100644 core/fpdfapi/fpdf_font/cpdf_type3font.h delete mode 100644 core/fpdfapi/fpdf_font/font_int.h delete mode 100644 core/fpdfapi/fpdf_font/fpdf_font.cpp delete mode 100644 core/fpdfapi/fpdf_font/fpdf_font_cid.cpp delete mode 100644 core/fpdfapi/fpdf_font/fpdf_font_cid_unittest.cpp delete mode 100644 core/fpdfapi/fpdf_font/fpdf_font_unittest.cpp delete mode 100644 core/fpdfapi/fpdf_font/ttgsubtable.cpp delete mode 100644 core/fpdfapi/fpdf_font/ttgsubtable.h diff --git a/BUILD.gn b/BUILD.gn index 338ca5333b..d440c2648c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -399,27 +399,27 @@ static_library("fpdfapi") { "core/fpdfapi/edit/cpdf_pagecontentgenerator.h", "core/fpdfapi/edit/editint.h", "core/fpdfapi/edit/fpdf_edit_create.cpp", - "core/fpdfapi/fpdf_font/cpdf_cidfont.cpp", - "core/fpdfapi/fpdf_font/cpdf_cidfont.h", - "core/fpdfapi/fpdf_font/cpdf_font.cpp", - "core/fpdfapi/fpdf_font/cpdf_font.h", - "core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp", - "core/fpdfapi/fpdf_font/cpdf_fontencoding.h", - "core/fpdfapi/fpdf_font/cpdf_simplefont.cpp", - "core/fpdfapi/fpdf_font/cpdf_simplefont.h", - "core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp", - "core/fpdfapi/fpdf_font/cpdf_truetypefont.h", - "core/fpdfapi/fpdf_font/cpdf_type1font.cpp", - "core/fpdfapi/fpdf_font/cpdf_type1font.h", - "core/fpdfapi/fpdf_font/cpdf_type3char.cpp", - "core/fpdfapi/fpdf_font/cpdf_type3char.h", - "core/fpdfapi/fpdf_font/cpdf_type3font.cpp", - "core/fpdfapi/fpdf_font/cpdf_type3font.h", - "core/fpdfapi/fpdf_font/font_int.h", - "core/fpdfapi/fpdf_font/fpdf_font.cpp", - "core/fpdfapi/fpdf_font/fpdf_font_cid.cpp", - "core/fpdfapi/fpdf_font/ttgsubtable.cpp", - "core/fpdfapi/fpdf_font/ttgsubtable.h", + "core/fpdfapi/font/cpdf_cidfont.cpp", + "core/fpdfapi/font/cpdf_cidfont.h", + "core/fpdfapi/font/cpdf_font.cpp", + "core/fpdfapi/font/cpdf_font.h", + "core/fpdfapi/font/cpdf_fontencoding.cpp", + "core/fpdfapi/font/cpdf_fontencoding.h", + "core/fpdfapi/font/cpdf_simplefont.cpp", + "core/fpdfapi/font/cpdf_simplefont.h", + "core/fpdfapi/font/cpdf_truetypefont.cpp", + "core/fpdfapi/font/cpdf_truetypefont.h", + "core/fpdfapi/font/cpdf_type1font.cpp", + "core/fpdfapi/font/cpdf_type1font.h", + "core/fpdfapi/font/cpdf_type3char.cpp", + "core/fpdfapi/font/cpdf_type3char.h", + "core/fpdfapi/font/cpdf_type3font.cpp", + "core/fpdfapi/font/cpdf_type3font.h", + "core/fpdfapi/font/font_int.h", + "core/fpdfapi/font/fpdf_font.cpp", + "core/fpdfapi/font/fpdf_font_cid.cpp", + "core/fpdfapi/font/ttgsubtable.cpp", + "core/fpdfapi/font/ttgsubtable.h", "core/fpdfapi/fpdf_page/cpdf_allstates.cpp", "core/fpdfapi/fpdf_page/cpdf_allstates.h", "core/fpdfapi/fpdf_page/cpdf_clippath.cpp", @@ -1636,8 +1636,8 @@ if (pdf_enable_xfa) { test("pdfium_unittests") { sources = [ - "core/fpdfapi/fpdf_font/fpdf_font_cid_unittest.cpp", - "core/fpdfapi/fpdf_font/fpdf_font_unittest.cpp", + "core/fpdfapi/font/fpdf_font_cid_unittest.cpp", + "core/fpdfapi/font/fpdf_font_unittest.cpp", "core/fpdfapi/fpdf_page/fpdf_page_parser_old_unittest.cpp", "core/fpdfapi/fpdf_page/fpdf_page_parser_unittest.cpp", "core/fpdfapi/fpdf_parser/cpdf_array_unittest.cpp", diff --git a/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp b/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp index 6351d2c9bb..8d7fa4b322 100644 --- a/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp +++ b/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp @@ -8,7 +8,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" diff --git a/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp b/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp index 9647eeeb1d..8c60b3be9f 100644 --- a/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp +++ b/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp @@ -8,7 +8,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" diff --git a/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp b/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp index f726d50376..5336060dc4 100644 --- a/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp +++ b/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp @@ -8,7 +8,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" diff --git a/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp b/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp index e8a0071ddb..cc417bf00c 100644 --- a/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp +++ b/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp @@ -8,7 +8,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" diff --git a/core/fpdfapi/cmaps/fpdf_cmaps.cpp b/core/fpdfapi/cmaps/fpdf_cmaps.cpp index c85a7d9010..58a1c082bb 100644 --- a/core/fpdfapi/cmaps/fpdf_cmaps.cpp +++ b/core/fpdfapi/cmaps/fpdf_cmaps.cpp @@ -7,7 +7,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" extern "C" { diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp new file mode 100644 index 0000000000..e5bbd80a83 --- /dev/null +++ b/core/fpdfapi/font/cpdf_cidfont.cpp @@ -0,0 +1,852 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_cidfont.h" + +#include +#include + +#include "core/fpdfapi/cmaps/cmap_int.h" +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/cpdf_fontencoding.h" +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/font/ttgsubtable.h" +#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "third_party/base/numerics/safe_math.h" + +namespace { + +const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200}; + +const struct CIDTransform { + uint16_t cid; + uint8_t a; + uint8_t b; + uint8_t c; + uint8_t d; + uint8_t e; + uint8_t f; +} g_Japan1_VertCIDs[] = { + {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, + {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, + {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, + {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, + {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, + {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, + {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, + {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, + {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127}, + {7904, 0, 129, 127, 0, 17, 127}, {7905, 0, 129, 127, 0, 17, 114}, + {7906, 0, 129, 127, 0, 17, 127}, {7907, 0, 129, 127, 0, 17, 127}, + {7908, 0, 129, 127, 0, 17, 127}, {7909, 0, 129, 127, 0, 17, 127}, + {7910, 0, 129, 127, 0, 17, 127}, {7911, 0, 129, 127, 0, 17, 127}, + {7912, 0, 129, 127, 0, 17, 127}, {7913, 0, 129, 127, 0, 17, 127}, + {7914, 0, 129, 127, 0, 17, 127}, {7915, 0, 129, 127, 0, 17, 114}, + {7916, 0, 129, 127, 0, 17, 127}, {7917, 0, 129, 127, 0, 17, 127}, + {7918, 127, 0, 0, 127, 18, 25}, {7919, 127, 0, 0, 127, 18, 25}, + {7920, 127, 0, 0, 127, 18, 25}, {7921, 127, 0, 0, 127, 18, 25}, + {7922, 127, 0, 0, 127, 18, 25}, {7923, 127, 0, 0, 127, 18, 25}, + {7924, 127, 0, 0, 127, 18, 25}, {7925, 127, 0, 0, 127, 18, 25}, + {7926, 127, 0, 0, 127, 18, 25}, {7927, 127, 0, 0, 127, 18, 25}, + {7928, 127, 0, 0, 127, 18, 25}, {7929, 127, 0, 0, 127, 18, 25}, + {7930, 127, 0, 0, 127, 18, 25}, {7931, 127, 0, 0, 127, 18, 25}, + {7932, 127, 0, 0, 127, 18, 25}, {7933, 127, 0, 0, 127, 18, 25}, + {7934, 127, 0, 0, 127, 18, 25}, {7935, 127, 0, 0, 127, 18, 25}, + {7936, 127, 0, 0, 127, 18, 25}, {7937, 127, 0, 0, 127, 18, 25}, + {7938, 127, 0, 0, 127, 18, 25}, {7939, 127, 0, 0, 127, 18, 25}, + {8720, 0, 129, 127, 0, 19, 102}, {8721, 0, 129, 127, 0, 13, 127}, + {8722, 0, 129, 127, 0, 19, 108}, {8723, 0, 129, 127, 0, 19, 102}, + {8724, 0, 129, 127, 0, 19, 102}, {8725, 0, 129, 127, 0, 19, 102}, + {8726, 0, 129, 127, 0, 19, 102}, {8727, 0, 129, 127, 0, 19, 102}, + {8728, 0, 129, 127, 0, 19, 114}, {8729, 0, 129, 127, 0, 19, 114}, + {8730, 0, 129, 127, 0, 38, 108}, {8731, 0, 129, 127, 0, 13, 108}, + {8732, 0, 129, 127, 0, 19, 108}, {8733, 0, 129, 127, 0, 19, 108}, + {8734, 0, 129, 127, 0, 19, 108}, {8735, 0, 129, 127, 0, 19, 108}, + {8736, 0, 129, 127, 0, 19, 102}, {8737, 0, 129, 127, 0, 19, 102}, + {8738, 0, 129, 127, 0, 19, 102}, {8739, 0, 129, 127, 0, 19, 102}, + {8740, 0, 129, 127, 0, 19, 102}, {8741, 0, 129, 127, 0, 19, 102}, + {8742, 0, 129, 127, 0, 19, 102}, {8743, 0, 129, 127, 0, 19, 102}, + {8744, 0, 129, 127, 0, 19, 102}, {8745, 0, 129, 127, 0, 19, 102}, + {8746, 0, 129, 127, 0, 19, 114}, {8747, 0, 129, 127, 0, 19, 114}, + {8748, 0, 129, 127, 0, 19, 102}, {8749, 0, 129, 127, 0, 19, 102}, + {8750, 0, 129, 127, 0, 19, 102}, {8751, 0, 129, 127, 0, 19, 102}, + {8752, 0, 129, 127, 0, 19, 102}, {8753, 0, 129, 127, 0, 19, 102}, + {8754, 0, 129, 127, 0, 19, 102}, {8755, 0, 129, 127, 0, 19, 102}, + {8756, 0, 129, 127, 0, 19, 102}, {8757, 0, 129, 127, 0, 19, 102}, + {8758, 0, 129, 127, 0, 19, 102}, {8759, 0, 129, 127, 0, 19, 102}, + {8760, 0, 129, 127, 0, 19, 102}, {8761, 0, 129, 127, 0, 19, 102}, + {8762, 0, 129, 127, 0, 19, 102}, {8763, 0, 129, 127, 0, 19, 102}, + {8764, 0, 129, 127, 0, 19, 102}, {8765, 0, 129, 127, 0, 19, 102}, + {8766, 0, 129, 127, 0, 19, 102}, {8767, 0, 129, 127, 0, 19, 102}, + {8768, 0, 129, 127, 0, 19, 102}, {8769, 0, 129, 127, 0, 19, 102}, + {8770, 0, 129, 127, 0, 19, 102}, {8771, 0, 129, 127, 0, 19, 102}, + {8772, 0, 129, 127, 0, 19, 102}, {8773, 0, 129, 127, 0, 19, 102}, + {8774, 0, 129, 127, 0, 19, 102}, {8775, 0, 129, 127, 0, 19, 102}, + {8776, 0, 129, 127, 0, 19, 102}, {8777, 0, 129, 127, 0, 19, 102}, + {8778, 0, 129, 127, 0, 19, 102}, {8779, 0, 129, 127, 0, 19, 114}, + {8780, 0, 129, 127, 0, 19, 108}, {8781, 0, 129, 127, 0, 19, 114}, + {8782, 0, 129, 127, 0, 13, 114}, {8783, 0, 129, 127, 0, 19, 108}, + {8784, 0, 129, 127, 0, 13, 114}, {8785, 0, 129, 127, 0, 19, 108}, + {8786, 0, 129, 127, 0, 19, 108}, {8787, 0, 129, 127, 0, 19, 108}, + {8788, 0, 129, 127, 0, 19, 108}, {8789, 0, 129, 127, 0, 19, 108}, + {8790, 0, 129, 127, 0, 19, 108}, {8791, 0, 129, 127, 0, 19, 108}, + {8792, 0, 129, 127, 0, 19, 108}, {8793, 0, 129, 127, 0, 19, 108}, + {8794, 0, 129, 127, 0, 19, 108}, {8795, 0, 129, 127, 0, 19, 108}, + {8796, 0, 129, 127, 0, 19, 108}, {8797, 0, 129, 127, 0, 19, 108}, + {8798, 0, 129, 127, 0, 19, 108}, {8799, 0, 129, 127, 0, 19, 108}, + {8800, 0, 129, 127, 0, 19, 108}, {8801, 0, 129, 127, 0, 19, 108}, + {8802, 0, 129, 127, 0, 19, 108}, {8803, 0, 129, 127, 0, 19, 108}, + {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108}, + {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, + {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, + {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, + {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, + {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, + {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, + {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, +}; + +CPDF_FontGlobals* GetFontGlobals() { + return CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); +} + +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) { + switch (charset) { + case CIDSET_GB1: + case CIDSET_CNS1: + case CIDSET_JAPAN1: + case CIDSET_KOREA1: + return true; + + default: + return false; + } +} + +FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, + CIDSet charset, + uint32_t charcode) { + if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) + return 0; + + uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); + const auto& codes = GetFontGlobals()->m_EmbeddedToUnicodes[charset]; + if (codes.m_pMap && cid && cid < codes.m_Count) + return codes.m_pMap[cid]; + return 0; +} + +uint32_t EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, + CIDSet charset, + FX_WCHAR unicode) { + if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) + return 0; + + const auto& codes = GetFontGlobals()->m_EmbeddedToUnicodes[charset]; + const uint16_t* pCodes = codes.m_pMap; + if (!pCodes) + return 0; + + for (uint32_t i = 0; i < codes.m_Count; ++i) { + if (pCodes[i] == unicode) { + uint32_t CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); + if (CharCode) + return CharCode; + } + } + return 0; +} + +#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +void FT_UseCIDCharmap(FXFT_Face face, int coding) { + int encoding; + switch (coding) { + case CIDCODING_GB: + encoding = FXFT_ENCODING_GB2312; + break; + case CIDCODING_BIG5: + encoding = FXFT_ENCODING_BIG5; + break; + case CIDCODING_JIS: + encoding = FXFT_ENCODING_SJIS; + break; + case CIDCODING_KOREA: + encoding = FXFT_ENCODING_JOHAB; + break; + default: + encoding = FXFT_ENCODING_UNICODE; + } + int err = FXFT_Select_Charmap(face, encoding); + if (err) + err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); + if (err && FXFT_Get_Face_Charmaps(face)) + FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); +} + +bool IsMetricForCID(const uint32_t* pEntry, uint16_t CID) { + return pEntry[0] <= CID && pEntry[1] >= CID; +} + +} // namespace + +CPDF_CIDFont::CPDF_CIDFont() + : m_pCMap(nullptr), + m_pCID2UnicodeMap(nullptr), + m_bCIDIsGID(false), + m_bAnsiWidthsFixed(false), + m_bAdobeCourierStd(false) { + for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i) + m_CharBBox[i] = FX_RECT(-1, -1, -1, -1); +} + +CPDF_CIDFont::~CPDF_CIDFont() {} + +bool CPDF_CIDFont::IsCIDFont() const { + return true; +} + +const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const { + return this; +} + +CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() { + return this; +} + +uint16_t CPDF_CIDFont::CIDFromCharCode(uint32_t charcode) const { + return m_pCMap ? m_pCMap->CIDFromCharCode(charcode) + : static_cast(charcode); +} + +bool CPDF_CIDFont::IsVertWriting() const { + return m_pCMap && m_pCMap->IsVertWriting(); +} + +CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(uint32_t charcode) const { + CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode); + if (!str.IsEmpty()) + return str; + FX_WCHAR ret = GetUnicodeFromCharCode(charcode); + return ret ? ret : CFX_WideString(); +} + +FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(uint32_t charcode) const { + switch (m_pCMap->m_Coding) { + case CIDCODING_UCS2: + case CIDCODING_UTF16: + return static_cast(charcode); + case CIDCODING_CID: + if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) + return 0; + return m_pCID2UnicodeMap->UnicodeFromCID(static_cast(charcode)); + } + if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded()) + return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode)); + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + FX_WCHAR unicode; + int charsize = 1; + if (charcode > 255) { + charcode = (charcode % 256) * 256 + (charcode / 256); + charsize = 2; + } + int ret = FXSYS_MultiByteToWideChar( + g_CharsetCPs[m_pCMap->m_Coding], 0, + reinterpret_cast(&charcode), charsize, &unicode, 1); + return ret == 1 ? unicode : 0; +#else + if (!m_pCMap->m_pEmbedMap) + return 0; + return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, + charcode); +#endif +} + +uint32_t CPDF_CIDFont::CharCodeFromUnicode(FX_WCHAR unicode) const { + uint32_t charcode = CPDF_Font::CharCodeFromUnicode(unicode); + if (charcode) + return charcode; + switch (m_pCMap->m_Coding) { + case CIDCODING_UNKNOWN: + return 0; + case CIDCODING_UCS2: + case CIDCODING_UTF16: + return unicode; + case CIDCODING_CID: { + if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) + return 0; + uint32_t CID = 0; + while (CID < 65536) { + FX_WCHAR this_unicode = + m_pCID2UnicodeMap->UnicodeFromCID(static_cast(CID)); + if (this_unicode == unicode) + return CID; + CID++; + } + break; + } + } + + if (unicode < 0x80) + return static_cast(unicode); + if (m_pCMap->m_Coding == CIDCODING_CID) + return 0; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + uint8_t buffer[32]; + int ret = FXSYS_WideCharToMultiByte( + g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1, + reinterpret_cast(buffer), 4, nullptr, nullptr); + if (ret == 1) + return buffer[0]; + if (ret == 2) + return buffer[0] * 256 + buffer[1]; +#else + if (m_pCMap->m_pEmbedMap) { + return EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, + unicode); + } +#endif + return 0; +} + +bool CPDF_CIDFont::Load() { + if (m_pFontDict->GetStringFor("Subtype") == "TrueType") { + LoadGB2312(); + return true; + } + + CPDF_Array* pFonts = m_pFontDict->GetArrayFor("DescendantFonts"); + if (!pFonts || pFonts->GetCount() != 1) + return false; + + CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0); + if (!pCIDFontDict) + return false; + + m_BaseFont = pCIDFontDict->GetStringFor("BaseFont"); + if ((m_BaseFont.Compare("CourierStd") == 0 || + m_BaseFont.Compare("CourierStd-Bold") == 0 || + m_BaseFont.Compare("CourierStd-BoldOblique") == 0 || + m_BaseFont.Compare("CourierStd-Oblique") == 0) && + !IsEmbedded()) { + m_bAdobeCourierStd = true; + } + CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictFor("FontDescriptor"); + if (pFontDesc) + LoadFontDescriptor(pFontDesc); + + CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); + if (!pEncoding) + return false; + + CFX_ByteString subtype = pCIDFontDict->GetStringFor("Subtype"); + m_bType1 = (subtype == "CIDFontType0"); + + CPDF_CMapManager& manager = GetFontGlobals()->m_CMapManager; + if (pEncoding->IsName()) { + CFX_ByteString cmap = pEncoding->GetString(); + bool bPromptCJK = m_pFontFile && m_bType1; + m_pCMap = manager.GetPredefinedCMap(cmap, bPromptCJK); + if (!m_pCMap) + return false; + } else if (CPDF_Stream* pStream = pEncoding->AsStream()) { + m_pCMap = new CPDF_CMap; + m_pAllocatedCMap.reset(m_pCMap); + CPDF_StreamAcc acc; + acc.LoadAllData(pStream, FALSE); + m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize()); + } else { + return false; + } + + m_Charset = m_pCMap->m_Charset; + if (m_Charset == CIDSET_UNKNOWN) { + CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictFor("CIDSystemInfo"); + if (pCIDInfo) { + m_Charset = + CharsetFromOrdering(pCIDInfo->GetStringFor("Ordering").AsStringC()); + } + } + if (m_Charset != CIDSET_UNKNOWN) { + bool bPromptCJK = !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID || + pCIDFontDict->KeyExist("W")); + m_pCID2UnicodeMap = manager.GetCID2UnicodeMap(m_Charset, bPromptCJK); + } + if (m_Font.GetFace()) { + if (m_bType1) + FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); + else + FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding); + } + m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000); + CPDF_Array* pWidthArray = pCIDFontDict->GetArrayFor("W"); + if (pWidthArray) + LoadMetricsArray(pWidthArray, m_WidthList, 1); + if (!IsEmbedded()) + LoadSubstFont(); + + if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) { + CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap"); + if (pmap) { + if (CPDF_Stream* pStream = pmap->AsStream()) { + m_pStreamAcc.reset(new CPDF_StreamAcc); + m_pStreamAcc->LoadAllData(pStream, FALSE); + } else if (pmap->GetString() == "Identity") { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (m_pFontFile) + m_bCIDIsGID = true; +#else + m_bCIDIsGID = true; +#endif + } + } + } + + CheckFontMetrics(); + if (IsVertWriting()) { + pWidthArray = pCIDFontDict->GetArrayFor("W2"); + if (pWidthArray) + LoadMetricsArray(pWidthArray, m_VertMetrics, 3); + CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayFor("DW2"); + if (pDefaultArray) { + m_DefaultVY = pDefaultArray->GetIntegerAt(0); + m_DefaultW1 = pDefaultArray->GetIntegerAt(1); + } else { + m_DefaultVY = 880; + m_DefaultW1 = -1000; + } + } + return true; +} + +FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) { + if (charcode < 256 && m_CharBBox[charcode].right != -1) + return m_CharBBox[charcode]; + + FX_RECT rect; + bool bVert = false; + int glyph_index = GlyphFromCharCode(charcode, &bVert); + FXFT_Face face = m_Font.GetFace(); + if (face) { + if (FXFT_Is_Face_Tricky(face)) { + int err = FXFT_Load_Glyph(face, glyph_index, + FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + if (!err) { + FXFT_BBox cbox; + FXFT_Glyph glyph; + err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph); + if (!err) { + FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); + int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem; + int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem; + if (pixel_size_x == 0 || pixel_size_y == 0) { + rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin); + } else { + rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x, + cbox.yMax * 1000 / pixel_size_y, + cbox.xMax * 1000 / pixel_size_x, + cbox.yMin * 1000 / pixel_size_y); + } + rect.top = std::min(rect.top, + static_cast(FXFT_Get_Face_Ascender(face))); + rect.bottom = std::max( + rect.bottom, static_cast(FXFT_Get_Face_Descender(face))); + FXFT_Done_Glyph(glyph); + } + } + } else { + int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE); + if (err == 0) { + rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face), + TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face), + TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + + FXFT_Get_Glyph_Width(face), + face), + TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - + FXFT_Get_Glyph_Height(face), + face)); + rect.top += rect.top / 64; + } + } + } + if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) { + uint16_t CID = CIDFromCharCode(charcode); + const uint8_t* pTransform = GetCIDTransform(CID); + if (pTransform && !bVert) { + CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]), + CIDTransformToFloat(pTransform[1]), + CIDTransformToFloat(pTransform[2]), + CIDTransformToFloat(pTransform[3]), + CIDTransformToFloat(pTransform[4]) * 1000, + CIDTransformToFloat(pTransform[5]) * 1000); + CFX_FloatRect rect_f(rect); + rect_f.Transform(&matrix); + rect = rect_f.GetOuterRect(); + } + } + if (charcode < 256) + m_CharBBox[charcode] = rect; + + return rect; +} + +int CPDF_CIDFont::GetCharWidthF(uint32_t charcode) { + if (charcode < 0x80 && m_bAnsiWidthsFixed) + return (charcode >= 32 && charcode < 127) ? 500 : 0; + + uint16_t cid = CIDFromCharCode(charcode); + int size = m_WidthList.GetSize(); + const uint32_t* pList = m_WidthList.GetData(); + for (int i = 0; i < size; i += 3) { + const uint32_t* pEntry = pList + i; + if (IsMetricForCID(pEntry, cid)) + return static_cast(pEntry[2]); + } + return m_DefaultWidth; +} + +short CPDF_CIDFont::GetVertWidth(uint16_t CID) const { + uint32_t vertsize = m_VertMetrics.GetSize() / 5; + if (vertsize) { + const uint32_t* pTable = m_VertMetrics.GetData(); + for (uint32_t i = 0; i < vertsize; i++) { + const uint32_t* pEntry = pTable + (i * 5); + if (IsMetricForCID(pEntry, CID)) + return static_cast(pEntry[2]); + } + } + return m_DefaultW1; +} + +void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const { + uint32_t vertsize = m_VertMetrics.GetSize() / 5; + if (vertsize) { + const uint32_t* pTable = m_VertMetrics.GetData(); + for (uint32_t i = 0; i < vertsize; i++) { + const uint32_t* pEntry = pTable + (i * 5); + if (IsMetricForCID(pEntry, CID)) { + vx = static_cast(pEntry[3]); + vy = static_cast(pEntry[4]); + return; + } + } + } + uint32_t dwWidth = m_DefaultWidth; + int size = m_WidthList.GetSize(); + const uint32_t* pList = m_WidthList.GetData(); + for (int i = 0; i < size; i += 3) { + const uint32_t* pEntry = pList + i; + if (IsMetricForCID(pEntry, CID)) { + dwWidth = pEntry[2]; + break; + } + } + vx = static_cast(dwWidth) / 2; + vy = m_DefaultVY; +} + +int CPDF_CIDFont::GetGlyphIndex(uint32_t unicode, bool* pVertGlyph) { + if (pVertGlyph) + *pVertGlyph = false; + + FXFT_Face face = m_Font.GetFace(); + int index = FXFT_Get_Char_Index(face, unicode); + if (unicode == 0x2502) + return index; + + if (!index || !IsVertWriting()) + return index; + + if (m_pTTGSUBTable) + return GetVerticalGlyph(index, pVertGlyph); + + if (!m_Font.GetSubData()) { + unsigned long length = 0; + int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, + nullptr, &length); + if (!error) + m_Font.SetSubData(FX_Alloc(uint8_t, length)); + } + int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, + m_Font.GetSubData(), nullptr); + if (error || !m_Font.GetSubData()) + return index; + + m_pTTGSUBTable.reset(new CFX_CTTGSUBTable); + m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData()); + return GetVerticalGlyph(index, pVertGlyph); +} + +int CPDF_CIDFont::GetVerticalGlyph(int index, bool* pVertGlyph) { + uint32_t vindex = 0; + m_pTTGSUBTable->GetVerticalGlyph(index, &vindex); + if (!vindex) + return index; + + index = vindex; + if (pVertGlyph) + *pVertGlyph = true; + return index; +} + +int CPDF_CIDFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { + if (pVertGlyph) + *pVertGlyph = FALSE; + + if (!m_pFontFile && !m_pStreamAcc) { + uint16_t cid = CIDFromCharCode(charcode); + FX_WCHAR unicode = 0; + if (m_bCIDIsGID) { +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ + return cid; +#else + if (m_Flags & PDFFONT_SYMBOLIC) + return cid; + + CFX_WideString uni_str = UnicodeFromCharCode(charcode); + if (uni_str.IsEmpty()) + return cid; + + unicode = uni_str.GetAt(0); +#endif + } else { + if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) + unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid); + if (unicode == 0) + unicode = GetUnicodeFromCharCode(charcode); + if (unicode == 0) { + CFX_WideString unicode_str = UnicodeFromCharCode(charcode); + if (!unicode_str.IsEmpty()) + unicode = unicode_str.GetAt(0); + } + } + FXFT_Face face = m_Font.GetFace(); + if (unicode == 0) { + if (!m_bAdobeCourierStd) + return charcode ? static_cast(charcode) : -1; + + charcode += 31; + bool bMSUnicode = FT_UseTTCharmap(face, 3, 1); + bool bMacRoman = !bMSUnicode && FT_UseTTCharmap(face, 1, 0); + int iBaseEncoding = PDFFONT_ENCODING_STANDARD; + if (bMSUnicode) + iBaseEncoding = PDFFONT_ENCODING_WINANSI; + else if (bMacRoman) + iBaseEncoding = PDFFONT_ENCODING_MACROMAN; + const FX_CHAR* name = GetAdobeCharName( + iBaseEncoding, std::vector(), charcode); + if (!name) + return charcode ? static_cast(charcode) : -1; + + int index = 0; + uint16_t name_unicode = PDF_UnicodeFromAdobeName(name); + if (!name_unicode) + return charcode ? static_cast(charcode) : -1; + + if (iBaseEncoding == PDFFONT_ENCODING_STANDARD) + return FXFT_Get_Char_Index(face, name_unicode); + + if (iBaseEncoding == PDFFONT_ENCODING_WINANSI) { + index = FXFT_Get_Char_Index(face, name_unicode); + } else { + ASSERT(iBaseEncoding == PDFFONT_ENCODING_MACROMAN); + uint32_t maccode = + FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, name_unicode); + index = maccode ? FXFT_Get_Char_Index(face, maccode) + : FXFT_Get_Name_Index(face, const_cast(name)); + } + if (index == 0 || index == 0xffff) + return charcode ? static_cast(charcode) : -1; + return index; + } + if (m_Charset == CIDSET_JAPAN1) { + if (unicode == '\\') { + unicode = '/'; +#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ + } else if (unicode == 0xa5) { + unicode = 0x5c; +#endif + } + } + if (!face) + return unicode; + + int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); + if (err) { + int i; + for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { + uint32_t ret = FT_CharCodeFromUnicode( + FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]), + static_cast(charcode)); + if (ret == 0) + continue; + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); + unicode = static_cast(ret); + break; + } + if (i == FXFT_Get_Face_CharmapCount(face) && i) { + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); + unicode = static_cast(charcode); + } + } + if (FXFT_Get_Face_Charmap(face)) { + int index = GetGlyphIndex(unicode, pVertGlyph); + return index != 0 ? index : -1; + } + return unicode; + } + + if (!m_Font.GetFace()) + return -1; + + uint16_t cid = CIDFromCharCode(charcode); + if (!m_pStreamAcc) { + if (m_bType1) + return cid; + + if (m_pFontFile && !m_pCMap->m_pMapping) + return cid; + if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || + !FXFT_Get_Face_Charmap(m_Font.GetFace())) { + return cid; + } + if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) == + FXFT_ENCODING_UNICODE) { + CFX_WideString unicode_str = UnicodeFromCharCode(charcode); + if (unicode_str.IsEmpty()) + return -1; + + charcode = unicode_str.GetAt(0); + } + return GetGlyphIndex(charcode, pVertGlyph); + } + uint32_t byte_pos = cid * 2; + if (byte_pos + 2 > m_pStreamAcc->GetSize()) + return -1; + + const uint8_t* pdata = m_pStreamAcc->GetData() + byte_pos; + return pdata[0] * 256 + pdata[1]; +} + +uint32_t CPDF_CIDFont::GetNextChar(const FX_CHAR* pString, + int nStrLen, + int& offset) const { + return m_pCMap->GetNextChar(pString, nStrLen, offset); +} + +int CPDF_CIDFont::GetCharSize(uint32_t charcode) const { + return m_pCMap->GetCharSize(charcode); +} + +int CPDF_CIDFont::CountChar(const FX_CHAR* pString, int size) const { + return m_pCMap->CountChar(pString, size); +} + +int CPDF_CIDFont::AppendChar(FX_CHAR* str, uint32_t charcode) const { + return m_pCMap->AppendChar(str, charcode); +} + +bool CPDF_CIDFont::IsUnicodeCompatible() const { + if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded()) + return true; + return m_pCMap->m_Coding != CIDCODING_UNKNOWN; +} + +void CPDF_CIDFont::LoadSubstFont() { + pdfium::base::CheckedNumeric safeStemV(m_StemV); + safeStemV *= 5; + m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, + safeStemV.ValueOrDefault(FXFONT_FW_NORMAL), m_ItalicAngle, + g_CharsetCPs[m_Charset], IsVertWriting()); +} + +void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray, + CFX_ArrayTemplate& result, + int nElements) { + int width_status = 0; + int iCurElement = 0; + int first_code = 0; + int last_code = 0; + for (size_t i = 0; i < pArray->GetCount(); i++) { + CPDF_Object* pObj = pArray->GetDirectObjectAt(i); + if (!pObj) + continue; + + if (CPDF_Array* pObjArray = pObj->AsArray()) { + if (width_status != 1) + return; + + for (size_t j = 0; j < pObjArray->GetCount(); j += nElements) { + result.Add(first_code); + result.Add(first_code); + for (int k = 0; k < nElements; k++) + result.Add(pObjArray->GetIntegerAt(j + k)); + first_code++; + } + width_status = 0; + } else { + if (width_status == 0) { + first_code = pObj->GetInteger(); + width_status = 1; + } else if (width_status == 1) { + last_code = pObj->GetInteger(); + width_status = 2; + iCurElement = 0; + } else { + if (!iCurElement) { + result.Add(first_code); + result.Add(last_code); + } + result.Add(pObj->GetInteger()); + iCurElement++; + if (iCurElement == nElements) + width_status = 0; + } + } + } +} + +// static +FX_FLOAT CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) { + return (ch < 128 ? ch : ch - 255) * (1.0f / 127); +} + +void CPDF_CIDFont::LoadGB2312() { + m_BaseFont = m_pFontDict->GetStringFor("BaseFont"); + CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); + if (pFontDesc) + LoadFontDescriptor(pFontDesc); + + m_Charset = CIDSET_GB1; + m_bType1 = false; + CPDF_CMapManager& manager = GetFontGlobals()->m_CMapManager; + m_pCMap = manager.GetPredefinedCMap("GBK-EUC-H", false); + m_pCID2UnicodeMap = manager.GetCID2UnicodeMap(m_Charset, false); + if (!IsEmbedded()) + LoadSubstFont(); + + CheckFontMetrics(); + m_DefaultWidth = 1000; + m_bAnsiWidthsFixed = true; +} + +const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { + if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) + return nullptr; + + const auto* pEnd = g_Japan1_VertCIDs + FX_ArraySize(g_Japan1_VertCIDs); + const auto* pTransform = std::lower_bound( + g_Japan1_VertCIDs, pEnd, CID, + [](const CIDTransform& entry, uint16_t cid) { return entry.cid < cid; }); + return (pTransform < pEnd && CID == pTransform->cid) ? &pTransform->a + : nullptr; +} diff --git a/core/fpdfapi/font/cpdf_cidfont.h b/core/fpdfapi/font/cpdf_cidfont.h new file mode 100644 index 0000000000..0a6b3e7871 --- /dev/null +++ b/core/fpdfapi/font/cpdf_cidfont.h @@ -0,0 +1,91 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_CIDFONT_H_ +#define CORE_FPDFAPI_FONT_CPDF_CIDFONT_H_ + +#include + +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/fx_system.h" + +enum CIDSet { + CIDSET_UNKNOWN, + CIDSET_GB1, + CIDSET_CNS1, + CIDSET_JAPAN1, + CIDSET_KOREA1, + CIDSET_UNICODE, + CIDSET_NUM_SETS +}; + +class CFX_CTTGSUBTable; +class CPDF_Array; +class CPDF_CID2UnicodeMap; +class CPDF_CMap; +class CPDF_StreamAcc; + +class CPDF_CIDFont : public CPDF_Font { + public: + CPDF_CIDFont(); + ~CPDF_CIDFont() override; + + static FX_FLOAT CIDTransformToFloat(uint8_t ch); + + // CPDF_Font: + bool IsCIDFont() const override; + const CPDF_CIDFont* AsCIDFont() const override; + CPDF_CIDFont* AsCIDFont() override; + int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) override; + int GetCharWidthF(uint32_t charcode) override; + FX_RECT GetCharBBox(uint32_t charcode) override; + uint32_t GetNextChar(const FX_CHAR* pString, + int nStrLen, + int& offset) const override; + int CountChar(const FX_CHAR* pString, int size) const override; + int AppendChar(FX_CHAR* str, uint32_t charcode) const override; + int GetCharSize(uint32_t charcode) const override; + bool IsVertWriting() const override; + bool IsUnicodeCompatible() const override; + bool Load() override; + CFX_WideString UnicodeFromCharCode(uint32_t charcode) const override; + uint32_t CharCodeFromUnicode(FX_WCHAR Unicode) const override; + + uint16_t CIDFromCharCode(uint32_t charcode) const; + const uint8_t* GetCIDTransform(uint16_t CID) const; + short GetVertWidth(uint16_t CID) const; + void GetVertOrigin(uint16_t CID, short& vx, short& vy) const; + + protected: + void LoadGB2312(); + int GetGlyphIndex(uint32_t unicodeb, bool* pVertGlyph); + int GetVerticalGlyph(int index, bool* pVertGlyph); + void LoadMetricsArray(CPDF_Array* pArray, + CFX_ArrayTemplate& result, + int nElements); + void LoadSubstFont(); + FX_WCHAR GetUnicodeFromCharCode(uint32_t charcode) const; + + CPDF_CMap* m_pCMap; + std::unique_ptr m_pAllocatedCMap; + CPDF_CID2UnicodeMap* m_pCID2UnicodeMap; + CIDSet m_Charset; + bool m_bType1; + bool m_bCIDIsGID; + uint16_t m_DefaultWidth; + std::unique_ptr m_pStreamAcc; + bool m_bAnsiWidthsFixed; + FX_RECT m_CharBBox[256]; + CFX_ArrayTemplate m_WidthList; + short m_DefaultVY; + short m_DefaultW1; + CFX_ArrayTemplate m_VertMetrics; + bool m_bAdobeCourierStd; + std::unique_ptr m_pTTGSUBTable; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_CIDFONT_H_ diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp new file mode 100644 index 0000000000..945681fc9d --- /dev/null +++ b/core/fpdfapi/font/cpdf_font.cpp @@ -0,0 +1,476 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_font.h" + +#include +#include + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/cpdf_fontencoding.h" +#include "core/fpdfapi/font/cpdf_truetypefont.h" +#include "core/fpdfapi/font/cpdf_type1font.h" +#include "core/fpdfapi/font/cpdf_type3font.h" +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/fpdf_page/pageint.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_name.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fxcrt/fx_memory.h" +#include "core/fxge/fx_freetype.h" +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" + +namespace { + +const uint8_t kChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00}, + {0xBF, 0xAC, 0xCC, 0xE5, 0x00}, + {0xBA, 0xDA, 0xCC, 0xE5, 0x00}, + {0xB7, 0xC2, 0xCB, 0xCE, 0x00}, + {0xD0, 0xC2, 0xCB, 0xCE, 0x00}}; + +void GetPredefinedEncoding(const CFX_ByteString& value, int* basemap) { + if (value == "WinAnsiEncoding") + *basemap = PDFFONT_ENCODING_WINANSI; + else if (value == "MacRomanEncoding") + *basemap = PDFFONT_ENCODING_MACROMAN; + else if (value == "MacExpertEncoding") + *basemap = PDFFONT_ENCODING_MACEXPERT; + else if (value == "PDFDocEncoding") + *basemap = PDFFONT_ENCODING_PDFDOC; +} + +} // namespace + +CPDF_Font::CPDF_Font() + : m_pFontFile(nullptr), + m_pFontDict(nullptr), + m_bToUnicodeLoaded(false), + m_Flags(0), + m_StemV(0), + m_Ascent(0), + m_Descent(0), + m_ItalicAngle(0) {} + +CPDF_Font::~CPDF_Font() { + if (m_pFontFile) { + m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( + m_pFontFile->GetStream()->AsStream()); + } +} + +bool CPDF_Font::IsType1Font() const { + return false; +} + +bool CPDF_Font::IsTrueTypeFont() const { + return false; +} + +bool CPDF_Font::IsType3Font() const { + return false; +} + +bool CPDF_Font::IsCIDFont() const { + return false; +} + +const CPDF_Type1Font* CPDF_Font::AsType1Font() const { + return nullptr; +} + +CPDF_Type1Font* CPDF_Font::AsType1Font() { + return nullptr; +} + +const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const { + return nullptr; +} + +CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() { + return nullptr; +} + +const CPDF_Type3Font* CPDF_Font::AsType3Font() const { + return nullptr; +} + +CPDF_Type3Font* CPDF_Font::AsType3Font() { + return nullptr; +} + +const CPDF_CIDFont* CPDF_Font::AsCIDFont() const { + return nullptr; +} + +CPDF_CIDFont* CPDF_Font::AsCIDFont() { + return nullptr; +} + +bool CPDF_Font::IsUnicodeCompatible() const { + return false; +} + +int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const { + return size; +} + +int CPDF_Font::GetCharSize(uint32_t charcode) const { + return 1; +} + +int CPDF_Font::GlyphFromCharCodeExt(uint32_t charcode) { + return GlyphFromCharCode(charcode, nullptr); +} + +bool CPDF_Font::IsVertWriting() const { + const CPDF_CIDFont* pCIDFont = AsCIDFont(); + return pCIDFont ? pCIDFont->IsVertWriting() : m_Font.IsVertical(); +} + +int CPDF_Font::AppendChar(FX_CHAR* buf, uint32_t charcode) const { + *buf = static_cast(charcode); + return 1; +} + +void CPDF_Font::AppendChar(CFX_ByteString& str, uint32_t charcode) const { + char buf[4]; + int len = AppendChar(buf, charcode); + if (len == 1) { + str += buf[0]; + } else { + str += CFX_ByteString(buf, len); + } +} + +CFX_WideString CPDF_Font::UnicodeFromCharCode(uint32_t charcode) const { + if (!m_bToUnicodeLoaded) + LoadUnicodeMap(); + + return m_pToUnicodeMap ? m_pToUnicodeMap->Lookup(charcode) : CFX_WideString(); +} + +uint32_t CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { + if (!m_bToUnicodeLoaded) + LoadUnicodeMap(); + + return m_pToUnicodeMap ? m_pToUnicodeMap->ReverseLookup(unicode) : 0; +} + +void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { + m_Flags = pFontDesc->GetIntegerFor("Flags", PDFFONT_NONSYMBOLIC); + int ItalicAngle = 0; + FX_BOOL bExistItalicAngle = FALSE; + if (pFontDesc->KeyExist("ItalicAngle")) { + ItalicAngle = pFontDesc->GetIntegerFor("ItalicAngle"); + bExistItalicAngle = TRUE; + } + if (ItalicAngle < 0) { + m_Flags |= PDFFONT_ITALIC; + m_ItalicAngle = ItalicAngle; + } + FX_BOOL bExistStemV = FALSE; + if (pFontDesc->KeyExist("StemV")) { + m_StemV = pFontDesc->GetIntegerFor("StemV"); + bExistStemV = TRUE; + } + FX_BOOL bExistAscent = FALSE; + if (pFontDesc->KeyExist("Ascent")) { + m_Ascent = pFontDesc->GetIntegerFor("Ascent"); + bExistAscent = TRUE; + } + FX_BOOL bExistDescent = FALSE; + if (pFontDesc->KeyExist("Descent")) { + m_Descent = pFontDesc->GetIntegerFor("Descent"); + bExistDescent = TRUE; + } + FX_BOOL bExistCapHeight = FALSE; + if (pFontDesc->KeyExist("CapHeight")) { + bExistCapHeight = TRUE; + } + if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && + bExistStemV) { + m_Flags |= PDFFONT_USEEXTERNATTR; + } + if (m_Descent > 10) { + m_Descent = -m_Descent; + } + CPDF_Array* pBBox = pFontDesc->GetArrayFor("FontBBox"); + if (pBBox) { + m_FontBBox.left = pBBox->GetIntegerAt(0); + m_FontBBox.bottom = pBBox->GetIntegerAt(1); + m_FontBBox.right = pBBox->GetIntegerAt(2); + m_FontBBox.top = pBBox->GetIntegerAt(3); + } + + CPDF_Stream* pFontFile = pFontDesc->GetStreamFor("FontFile"); + if (!pFontFile) + pFontFile = pFontDesc->GetStreamFor("FontFile2"); + if (!pFontFile) + pFontFile = pFontDesc->GetStreamFor("FontFile3"); + if (!pFontFile) + return; + + m_pFontFile = m_pDocument->LoadFontFile(pFontFile); + if (!m_pFontFile) + return; + + const uint8_t* pFontData = m_pFontFile->GetData(); + uint32_t dwFontSize = m_pFontFile->GetSize(); + if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) { + m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( + m_pFontFile->GetStream()->AsStream()); + m_pFontFile = nullptr; + } +} + +void CPDF_Font::CheckFontMetrics() { + if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && + m_FontBBox.right == 0) { + FXFT_Face face = m_Font.GetFace(); + if (face) { + m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face); + m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face); + m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face); + m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face); + m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face); + m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face); + } else { + FX_BOOL bFirst = TRUE; + for (int i = 0; i < 256; i++) { + FX_RECT rect = GetCharBBox(i); + if (rect.left == rect.right) { + continue; + } + if (bFirst) { + m_FontBBox = rect; + bFirst = FALSE; + } else { + if (m_FontBBox.top < rect.top) { + m_FontBBox.top = rect.top; + } + if (m_FontBBox.right < rect.right) { + m_FontBBox.right = rect.right; + } + if (m_FontBBox.left > rect.left) { + m_FontBBox.left = rect.left; + } + if (m_FontBBox.bottom > rect.bottom) { + m_FontBBox.bottom = rect.bottom; + } + } + } + } + } + if (m_Ascent == 0 && m_Descent == 0) { + FX_RECT rect = GetCharBBox('A'); + m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top; + rect = GetCharBBox('g'); + m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom; + } +} + +void CPDF_Font::LoadUnicodeMap() const { + m_bToUnicodeLoaded = true; + CPDF_Stream* pStream = m_pFontDict->GetStreamFor("ToUnicode"); + if (!pStream) { + return; + } + m_pToUnicodeMap.reset(new CPDF_ToUnicodeMap); + m_pToUnicodeMap->Load(pStream); +} + +int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) { + int offset = 0; + int width = 0; + while (offset < size) { + uint32_t charcode = GetNextChar(pString, size, offset); + width += GetCharWidthF(charcode); + } + return width; +} + +CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, + const CFX_ByteStringC& name) { + CFX_ByteString fontname(name); + int font_id = PDF_GetStandardFontName(&fontname); + if (font_id < 0) + return nullptr; + + CPDF_FontGlobals* pFontGlobals = + CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); + CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); + if (pFont) + return pFont; + + CPDF_Dictionary* pDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); + pDict->SetNameFor("Type", "Font"); + pDict->SetNameFor("Subtype", "Type1"); + pDict->SetNameFor("BaseFont", fontname); + pDict->SetNameFor("Encoding", "WinAnsiEncoding"); + return pFontGlobals->Set(pDoc, font_id, CPDF_Font::Create(nullptr, pDict)); +} + +std::unique_ptr CPDF_Font::Create(CPDF_Document* pDoc, + CPDF_Dictionary* pFontDict) { + CFX_ByteString type = pFontDict->GetStringFor("Subtype"); + std::unique_ptr pFont; + if (type == "TrueType") { + CFX_ByteString tag = pFontDict->GetStringFor("BaseFont").Left(4); + for (size_t i = 0; i < FX_ArraySize(kChineseFontNames); ++i) { + if (tag == CFX_ByteString(kChineseFontNames[i], 4)) { + CPDF_Dictionary* pFontDesc = pFontDict->GetDictFor("FontDescriptor"); + if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) + pFont.reset(new CPDF_CIDFont); + break; + } + } + if (!pFont) + pFont.reset(new CPDF_TrueTypeFont); + } else if (type == "Type3") { + pFont.reset(new CPDF_Type3Font); + } else if (type == "Type0") { + pFont.reset(new CPDF_CIDFont); + } else { + pFont.reset(new CPDF_Type1Font); + } + pFont->m_pFontDict = pFontDict; + pFont->m_pDocument = pDoc; + pFont->m_BaseFont = pFontDict->GetStringFor("BaseFont"); + return pFont->Load() ? std::move(pFont) : std::unique_ptr(); +} + +uint32_t CPDF_Font::GetNextChar(const FX_CHAR* pString, + int nStrLen, + int& offset) const { + if (offset < 0 || nStrLen < 1) { + return 0; + } + uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1]; + return static_cast(ch); +} + +void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, + int& iBaseEncoding, + std::vector* pCharNames, + bool bEmbedded, + bool bTrueType) { + if (!pEncoding) { + if (m_BaseFont == "Symbol") { + iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL + : PDFFONT_ENCODING_ADOBE_SYMBOL; + } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { + iBaseEncoding = PDFFONT_ENCODING_WINANSI; + } + return; + } + if (pEncoding->IsName()) { + if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || + iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { + return; + } + if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") { + if (!bTrueType) { + iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; + } + return; + } + CFX_ByteString bsEncoding = pEncoding->GetString(); + if (bsEncoding.Compare("MacExpertEncoding") == 0) { + bsEncoding = "WinAnsiEncoding"; + } + GetPredefinedEncoding(bsEncoding, &iBaseEncoding); + return; + } + + CPDF_Dictionary* pDict = pEncoding->AsDictionary(); + if (!pDict) + return; + + if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && + iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { + CFX_ByteString bsEncoding = pDict->GetStringFor("BaseEncoding"); + if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) { + bsEncoding = "WinAnsiEncoding"; + } + GetPredefinedEncoding(bsEncoding, &iBaseEncoding); + } + if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) + iBaseEncoding = PDFFONT_ENCODING_STANDARD; + + CPDF_Array* pDiffs = pDict->GetArrayFor("Differences"); + if (!pDiffs) + return; + + pCharNames->resize(256); + uint32_t cur_code = 0; + for (uint32_t i = 0; i < pDiffs->GetCount(); i++) { + CPDF_Object* pElement = pDiffs->GetDirectObjectAt(i); + if (!pElement) + continue; + + if (CPDF_Name* pName = pElement->AsName()) { + if (cur_code < 256) + (*pCharNames)[cur_code] = pName->GetString(); + cur_code++; + } else { + cur_code = pElement->GetInteger(); + } + } +} + +bool CPDF_Font::IsStandardFont() const { + if (!IsType1Font()) + return false; + if (m_pFontFile) + return false; + if (AsType1Font()->GetBase14Font() < 0) + return false; + return true; +} + +const FX_CHAR* CPDF_Font::GetAdobeCharName( + int iBaseEncoding, + const std::vector& charnames, + int charcode) { + if (charcode < 0 || charcode >= 256) { + ASSERT(false); + return nullptr; + } + + if (!charnames.empty() && !charnames[charcode].IsEmpty()) + return charnames[charcode].c_str(); + + const FX_CHAR* name = nullptr; + if (iBaseEncoding) + name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); + return name && name[0] ? name : nullptr; +} + +uint32_t CPDF_Font::FallbackFontFromCharcode(uint32_t charcode) { + if (m_FontFallbacks.empty()) { + m_FontFallbacks.push_back(pdfium::MakeUnique()); + m_FontFallbacks[0]->LoadSubst("Arial", IsTrueTypeFont(), m_Flags, + m_StemV * 5, m_ItalicAngle, 0, + IsVertWriting()); + } + return 0; +} + +int CPDF_Font::FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode) { + if (fallbackFont < 0 || + fallbackFont >= pdfium::CollectionSize(m_FontFallbacks)) { + return -1; + } + int glyph = + FXFT_Get_Char_Index(m_FontFallbacks[fallbackFont]->GetFace(), charcode); + if (glyph == 0 || glyph == 0xffff) + return -1; + return glyph; +} diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h new file mode 100644 index 0000000000..244ab72158 --- /dev/null +++ b/core/fpdfapi/font/cpdf_font.h @@ -0,0 +1,132 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_FONT_H_ +#define CORE_FPDFAPI_FONT_CPDF_FONT_H_ + +#include +#include + +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/fx_system.h" +#include "core/fxge/fx_font.h" + +#define PDFFONT_FIXEDPITCH 1 +#define PDFFONT_SERIF 2 +#define PDFFONT_SYMBOLIC 4 +#define PDFFONT_SCRIPT 8 +#define PDFFONT_NONSYMBOLIC 32 +#define PDFFONT_ITALIC 64 +#define PDFFONT_ALLCAP 0x10000 +#define PDFFONT_SMALLCAP 0x20000 +#define PDFFONT_FORCEBOLD 0x40000 +#define PDFFONT_USEEXTERNATTR 0x80000 + +class CFX_SubstFont; +class CPDF_CIDFont; +class CPDF_Dictionary; +class CPDF_Document; +class CPDF_Object; +class CPDF_StreamAcc; +class CPDF_TrueTypeFont; +class CPDF_Type1Font; +class CPDF_Type3Font; +class CPDF_ToUnicodeMap; + +class CPDF_Font { + public: + static std::unique_ptr Create(CPDF_Document* pDoc, + CPDF_Dictionary* pFontDict); + static CPDF_Font* GetStockFont(CPDF_Document* pDoc, + const CFX_ByteStringC& fontname); + static const uint32_t kInvalidCharCode = static_cast(-1); + + virtual ~CPDF_Font(); + + virtual bool IsType1Font() const; + virtual bool IsTrueTypeFont() const; + virtual bool IsType3Font() const; + virtual bool IsCIDFont() const; + virtual const CPDF_Type1Font* AsType1Font() const; + virtual CPDF_Type1Font* AsType1Font(); + virtual const CPDF_TrueTypeFont* AsTrueTypeFont() const; + virtual CPDF_TrueTypeFont* AsTrueTypeFont(); + virtual const CPDF_Type3Font* AsType3Font() const; + virtual CPDF_Type3Font* AsType3Font(); + virtual const CPDF_CIDFont* AsCIDFont() const; + virtual CPDF_CIDFont* AsCIDFont(); + + virtual bool IsVertWriting() const; + virtual bool IsUnicodeCompatible() const; + virtual uint32_t GetNextChar(const FX_CHAR* pString, + int nStrLen, + int& offset) const; + virtual int CountChar(const FX_CHAR* pString, int size) const; + virtual int AppendChar(FX_CHAR* buf, uint32_t charcode) const; + virtual int GetCharSize(uint32_t charcode) const; + virtual int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) = 0; + virtual int GlyphFromCharCodeExt(uint32_t charcode); + virtual CFX_WideString UnicodeFromCharCode(uint32_t charcode) const; + virtual uint32_t CharCodeFromUnicode(FX_WCHAR Unicode) const; + + const CFX_ByteString& GetBaseFont() const { return m_BaseFont; } + CFX_SubstFont* GetSubstFont() const { return m_Font.GetSubstFont(); } + uint32_t GetFlags() const { return m_Flags; } + bool IsEmbedded() const { return IsType3Font() || m_pFontFile != nullptr; } + CPDF_StreamAcc* GetFontFile() const { return m_pFontFile; } + CPDF_Dictionary* GetFontDict() const { return m_pFontDict; } + bool IsStandardFont() const; + FXFT_Face GetFace() const { return m_Font.GetFace(); } + void AppendChar(CFX_ByteString& str, uint32_t charcode) const; + + void GetFontBBox(FX_RECT& rect) const { rect = m_FontBBox; } + int GetTypeAscent() const { return m_Ascent; } + int GetTypeDescent() const { return m_Descent; } + int GetItalicAngle() const { return m_ItalicAngle; } + int GetStemV() const { return m_StemV; } + int GetStringWidth(const FX_CHAR* pString, int size); + uint32_t FallbackFontFromCharcode(uint32_t charcode); + int FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode); + + virtual int GetCharWidthF(uint32_t charcode) = 0; + virtual FX_RECT GetCharBBox(uint32_t charcode) = 0; + + CPDF_Document* m_pDocument; + CFX_Font m_Font; + std::vector> m_FontFallbacks; + + protected: + CPDF_Font(); + + virtual bool Load() = 0; + + void LoadUnicodeMap() const; // logically const only. + void LoadPDFEncoding(CPDF_Object* pEncoding, + int& iBaseEncoding, + std::vector* pCharNames, + bool bEmbedded, + bool bTrueType); + void LoadFontDescriptor(CPDF_Dictionary* pDict); + void CheckFontMetrics(); + + const FX_CHAR* GetAdobeCharName(int iBaseEncoding, + const std::vector& charnames, + int charcode); + + CFX_ByteString m_BaseFont; + CPDF_StreamAcc* m_pFontFile; + CPDF_Dictionary* m_pFontDict; + mutable std::unique_ptr m_pToUnicodeMap; + mutable bool m_bToUnicodeLoaded; + int m_Flags; + FX_RECT m_FontBBox; + int m_StemV; + int m_Ascent; + int m_Descent; + int m_ItalicAngle; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_FONT_H_ diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp new file mode 100644 index 0000000000..f6c5186a63 --- /dev/null +++ b/core/fpdfapi/font/cpdf_fontencoding.cpp @@ -0,0 +1,1818 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_fontencoding.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_name.h" +#include "core/fpdfapi/fpdf_parser/cpdf_number.h" +#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" +#include "core/fxge/fx_freetype.h" + +namespace { + +const uint16_t MSSymbolEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 32, 33, 8704, 35, + 8707, 37, 38, 8715, 40, 41, 8727, 43, 44, + 8722, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 8773, 913, 914, 935, 916, 917, 934, 915, + 919, 921, 977, 922, 923, 924, 925, 927, 928, + 920, 929, 931, 932, 933, 962, 937, 926, 936, + 918, 91, 8756, 93, 8869, 95, 8254, 945, 946, + 967, 948, 949, 966, 947, 951, 953, 981, 954, + 955, 956, 957, 959, 960, 952, 961, 963, 964, + 965, 982, 969, 958, 968, 950, 123, 124, 125, + 8764, 0, 0, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 978, + 8242, 8804, 8725, 8734, 402, 9827, 9830, 9828, 9824, + 8596, 8592, 8593, 8594, 8595, 176, 177, 8243, 8805, + 215, 8733, 8706, 8729, 247, 8800, 8801, 8776, 8943, + 0, 0, 8629, 0, 8465, 8476, 8472, 8855, 8853, + 8709, 8745, 8746, 8835, 8839, 8836, 8834, 8838, 8712, + 8713, 8736, 8711, 174, 169, 8482, 8719, 8730, 8901, + 172, 8743, 8744, 8660, 8656, 8657, 8658, 8659, 9674, + 9001, 0, 0, 0, 8721, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0x0000, 9002, 8747, + 8992, 0, 8993, 0, 0, 0, 0, 0, 0, + 0x0000, 0x0000, 0x0000, 0x0000}; + +const uint16_t StandardEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x2019, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x2018, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00a1, + 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, 0x00a4, 0x0027, 0x201c, + 0x00ab, 0x2039, 0x203a, 0xfb01, 0xfb02, 0x0000, 0x2013, 0x2020, 0x2021, + 0x00b7, 0x0000, 0x00b6, 0x2022, 0x201a, 0x201e, 0x201d, 0x00bb, 0x2026, + 0x2030, 0x0000, 0x00bf, 0x0000, 0x0060, 0x00b4, 0x02c6, 0x02dc, 0x00af, + 0x02d8, 0x02d9, 0x00a8, 0x0000, 0x02da, 0x00b8, 0x0000, 0x02dd, 0x02db, + 0x02c7, 0x2014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00c6, 0x0000, 0x00aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0141, 0x00d8, + 0x0152, 0x00ba, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00e6, 0x0000, + 0x0000, 0x0000, 0x0131, 0x0000, 0x0000, 0x0142, 0x00f8, 0x0153, 0x00df, + 0x0000, 0x0000, 0x0000, 0x0000}; + +const uint16_t MacRomanEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x0000, 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, + 0x00e1, 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f2, + 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, 0x2020, 0x00b0, + 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, 0x00ae, 0x00a9, 0x2122, + 0x00b4, 0x00a8, 0x0000, 0x00c6, 0x00d8, 0x0000, 0x00b1, 0x0000, 0x0000, + 0x00a5, 0x00b5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00aa, 0x00ba, + 0x0000, 0x00e6, 0x00f8, 0x00bf, 0x00a3, 0x00ac, 0x0000, 0x0192, 0x0000, + 0x0000, 0x00ab, 0x00bb, 0x2026, 0x0020, 0x00c0, 0x00c3, 0x00d5, 0x0152, + 0x0153, 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x0000, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, 0x2021, + 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, 0x00cb, 0x00c8, + 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, 0x0000, 0x00d2, 0x00da, + 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da, + 0x00b8, 0x02dd, 0x02db, 0x02c7}; + +const uint16_t AdobeWinAnsiEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, + 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, + 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, + 0x007e, 0x2022, 0x20ac, 0x2022, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, + 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x2022, 0x017d, 0x2022, + 0x2022, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, + 0x2122, 0x0161, 0x203a, 0x0153, 0x2022, 0x017e, 0x0178, 0x0020, 0x00a1, + 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, + 0x00ab, 0x00ac, 0x002d, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, + 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, + 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, + 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, + 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, + 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, + 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, + 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, + 0x00fc, 0x00fd, 0x00fe, 0x00ff}; + +const uint16_t MacExpertEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0xf721, 0xf6f8, 0xf7a2, + 0xf724, 0xf6e4, 0xf726, 0xf7b4, 0x207d, 0x207e, 0x2025, 0x2024, 0x002c, + 0x002d, 0x002e, 0x2044, 0xf730, 0xf731, 0xf732, 0xf733, 0xf734, 0xf735, + 0xf736, 0xf737, 0xf738, 0xf739, 0x003a, 0x003b, 0x0000, 0xf6de, 0x0000, + 0xf73f, 0x0000, 0x0000, 0x0000, 0x0000, 0xf7f0, 0x0000, 0x0000, 0x00bc, + 0x00bd, 0x00be, 0x215b, 0x215c, 0x215d, 0x215e, 0x2153, 0x2154, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfb01, 0xfb02, 0xfb03, + 0xfb04, 0x208d, 0x0000, 0x208e, 0xf6f6, 0xf6e5, 0xf760, 0xf761, 0xf762, + 0xf763, 0xf764, 0xf765, 0xf766, 0xf767, 0xf768, 0xf769, 0xf76a, 0xf76b, + 0xf76c, 0xf76d, 0xf76e, 0xf76f, 0xf770, 0xf771, 0xf772, 0xf773, 0xf774, + 0xf775, 0xf776, 0xf777, 0xf778, 0xf779, 0xf77a, 0x20a1, 0xf6dc, 0xf6dd, + 0xf6fe, 0x0000, 0x0000, 0xf6e9, 0xf6e0, 0x0000, 0x0000, 0x0000, 0x0000, + 0xf7e1, 0xf7e0, 0xf7e2, 0xf7e4, 0xf7e3, 0xf7e5, 0xf7e7, 0xf7e9, 0xf7e8, + 0xf7ea, 0xf7eb, 0xf7ed, 0xf7ec, 0xf7ee, 0xf7ef, 0xf7f1, 0xf7f3, 0xf7f2, + 0xf7f4, 0xf7f6, 0xf7f5, 0xf7fa, 0xf7f9, 0xf7fb, 0xf7fc, 0x0000, 0x2078, + 0x2084, 0x2083, 0x2086, 0x2088, 0x2087, 0xf6fd, 0x0000, 0xf6df, 0x2082, + 0x0000, 0xf7a8, 0x0000, 0xf6f5, 0xf6fd, 0x2085, 0x0000, 0xf6e1, 0xf6e7, + 0xf7fd, 0x0000, 0xf6e3, 0x0000, 0x0000, 0xf7fe, 0x0000, 0x2089, 0x2080, + 0xf6ff, 0xf7e6, 0xf7f8, 0xf7bf, 0x2081, 0xf6e9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0xf7b8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0xf6fa, 0x2012, 0xf6e6, 0x0000, 0x0000, 0x0000, 0x0000, 0xf7a1, 0x0000, + 0xf7ff, 0x0000, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, + 0x2079, 0x2070, 0x0000, 0xf6ec, 0xf6f1, 0x0000, 0x0000, 0x0000, 0xf6ed, + 0xf6f2, 0xf6eb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf6ee, 0xf6fb, + 0xf6f4, 0xf7af, 0xf6ea, 0x207f, 0xf6ef, 0xf6e2, 0xf6e8, 0xf6f7, 0xf6fc, + 0x0000, 0x0000, 0x0000, 0x0000}; + +const uint16_t AdobeSymbolEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x2200, 0x0023, + 0x2203, 0x0025, 0x0026, 0x220B, 0x0028, 0x0029, 0x2217, 0x002B, 0x002C, + 0x2212, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, + 0x003F, 0x2245, 0x0391, 0x0392, 0x03A7, 0x0394, 0x0395, 0x03A6, 0x0393, + 0x0397, 0x0399, 0x03D1, 0x039A, 0x039B, 0x039C, 0x039D, 0x039F, 0x03A0, + 0x0398, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03C2, 0x03A9, 0x039E, 0x03A8, + 0x0396, 0x005B, 0x2234, 0x005D, 0x22A5, 0x005F, 0xF8E5, 0x03B1, 0x03B2, + 0x03C7, 0x03B4, 0x03B5, 0x03C6, 0x03B3, 0x03B7, 0x03B9, 0x03D5, 0x03BA, + 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0, 0x03B8, 0x03C1, 0x03C3, 0x03C4, + 0x03C5, 0x03D6, 0x03C9, 0x03BE, 0x03C8, 0x03B6, 0x007B, 0x007C, 0x007D, + 0x223C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20AC, 0x03D2, + 0x2032, 0x2264, 0x2044, 0x221E, 0x0192, 0x2663, 0x2666, 0x2665, 0x2660, + 0x2194, 0x2190, 0x2191, 0x2192, 0x2193, 0x00B0, 0x00B1, 0x2033, 0x2265, + 0x00D7, 0x221D, 0x2202, 0x2022, 0x00F7, 0x2260, 0x2261, 0x2248, 0x2026, + 0xF8E6, 0xF8E7, 0x21B5, 0x2135, 0x2111, 0x211C, 0x2118, 0x2297, 0x2295, + 0x2205, 0x2229, 0x222A, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, + 0x2209, 0x2220, 0x2207, 0xF6DA, 0xF6D9, 0xF6DB, 0x220F, 0x221A, 0x22C5, + 0x00AC, 0x2227, 0x2228, 0x21D4, 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x25CA, + 0x2329, 0xF8E8, 0xF8E9, 0xF8EA, 0x2211, 0xF8EB, 0xF8EC, 0xF8ED, 0xF8EE, + 0xF8EF, 0xF8F0, 0xF8F1, 0xF8F2, 0xF8F3, 0xF8F4, 0x0000, 0x232A, 0x222B, + 0x2320, 0xF8F5, 0x2321, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, 0xF8FA, 0xF8FB, + 0xF8FC, 0xF8FD, 0xF8FE, 0x0000, +}; + +const uint16_t ZapfEncoding[256] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x2701, 0x2702, 0x2703, + 0x2704, 0x260E, 0x2706, 0x2707, 0x2708, 0x2709, 0x261B, 0x261E, 0x270C, + 0x270D, 0x270E, 0x270F, 0x2710, 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, + 0x2716, 0x2717, 0x2718, 0x2719, 0x271A, 0x271B, 0x271C, 0x271D, 0x271E, + 0x271F, 0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2727, + 0x2605, 0x2729, 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F, 0x2730, + 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, + 0x273A, 0x273B, 0x273C, 0x273D, 0x273E, 0x273F, 0x2740, 0x2741, 0x2742, + 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274A, 0x274B, + 0x25CF, 0x274D, 0x25A0, 0x274F, 0x2750, 0x2751, 0x2752, 0x25B2, 0x25BC, + 0x25C6, 0x2756, 0x25D7, 0x2758, 0x2759, 0x275A, 0x275B, 0x275C, 0x275D, + 0x275E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2761, + 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2663, 0x2666, 0x2665, + 0x2660, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x2776, 0x2777, 0x2778, 0x2779, 0x277A, 0x277B, 0x277C, + 0x277D, 0x277E, 0x277F, 0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, + 0x2786, 0x2787, 0x2788, 0x2789, 0x278A, 0x278B, 0x278C, 0x278D, 0x278E, + 0x278F, 0x2790, 0x2791, 0x2792, 0x2793, 0x2794, 0x2192, 0x2194, 0x2195, + 0x2798, 0x2799, 0x279A, 0x279B, 0x279C, 0x279D, 0x279E, 0x279F, 0x27A0, + 0x27A1, 0x27A2, 0x27A3, 0x27A4, 0x27A5, 0x27A6, 0x27A7, 0x27A8, 0x27A9, + 0x27AA, 0x27AB, 0x27AC, 0x27AD, 0x27AE, 0x27AF, 0x0000, 0x27B1, 0x27B2, + 0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, 0x27B8, 0x27B9, 0x27BA, 0x27BB, + 0x27BC, 0x27BD, 0x27BE, 0x0000, +}; + +const FX_CHAR* const StandardEncodingNames[224] = { + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + nullptr, + "endash", + "dagger", + "daggerdbl", + "periodcentered", + nullptr, + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + nullptr, + "questiondown", + nullptr, + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + nullptr, + "ring", + "cedilla", + nullptr, + "hungarumlaut", + "ogonek", + "caron", + "emdash", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "AE", + nullptr, + "ordfeminine", + nullptr, + nullptr, + nullptr, + nullptr, + "Lslash", + "Oslash", + "OE", + "ordmasculine", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "ae", + nullptr, + nullptr, + nullptr, + "dotlessi", + nullptr, + nullptr, + "lslash", + "oslash", + "oe", + "germandbls", + nullptr, + nullptr, + nullptr, + nullptr, +}; + +const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = { + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "bullet", + "Euro", + "bullet", + "quotesinglbase", + "florin", + "quotedblbase", + "ellipsis", + "dagger", + "daggerdbl", + "circumflex", + "perthousand", + "Scaron", + "guilsinglleft", + "OE", + "bullet", + "Zcaron", + "bullet", + "bullet", + "quoteleft", + "quoteright", + "quotedblleft", + "quotedblright", + "bullet", + "endash", + "emdash", + "tilde", + "trademark", + "scaron", + "guilsinglright", + "oe", + "bullet", + "zcaron", + "Ydieresis", + "space", + "exclamdown", + "cent", + "sterling", + "currency", + "yen", + "brokenbar", + "section", + "dieresis", + "copyright", + "ordfeminine", + "guillemotleft", + "logicalnot", + "hyphen", + "registered", + "macron", + "degree", + "plusminus", + "twosuperior", + "threesuperior", + "acute", + "mu", + "paragraph", + "periodcentered", + "cedilla", + "onesuperior", + "ordmasculine", + "guillemotright", + "onequarter", + "onehalf", + "threequarters", + "questiondown", + "Agrave", + "Aacute", + "Acircumflex", + "Atilde", + "Adieresis", + "Aring", + "AE", + "Ccedilla", + "Egrave", + "Eacute", + "Ecircumflex", + "Edieresis", + "Igrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Eth", + "Ntilde", + "Ograve", + "Oacute", + "Ocircumflex", + "Otilde", + "Odieresis", + "multiply", + "Oslash", + "Ugrave", + "Uacute", + "Ucircumflex", + "Udieresis", + "Yacute", + "Thorn", + "germandbls", + "agrave", + "aacute", + "acircumflex", + "atilde", + "adieresis", + "aring", + "ae", + "ccedilla", + "egrave", + "eacute", + "ecircumflex", + "edieresis", + "igrave", + "iacute", + "icircumflex", + "idieresis", + "eth", + "ntilde", + "ograve", + "oacute", + "ocircumflex", + "otilde", + "odieresis", + "divide", + "oslash", + "ugrave", + "uacute", + "ucircumflex", + "udieresis", + "yacute", + "thorn", + "ydieresis", +}; + +const FX_CHAR* const MacRomanEncodingNames[224] = { + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + nullptr, + "Adieresis", + "Aring", + "Ccedilla", + "Eacute", + "Ntilde", + "Odieresis", + "Udieresis", + "aacute", + "agrave", + "acircumflex", + "adieresis", + "atilde", + "aring", + "ccedilla", + "eacute", + "egrave", + "ecircumflex", + "edieresis", + "iacute", + "igrave", + "icircumflex", + "idieresis", + "ntilde", + "oacute", + "ograve", + "ocircumflex", + "odieresis", + "otilde", + "uacute", + "ugrave", + "ucircumflex", + "udieresis", + "dagger", + "degree", + "cent", + "sterling", + "section", + "bullet", + "paragraph", + "germandbls", + "registered", + "copyright", + "trademark", + "acute", + "dieresis", + "notequal", + "AE", + "Oslash", + "infinity", + "plusminus", + "lessequal", + "greaterequal", + "yen", + "mu", + "partialdiff", + "summation", + "product", + "pi", + "integral", + "ordfeminine", + "ordmasculine", + "Omega", + "ae", + "oslash", + "questiondown", + "exclamdown", + "logicalnot", + "radical", + "florin", + "approxequal", + "Delta", + "guillemotleft", + "guillemotright", + "ellipsis", + "space", + "Agrave", + "Atilde", + "Otilde", + "OE", + "oe", + "endash", + "emdash", + "quotedblleft", + "quotedblright", + "quoteleft", + "quoteright", + "divide", + "lozenge", + "ydieresis", + "Ydieresis", + "fraction", + "currency", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "daggerdbl", + "periodcentered", + "quotesinglbase", + "quotedblbase", + "perthousand", + "Acircumflex", + "Ecircumflex", + "Aacute", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Oacute", + "Ocircumflex", + "apple", + "Ograve", + "Uacute", + "Ucircumflex", + "Ugrave", + "dotlessi", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", +}; + +const FX_CHAR* const MacExpertEncodingNames[224] = { + "space", + "exclamsmall", + "Hungarumlautsmall", + "centoldstyle", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + nullptr, + "threequartersemdash", + nullptr, + "questionsmall", + nullptr, + nullptr, + nullptr, + nullptr, + "Ethsmall", + nullptr, + nullptr, + "onequarter", + "onehalf", + "threequarters", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + nullptr, + "parenrightinferior", + "Circumflexsmall", + "hypheninferior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + nullptr, + nullptr, + "asuperior", + "centsuperior", + nullptr, + nullptr, + nullptr, + nullptr, + "Aacutesmall", + "Agravesmall", + "Acircumflexsmall", + "Adieresissmall", + "Atildesmall", + "Aringsmall", + "Ccedillasmall", + "Eacutesmall", + "Egravesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Iacutesmall", + "Igravesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ntildesmall", + "Oacutesmall", + "Ogravesmall", + "Ocircumflexsmall", + "Odieresissmall", + "Otildesmall", + "Uacutesmall", + "Ugravesmall", + "Ucircumflexsmall", + "Udieresissmall", + nullptr, + "eightsuperior", + "fourinferior", + "threeinferior", + "sixinferior", + "eightinferior", + "seveninferior", + "Scaronsmall", + nullptr, + "centinferior", + "twoinferior", + nullptr, + "Dieresissmall", + nullptr, + "Caronsmall", + "Scaronsmall", + "fiveinferior", + nullptr, + "commainferior", + "periodinferior", + "Yacutesmall", + nullptr, + "dollarinferior", + nullptr, + nullptr, + "Thornsmall", + nullptr, + "nineinferior", + "zeroinferior", + "Zcaronsmall", + "AEsmall", + "Oslashsmall", + "questiondownsmall", + "oneinferior", + "asuperior", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "Cedillasmall", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "OEsmall", + "figuredash", + "hyphensuperior", + nullptr, + nullptr, + nullptr, + nullptr, + "exclamdownsmall", + nullptr, + "Ydieresissmall", + nullptr, + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "ninesuperior", + "zerosuperior", + nullptr, + "esuperior", + "rsuperior", + nullptr, + nullptr, + nullptr, + "isuperior", + "ssuperior", + "dsuperior", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "lsuperior", + "Ogoneksmall", + "Brevesmall", + "Macronsmall", + "bsuperior", + "nsuperior", + "msuperior", + "commasuperior", + "periodsuperior", + "Dotaccentsmall", + "Ringsmall", + nullptr, + nullptr, + nullptr, + nullptr, +}; + +const FX_CHAR* const PDFDocEncodingNames[232] = { + "breve", + "caron", + "circumflex", + "dotaccent", + "hungarumlaut", + "ogonek", + "ring", + "tilde", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + nullptr, + "bullet3", + "dagger", + "daggerdbl", + "ellipsis", + "emdash", + "endash", + "florin", + "fraction", + "guilsinglleft", + "guilsinglright", + "minus", + "perthousand", + "quotedblbase", + "quotedblleft", + "quotedblright", + "quoteleft", + "quoteright", + "quotesinglbase", + "trademark", + "fi", + "fl", + "Lslash", + "OE", + "Scaron", + "Ydieresis", + "Zcaron2", + "dotlessi", + "lslash", + "oe", + "scaron", + "zcaron2", + nullptr, + "Euro", + "exclamdown", + "cent", + "sterling", + "currency", + "yen", + "brokenbar", + "section", + "dieresis", + "copyright", + "ordfeminine", + "guillemotleft4", + "logicalnot", + nullptr, + "registered", + "macron", + "degree", + "plusminus", + "twosuperior", + "threesuperior", + "acute", + "mu", + "paragraph", + "periodcentered", + "cedilla", + "onesuperior", + "ordmasculine", + "guillemotright4", + "onequarter", + "onehalf", + "threequarters", + "questiondown", + "Agrave", + "Aacute", + "Acircumflex", + "Atilde", + "Adieresis", + "Aring", + "AE", + "Ccedilla", + "Egrave", + "Eacute", + "Ecircumflex", + "Edieresis", + "Igrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Eth", + "Ntilde", + "Ograve", + "Oacute", + "Ocircumflex", + "Otilde", + "Odieresis", + "multiply", + "Oslash", + "Ugrave", + "Uacute", + "Ucircumflex", + "Udieresis", + "Yacute", + "Thorn", + "germandbls", + "agrave", + "aacute", + "acircumflex", + "atilde", + "adieresis", + "aring", + "ae", + "ccedilla", + "egrave", + "eacute", + "ecircumflex", + "edieresis", + "igrave", + "iacute", + "icircumflex", + "idieresis", + "eth", + "ntilde", + "ograve", + "oacute", + "ocircumflex", + "otilde", + "odieresis", + "divide", + "oslash", + "ugrave", + "uacute", + "ucircumflex", + "udieresis", + "yacute", + "thorn", + "ydieresis", +}; + +const FX_CHAR* const AdobeSymbolEncodingNames[224] = { + "space", + "exclam", + "universal", + "numbersign", + "existential", + "percent", + "ampersand", + "suchthat", + "parenleft", + "parenright", + "asteriskmath", + "plus", + "comma", + "minus", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "congruent", + "Alpha", + "Beta", + "Chi", + "Delta", + "Epsilon", + "Phi", + "Gamma", + "Eta", + "Iota", + "theta1", + "Kappa", + "Lambda", + "Mu", + "Nu", + "Omicron", + "Pi", + "Theta", + "Rho", + "Sigma", + "Tau", + "Upsilon", + "sigma1", + "Omega", + "Xi", + "Psi", + "Zeta", + "bracketleft", + "therefore", + "bracketright", + "perpendicular", + "underscore", + "radicalex", + "alpha", + "beta", + "chi", + "delta", + "epsilon", + "phi", + "gamma", + "eta", + "iota", + "phi1", + "kappa", + "lambda", + "mu", + "nu", + "omicron", + "pi", + "theta", + "rho", + "sigma", + "tau", + "upsilon", + "omega1", + "omega", + "xi", + "psi", + "zeta", + "braceleft", + "bar", + "braceright", + "similar", + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + "Euro", + "Upsilon1", + "minute", + "lessequal", + "fraction", + "infinity", + "florin", + "club", + "diamond", + "heart", + "spade", + "arrowboth", + "arrowleft", + "arrowup", + "arrowright", + "arrowdown", + "degree", + "plusminus", + "second", + "greaterequal", + "multiply", + "proportional", + "partialdiff", + "bullet", + "divide", + "notequal", + "equivalence", + "approxequal", + "ellipsis", + "arrowvertex", + "arrowhorizex", + "carriagereturn", + "aleph", + "Ifraktur", + "Rfraktur", + "weierstrass", + "circlemultiply", + "circleplus", + "emptyset", + "intersection", + "union", + "propersuperset", + "reflexsuperset", + "notsubset", + "propersubset", + "reflexsubset", + "element", + "notelement", + "angle", + "gradient", + "registerserif", + "copyrightserif", + "trademarkserif", + "product", + "radical", + "dotmath", + "logicalnot", + "logicaland", + "logicalor", + "arrowdblboth", + "arrowdblleft", + "arrowdblup", + "arrowdblright", + "arrowdbldown", + "lozenge", + "angleleft", + "registersans", + "copyrightsans", + "trademarksans", + "summation", + "parenlefttp", + "parenleftex", + "parenleftbt", + "bracketlefttp", + "bracketleftex", + "bracketleftbt", + "bracelefttp", + "braceleftmid", + "braceleftbt", + "braceex", + nullptr, + "angleright", + "integral", + "integraltp", + "integralex", + "integralbt", + "parenrighttp", + "parenrightex", + "parenrightbt", + "bracketrighttp", + "bracketrightex", + "bracketrightbt", + "bracerighttp", + "bracerightmid", + "bracerightbt", + nullptr, +}; + +const FX_CHAR* const ZapfEncodingNames[224] = { + "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", + "a118", "a117", "a11", "a12", "a13", "a14", "a15", "a16", + "a105", "a17", "a18", "a19", "a20", "a21", "a22", "a23", + "a24", "a25", "a26", "a27", "a28", "a6", "a7", "a8", + "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", + "a35", "a36", "a37", "a38", "a39", "a40", "a41", "a42", + "a43", "a44", "a45", "a46", "a47", "a48", "a49", "a50", + "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", + "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", + "a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", + "a203", "a75", "a204", "a76", "a77", "a78", "a79", "a81", + "a82", "a83", "a84", "a97", "a98", "a99", "a100", nullptr, + "a89", "a90", "a93", "a94", "a91", "a92", "a205", "a85", + "a206", "a86", "a87", "a88", "a95", "a96", nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, "a101", "a102", "a103", "a104", "a106", "a107", "a108", + "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", + "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", + "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", + "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", + "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", + "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", + "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", + "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", + "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", + nullptr, "a201", "a183", "a184", "a197", "a185", "a194", "a198", + "a186", "a195", "a187", "a188", "a189", "a190", "a191", nullptr}; + +uint32_t PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) { + for (uint32_t i = 0; i < 256; i++) + if (pCodes[i] == unicode) + return i; + return 0; +} + +} // namespace + +CPDF_FontEncoding::CPDF_FontEncoding() { + FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); +} + +int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const { + for (int i = 0; i < 256; i++) + if (m_Unicodes[i] == unicode) { + return i; + } + return -1; +} + +CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) { + const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); + if (!pSrc) { + FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); + } else { + for (int i = 0; i < 256; i++) + m_Unicodes[i] = pSrc[i]; + } +} + +FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const { + return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == + 0; +} + +CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr pPool) { + int predefined = 0; + for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; + cs++) { + const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(cs); + FX_BOOL match = TRUE; + for (int i = 0; i < 256; ++i) { + if (m_Unicodes[i] != pSrc[i]) { + match = FALSE; + break; + } + } + if (match) { + predefined = cs; + break; + } + } + if (predefined) { + if (predefined == PDFFONT_ENCODING_WINANSI) { + return new CPDF_Name(pPool->Intern("WinAnsiEncoding")); + } + if (predefined == PDFFONT_ENCODING_MACROMAN) { + return new CPDF_Name(pPool->Intern("MacRomanEncoding")); + } + if (predefined == PDFFONT_ENCODING_MACEXPERT) { + return new CPDF_Name(pPool->Intern("MacExpertEncoding")); + } + return nullptr; + } + const uint16_t* pStandard = + PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); + CPDF_Array* pDiff = new CPDF_Array; + for (int i = 0; i < 256; i++) { + if (pStandard[i] == m_Unicodes[i]) { + continue; + } + pDiff->Add(new CPDF_Number(i)); + pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); + } + + CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool); + pDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); + pDict->SetFor("Differences", pDiff); + return pDict; +} + +uint32_t FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode) { + switch (encoding) { + case FXFT_ENCODING_UNICODE: + return unicode; + case FXFT_ENCODING_ADOBE_STANDARD: + return PDF_FindCode(StandardEncoding, unicode); + case FXFT_ENCODING_ADOBE_EXPERT: + return PDF_FindCode(MacExpertEncoding, unicode); + case FXFT_ENCODING_ADOBE_LATIN_1: + return PDF_FindCode(AdobeWinAnsiEncoding, unicode); + case FXFT_ENCODING_APPLE_ROMAN: + return PDF_FindCode(MacRomanEncoding, unicode); + case FXFT_ENCODING_ADOBE_CUSTOM: + return PDF_FindCode(PDFDocEncoding, unicode); + case FXFT_ENCODING_MS_SYMBOL: + return PDF_FindCode(MSSymbolEncoding, unicode); + } + return 0; +} +const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding) { + switch (encoding) { + case PDFFONT_ENCODING_WINANSI: + return AdobeWinAnsiEncoding; + case PDFFONT_ENCODING_MACROMAN: + return MacRomanEncoding; + case PDFFONT_ENCODING_MACEXPERT: + return MacExpertEncoding; + case PDFFONT_ENCODING_STANDARD: + return StandardEncoding; + case PDFFONT_ENCODING_ADOBE_SYMBOL: + return AdobeSymbolEncoding; + case PDFFONT_ENCODING_ZAPFDINGBATS: + return ZapfEncoding; + case PDFFONT_ENCODING_PDFDOC: + return PDFDocEncoding; + case PDFFONT_ENCODING_MS_SYMBOL: + return MSSymbolEncoding; + } + return nullptr; +} + +FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name) { + return (FX_WCHAR)(FXFT_unicode_from_adobe_name(name) & 0x7FFFFFFF); +} + +CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode) { + char glyph_name[64]; + FXFT_adobe_name_from_unicode(glyph_name, unicode); + return CFX_ByteString(glyph_name); +} + +const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding, + uint8_t charcode) { + if (encoding == PDFFONT_ENCODING_PDFDOC) { + if (charcode < 24) + return nullptr; + + charcode -= 24; + } else { + if (charcode < 32) + return nullptr; + + charcode -= 32; + } + switch (encoding) { + case PDFFONT_ENCODING_WINANSI: + return AdobeWinAnsiEncodingNames[charcode]; + case PDFFONT_ENCODING_MACROMAN: + return MacRomanEncodingNames[charcode]; + case PDFFONT_ENCODING_MACEXPERT: + return MacExpertEncodingNames[charcode]; + case PDFFONT_ENCODING_STANDARD: + return StandardEncodingNames[charcode]; + case PDFFONT_ENCODING_ADOBE_SYMBOL: + return AdobeSymbolEncodingNames[charcode]; + case PDFFONT_ENCODING_ZAPFDINGBATS: + return ZapfEncodingNames[charcode]; + case PDFFONT_ENCODING_PDFDOC: + return PDFDocEncodingNames[charcode]; + } + return nullptr; +} + +FX_WCHAR FT_UnicodeFromCharCode(int encoding, uint32_t charcode) { + switch (encoding) { + case FXFT_ENCODING_UNICODE: + return (uint16_t)charcode; + case FXFT_ENCODING_ADOBE_STANDARD: + return StandardEncoding[(uint8_t)charcode]; + case FXFT_ENCODING_ADOBE_EXPERT: + return MacExpertEncoding[(uint8_t)charcode]; + case FXFT_ENCODING_ADOBE_LATIN_1: + return AdobeWinAnsiEncoding[(uint8_t)charcode]; + case FXFT_ENCODING_APPLE_ROMAN: + return MacRomanEncoding[(uint8_t)charcode]; + case PDFFONT_ENCODING_PDFDOC: + return PDFDocEncoding[(uint8_t)charcode]; + } + return 0; +} diff --git a/core/fpdfapi/font/cpdf_fontencoding.h b/core/fpdfapi/font/cpdf_fontencoding.h new file mode 100644 index 0000000000..a81035c825 --- /dev/null +++ b/core/fpdfapi/font/cpdf_fontencoding.h @@ -0,0 +1,61 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_FONTENCODING_H_ +#define CORE_FPDFAPI_FONT_CPDF_FONTENCODING_H_ + +#include "core/fxcrt/cfx_string_pool_template.h" +#include "core/fxcrt/cfx_weak_ptr.h" +#include "core/fxcrt/fx_string.h" + +#define PDFFONT_ENCODING_BUILTIN 0 +#define PDFFONT_ENCODING_WINANSI 1 +#define PDFFONT_ENCODING_MACROMAN 2 +#define PDFFONT_ENCODING_MACEXPERT 3 +#define PDFFONT_ENCODING_STANDARD 4 +#define PDFFONT_ENCODING_ADOBE_SYMBOL 5 +#define PDFFONT_ENCODING_ZAPFDINGBATS 6 +#define PDFFONT_ENCODING_PDFDOC 7 +#define PDFFONT_ENCODING_MS_SYMBOL 8 +#define PDFFONT_ENCODING_UNICODE 9 + +uint32_t FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode); +FX_WCHAR FT_UnicodeFromCharCode(int encoding, uint32_t charcode); + +FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name); +CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode); + +const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding); +const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding, + uint8_t charcode); + +class CPDF_Object; + +class CPDF_FontEncoding { + public: + CPDF_FontEncoding(); + explicit CPDF_FontEncoding(int PredefinedEncoding); + + void LoadEncoding(CPDF_Object* pEncoding); + + FX_BOOL IsIdentical(CPDF_FontEncoding* pAnother) const; + + FX_WCHAR UnicodeFromCharCode(uint8_t charcode) const { + return m_Unicodes[charcode]; + } + int CharCodeFromUnicode(FX_WCHAR unicode) const; + + void SetUnicode(uint8_t charcode, FX_WCHAR unicode) { + m_Unicodes[charcode] = unicode; + } + + CPDF_Object* Realize(CFX_WeakPtr pPool); + + public: + FX_WCHAR m_Unicodes[256]; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_FONTENCODING_H_ diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp new file mode 100644 index 0000000000..b596cf0036 --- /dev/null +++ b/core/fpdfapi/font/cpdf_simplefont.cpp @@ -0,0 +1,216 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_simplefont.h" + +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fxge/fx_freetype.h" +#include "third_party/base/numerics/safe_math.h" + +CPDF_SimpleFont::CPDF_SimpleFont() : m_BaseEncoding(PDFFONT_ENCODING_BUILTIN) { + FXSYS_memset(m_CharWidth, 0xff, sizeof(m_CharWidth)); + FXSYS_memset(m_GlyphIndex, 0xff, sizeof(m_GlyphIndex)); + FXSYS_memset(m_ExtGID, 0xff, sizeof(m_ExtGID)); + for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i) + m_CharBBox[i] = FX_RECT(-1, -1, -1, -1); +} + +CPDF_SimpleFont::~CPDF_SimpleFont() {} + +int CPDF_SimpleFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { + if (pVertGlyph) + *pVertGlyph = false; + + if (charcode > 0xff) + return -1; + + int index = m_GlyphIndex[(uint8_t)charcode]; + return index != 0xffff ? index : -1; +} + +void CPDF_SimpleFont::LoadCharMetrics(int charcode) { + if (!m_Font.GetFace()) + return; + + if (charcode < 0 || charcode > 0xff) { + return; + } + int glyph_index = m_GlyphIndex[charcode]; + if (glyph_index == 0xffff) { + if (!m_pFontFile && charcode != 32) { + LoadCharMetrics(32); + m_CharBBox[charcode] = m_CharBBox[32]; + if (m_bUseFontWidth) { + m_CharWidth[charcode] = m_CharWidth[32]; + } + } + return; + } + FXFT_Face face = m_Font.GetFace(); + int err = FXFT_Load_Glyph( + face, glyph_index, + FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); + if (err) + return; + + int iHoriBearingX = FXFT_Get_Glyph_HoriBearingX(face); + int iHoriBearingY = FXFT_Get_Glyph_HoriBearingY(face); + m_CharBBox[charcode] = + FX_RECT(TT2PDF(iHoriBearingX, face), TT2PDF(iHoriBearingY, face), + TT2PDF(iHoriBearingX + FXFT_Get_Glyph_Width(face), face), + TT2PDF(iHoriBearingY - FXFT_Get_Glyph_Height(face), face)); + + if (m_bUseFontWidth) { + int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face); + if (m_CharWidth[charcode] == 0xffff) { + m_CharWidth[charcode] = TT_Width; + } else if (TT_Width && !IsEmbedded()) { + m_CharBBox[charcode].right = + m_CharBBox[charcode].right * m_CharWidth[charcode] / TT_Width; + m_CharBBox[charcode].left = + m_CharBBox[charcode].left * m_CharWidth[charcode] / TT_Width; + } + } +} + +int CPDF_SimpleFont::GetCharWidthF(uint32_t charcode) { + if (charcode > 0xff) + charcode = 0; + + if (m_CharWidth[charcode] == 0xffff) { + LoadCharMetrics(charcode); + if (m_CharWidth[charcode] == 0xffff) { + m_CharWidth[charcode] = 0; + } + } + return m_CharWidth[charcode]; +} + +FX_RECT CPDF_SimpleFont::GetCharBBox(uint32_t charcode) { + if (charcode > 0xff) + charcode = 0; + + if (m_CharBBox[charcode].left == -1) + LoadCharMetrics(charcode); + + return m_CharBBox[charcode]; +} + +bool CPDF_SimpleFont::LoadCommon() { + CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); + if (pFontDesc) { + LoadFontDescriptor(pFontDesc); + } + CPDF_Array* pWidthArray = m_pFontDict->GetArrayFor("Widths"); + m_bUseFontWidth = !pWidthArray; + if (pWidthArray) { + if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) { + int MissingWidth = pFontDesc->GetIntegerFor("MissingWidth"); + for (int i = 0; i < 256; i++) { + m_CharWidth[i] = MissingWidth; + } + } + size_t width_start = m_pFontDict->GetIntegerFor("FirstChar", 0); + size_t width_end = m_pFontDict->GetIntegerFor("LastChar", 0); + if (width_start <= 255) { + if (width_end == 0 || width_end >= width_start + pWidthArray->GetCount()) + width_end = width_start + pWidthArray->GetCount() - 1; + if (width_end > 255) + width_end = 255; + for (size_t i = width_start; i <= width_end; i++) + m_CharWidth[i] = pWidthArray->GetIntegerAt(i - width_start); + } + } + if (m_pFontFile) { + if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { + m_BaseFont = m_BaseFont.Mid(8); + } + } else { + LoadSubstFont(); + } + if (!(m_Flags & PDFFONT_SYMBOLIC)) { + m_BaseEncoding = PDFFONT_ENCODING_STANDARD; + } + CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); + LoadPDFEncoding(pEncoding, m_BaseEncoding, &m_CharNames, !!m_pFontFile, + m_Font.IsTTFont()); + LoadGlyphMap(); + m_CharNames.clear(); + if (!m_Font.GetFace()) + return true; + + if (m_Flags & PDFFONT_ALLCAP) { + unsigned char kLowercases[][2] = {{'a', 'z'}, {0xe0, 0xf6}, {0xf8, 0xfd}}; + for (size_t range = 0; range < FX_ArraySize(kLowercases); ++range) { + const auto& lower = kLowercases[range]; + for (int i = lower[0]; i <= lower[1]; ++i) { + if (m_GlyphIndex[i] != 0xffff && m_pFontFile) + continue; + + int j = i - 32; + m_GlyphIndex[i] = m_GlyphIndex[j]; + if (m_CharWidth[j]) { + m_CharWidth[i] = m_CharWidth[j]; + m_CharBBox[i] = m_CharBBox[j]; + } + } + } + } + CheckFontMetrics(); + return true; +} + +void CPDF_SimpleFont::LoadSubstFont() { + if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { + int width = 0, i; + for (i = 0; i < 256; i++) { + if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { + continue; + } + if (width == 0) { + width = m_CharWidth[i]; + } else if (width != m_CharWidth[i]) { + break; + } + } + if (i == 256 && width) { + m_Flags |= PDFFONT_FIXEDPITCH; + } + } + pdfium::base::CheckedNumeric safeStemV(m_StemV); + if (m_StemV < 140) + safeStemV *= 5; + else + safeStemV = safeStemV * 4 + 140; + m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, + safeStemV.ValueOrDefault(FXFONT_FW_NORMAL), m_ItalicAngle, 0, + false); +} + +bool CPDF_SimpleFont::IsUnicodeCompatible() const { + return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && + m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && + m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS; +} + +CFX_WideString CPDF_SimpleFont::UnicodeFromCharCode(uint32_t charcode) const { + CFX_WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode); + if (!unicode.IsEmpty()) + return unicode; + FX_WCHAR ret = m_Encoding.UnicodeFromCharCode((uint8_t)charcode); + if (ret == 0) + return CFX_WideString(); + return ret; +} + +uint32_t CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const { + uint32_t ret = CPDF_Font::CharCodeFromUnicode(unicode); + if (ret) + return ret; + return m_Encoding.CharCodeFromUnicode(unicode); +} diff --git a/core/fpdfapi/font/cpdf_simplefont.h b/core/fpdfapi/font/cpdf_simplefont.h new file mode 100644 index 0000000000..592290b99b --- /dev/null +++ b/core/fpdfapi/font/cpdf_simplefont.h @@ -0,0 +1,49 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_SIMPLEFONT_H_ +#define CORE_FPDFAPI_FONT_CPDF_SIMPLEFONT_H_ + +#include + +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_fontencoding.h" +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_SimpleFont : public CPDF_Font { + public: + CPDF_SimpleFont(); + ~CPDF_SimpleFont() override; + + // CPDF_Font + int GetCharWidthF(uint32_t charcode) override; + FX_RECT GetCharBBox(uint32_t charcode) override; + int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) override; + bool IsUnicodeCompatible() const override; + CFX_WideString UnicodeFromCharCode(uint32_t charcode) const override; + uint32_t CharCodeFromUnicode(FX_WCHAR Unicode) const override; + + CPDF_FontEncoding* GetEncoding() { return &m_Encoding; } + + protected: + virtual void LoadGlyphMap() = 0; + + bool LoadCommon(); + void LoadSubstFont(); + void LoadCharMetrics(int charcode); + + CPDF_FontEncoding m_Encoding; + uint16_t m_GlyphIndex[256]; + uint16_t m_ExtGID[256]; + std::vector m_CharNames; + int m_BaseEncoding; + uint16_t m_CharWidth[256]; + FX_RECT m_CharBBox[256]; + bool m_bUseFontWidth; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_SIMPLEFONT_H_ diff --git a/core/fpdfapi/font/cpdf_truetypefont.cpp b/core/fpdfapi/font/cpdf_truetypefont.cpp new file mode 100644 index 0000000000..f3b5f2507e --- /dev/null +++ b/core/fpdfapi/font/cpdf_truetypefont.cpp @@ -0,0 +1,223 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_truetypefont.h" + +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fxge/fx_font.h" + +namespace { + +const uint8_t kPrefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; + +} // namespace + +CPDF_TrueTypeFont::CPDF_TrueTypeFont() {} + +bool CPDF_TrueTypeFont::IsTrueTypeFont() const { + return true; +} + +const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const { + return this; +} + +CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() { + return this; +} + +bool CPDF_TrueTypeFont::Load() { + return LoadCommon(); +} + +void CPDF_TrueTypeFont::LoadGlyphMap() { + if (!m_Font.GetFace()) + return; + + int baseEncoding = m_BaseEncoding; + if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 && + (baseEncoding == PDFFONT_ENCODING_MACROMAN || + baseEncoding == PDFFONT_ENCODING_WINANSI) && + (m_Flags & PDFFONT_SYMBOLIC)) { + FX_BOOL bSupportWin = FALSE; + FX_BOOL bSupportMac = FALSE; + for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) { + int platform_id = FXFT_Get_Charmap_PlatformID( + FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]); + if (platform_id == 0 || platform_id == 3) { + bSupportWin = TRUE; + } else if (platform_id == 0 || platform_id == 1) { + bSupportMac = TRUE; + } + } + if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { + baseEncoding = + bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; + } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { + baseEncoding = + bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; + } + } + if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || + baseEncoding == PDFFONT_ENCODING_WINANSI) && + m_CharNames.empty()) || + (m_Flags & PDFFONT_NONSYMBOLIC)) { + if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && + (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { + int nStartChar = m_pFontDict->GetIntegerFor("FirstChar"); + if (nStartChar < 0 || nStartChar > 255) + return; + + int charcode = 0; + for (; charcode < nStartChar; charcode++) { + m_GlyphIndex[charcode] = 0; + } + uint16_t nGlyph = charcode - nStartChar + 3; + for (; charcode < 256; charcode++, nGlyph++) { + m_GlyphIndex[charcode] = nGlyph; + } + return; + } + bool bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); + bool bMacRoman = false; + bool bMSSymbol = false; + if (!bMSUnicode) { + if (m_Flags & PDFFONT_NONSYMBOLIC) { + bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); + bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); + } else { + bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0); + bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0); + } + } + FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode"); + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(baseEncoding, m_CharNames, charcode); + if (!name) { + m_GlyphIndex[charcode] = + m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1; + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + if (bMSSymbol) { + for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { + uint16_t unicode = kPrefix[j] * 256 + charcode; + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), unicode); + if (m_GlyphIndex[charcode]) { + break; + } + } + } else if (m_Encoding.m_Unicodes[charcode]) { + if (bMSUnicode) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index( + m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); + } else if (bMacRoman) { + uint32_t maccode = FT_CharCodeFromUnicode( + FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); + if (!maccode) { + m_GlyphIndex[charcode] = + FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); + } else { + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), maccode); + } + } + } + if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && + name) { + if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32); + } else { + m_GlyphIndex[charcode] = + FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); + if (m_GlyphIndex[charcode] == 0) { + if (bToUnicode) { + CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); + if (!wsUnicode.IsEmpty()) { + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]); + m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; + } + } + if (m_GlyphIndex[charcode] == 0) { + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), charcode); + } + } + } + } + } + return; + } + if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { + bool bFound = false; + for (int charcode = 0; charcode < 256; charcode++) { + for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { + uint16_t unicode = kPrefix[j] * 256 + charcode; + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); + if (m_GlyphIndex[charcode]) { + bFound = true; + break; + } + } + } + if (bFound) { + if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(baseEncoding, m_CharNames, charcode); + if (name) + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + } + } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { + for (int charcode = 0; charcode < 256; charcode++) { + m_Encoding.m_Unicodes[charcode] = + FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); + } + } + return; + } + } + if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { + bool bFound = false; + for (int charcode = 0; charcode < 256; charcode++) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); + m_Encoding.m_Unicodes[charcode] = + FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); + if (m_GlyphIndex[charcode]) { + bFound = true; + } + } + if (m_pFontFile || bFound) + return; + } + if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { + bool bFound = false; + const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); + for (int charcode = 0; charcode < 256; charcode++) { + if (m_pFontFile) { + m_Encoding.m_Unicodes[charcode] = charcode; + } else { + const FX_CHAR* name = GetAdobeCharName(0, m_CharNames, charcode); + if (name) + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + else if (pUnicodes) + m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; + } + m_GlyphIndex[charcode] = FXFT_Get_Char_Index( + m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); + if (m_GlyphIndex[charcode]) + bFound = true; + } + if (bFound) + return; + } + for (int charcode = 0; charcode < 256; charcode++) + m_GlyphIndex[charcode] = charcode; +} diff --git a/core/fpdfapi/font/cpdf_truetypefont.h b/core/fpdfapi/font/cpdf_truetypefont.h new file mode 100644 index 0000000000..6a5e0fc83e --- /dev/null +++ b/core/fpdfapi/font/cpdf_truetypefont.h @@ -0,0 +1,30 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_TRUETYPEFONT_H_ +#define CORE_FPDFAPI_FONT_CPDF_TRUETYPEFONT_H_ + +#include "core/fpdfapi/font/cpdf_simplefont.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_TrueTypeFont : public CPDF_SimpleFont { + public: + CPDF_TrueTypeFont(); + + // CPDF_Font: + bool IsTrueTypeFont() const override; + const CPDF_TrueTypeFont* AsTrueTypeFont() const override; + CPDF_TrueTypeFont* AsTrueTypeFont() override; + + protected: + // CPDF_Font: + bool Load() override; + + // CPDF_SimpleFont: + void LoadGlyphMap() override; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_TRUETYPEFONT_H_ diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp new file mode 100644 index 0000000000..7848af5dee --- /dev/null +++ b/core/fpdfapi/font/cpdf_type1font.cpp @@ -0,0 +1,398 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_type1font.h" + +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fxge/cfx_gemodule.h" +#include "core/fxge/fx_freetype.h" + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +#include "core/fxge/apple/apple_int.h" +#endif + +namespace { + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ +struct GlyphNameMap { + const FX_CHAR* m_pStrAdobe; + const FX_CHAR* m_pStrUnicode; +}; + +const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"}, + {"ffi", "uniFB03"}, + {"ffl", "uniFB04"}, + {"fi", "uniFB01"}, + {"fl", "uniFB02"}}; + +int compareString(const void* key, const void* element) { + return FXSYS_stricmp(static_cast(key), + static_cast(element)->m_pStrAdobe); +} + +const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) { + const GlyphNameMap* found = static_cast(FXSYS_bsearch( + pStrAdobe, g_GlyphNameSubsts, FX_ArraySize(g_GlyphNameSubsts), + sizeof(GlyphNameMap), compareString)); + return found ? found->m_pStrUnicode : nullptr; +} + +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + +FX_BOOL FT_UseType1Charmap(FXFT_Face face) { + if (FXFT_Get_Face_CharmapCount(face) == 0) { + return FALSE; + } + if (FXFT_Get_Face_CharmapCount(face) == 1 && + FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == + FXFT_ENCODING_UNICODE) { + return FALSE; + } + if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == + FXFT_ENCODING_UNICODE) { + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); + } else { + FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); + } + return TRUE; +} + +} // namespace + +CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {} + +bool CPDF_Type1Font::IsType1Font() const { + return true; +} + +const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const { + return this; +} + +CPDF_Type1Font* CPDF_Type1Font::AsType1Font() { + return this; +} + +bool CPDF_Type1Font::Load() { + m_Base14Font = PDF_GetStandardFontName(&m_BaseFont); + if (m_Base14Font >= 0) { + CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); + if (pFontDesc && pFontDesc->KeyExist("Flags")) + m_Flags = pFontDesc->GetIntegerFor("Flags"); + else + m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC; + + if (m_Base14Font < 4) { + for (int i = 0; i < 256; i++) + m_CharWidth[i] = 600; + } + if (m_Base14Font == 12) + m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; + else if (m_Base14Font == 13) + m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; + else if (m_Flags & PDFFONT_NONSYMBOLIC) + m_BaseEncoding = PDFFONT_ENCODING_STANDARD; + } + return LoadCommon(); +} + +int CPDF_Type1Font::GlyphFromCharCodeExt(uint32_t charcode) { + if (charcode > 0xff) { + return -1; + } + int index = m_ExtGID[(uint8_t)charcode]; + if (index == 0xffff) { + return -1; + } + return index; +} + +void CPDF_Type1Font::LoadGlyphMap() { + if (!m_Font.GetFace()) + return; + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + bool bCoreText = true; + CQuartz2D& quartz2d = + static_cast(CFX_GEModule::Get()->GetPlatformData()) + ->m_quartz2d; + if (!m_Font.GetPlatformFont()) { + if (m_Font.GetPsName() == "DFHeiStd-W5") + bCoreText = false; + + m_Font.SetPlatformFont( + quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize())); + if (!m_Font.GetPlatformFont()) + bCoreText = false; + } +#endif + if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { + if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { + FX_BOOL bGotOne = FALSE; + for (int charcode = 0; charcode < 256; charcode++) { + const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; + for (int j = 0; j < 4; j++) { + uint16_t unicode = prefix[j] * 256 + charcode; + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), unicode); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], + name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } +#endif + if (m_GlyphIndex[charcode]) { + bGotOne = TRUE; + break; + } + } + } + if (bGotOne) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) + FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); +#endif + return; + } + } + FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); + if (m_BaseEncoding == 0) { + m_BaseEncoding = PDFFONT_ENCODING_STANDARD; + } + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); + if (!name) + continue; + + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = FXFT_Get_Char_Index( + m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph, + 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } +#endif + if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) { + m_Encoding.m_Unicodes[charcode] = 0x20; + m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], + name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } +#endif + } + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) + FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); +#endif + return; + } + FT_UseType1Charmap(m_Font.GetFace()); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (bCoreText) { + if (m_Flags & PDFFONT_SYMBOLIC) { + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); + if (name) { + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = + FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } else { + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), charcode); + FX_WCHAR unicode = 0; + if (m_GlyphIndex[charcode]) { + unicode = + FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); + } + FX_CHAR name_glyph[256]; + FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], + name_glyph, 256); + name_glyph[255] = 0; + if (unicode == 0 && name_glyph[0] != 0) { + unicode = PDF_UnicodeFromAdobeName(name_glyph); + } + m_Encoding.m_Unicodes[charcode] = unicode; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } + } + return; + } + FX_BOOL bUnicode = FALSE; + if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { + bUnicode = TRUE; + } + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); + if (!name) { + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + const FX_CHAR* pStrUnicode = GlyphNameRemap(name); + if (pStrUnicode && + 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) { + name = pStrUnicode; + } + m_GlyphIndex[charcode] = + FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } + if (m_GlyphIndex[charcode] == 0) { + if (FXSYS_strcmp(name, ".notdef") != 0 && + FXSYS_strcmp(name, "space") != 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index( + m_Font.GetFace(), + bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], + name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } else { + m_Encoding.m_Unicodes[charcode] = 0x20; + m_GlyphIndex[charcode] = + bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff; + FX_CHAR name_glyph[256]; + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], + name_glyph, 256); + name_glyph[255] = 0; + CFStringRef name_ct = CFStringCreateWithCStringNoCopy( + kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, + kCFAllocatorNull); + m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( + (CGFontRef)m_Font.GetPlatformFont(), name_ct); + if (name_ct) { + CFRelease(name_ct); + } + } + } + } + return; + } +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (m_Flags & PDFFONT_SYMBOLIC) { + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); + if (name) { + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = + FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); + } else { + m_GlyphIndex[charcode] = + FXFT_Get_Char_Index(m_Font.GetFace(), charcode); + if (m_GlyphIndex[charcode]) { + FX_WCHAR unicode = + FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); + if (unicode == 0) { + FX_CHAR name_glyph[256]; + FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); + FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], + name_glyph, 256); + name_glyph[255] = 0; + if (name_glyph[0] != 0) { + unicode = PDF_UnicodeFromAdobeName(name_glyph); + } + } + m_Encoding.m_Unicodes[charcode] = unicode; + } + } + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) + FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); + +#endif + return; + } + FX_BOOL bUnicode = FALSE; + if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { + bUnicode = TRUE; + } + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); + if (!name) { + continue; + } + m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); + m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); + if (m_GlyphIndex[charcode] == 0) { + if (FXSYS_strcmp(name, ".notdef") != 0 && + FXSYS_strcmp(name, "space") != 0) { + m_GlyphIndex[charcode] = FXFT_Get_Char_Index( + m_Font.GetFace(), + bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); + } else { + m_Encoding.m_Unicodes[charcode] = 0x20; + m_GlyphIndex[charcode] = 0xffff; + } + } + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bCoreText) + FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); +#endif +} diff --git a/core/fpdfapi/font/cpdf_type1font.h b/core/fpdfapi/font/cpdf_type1font.h new file mode 100644 index 0000000000..4dc5ea0917 --- /dev/null +++ b/core/fpdfapi/font/cpdf_type1font.h @@ -0,0 +1,35 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_TYPE1FONT_H_ +#define CORE_FPDFAPI_FONT_CPDF_TYPE1FONT_H_ + +#include "core/fpdfapi/font/cpdf_simplefont.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Type1Font : public CPDF_SimpleFont { + public: + CPDF_Type1Font(); + + // CPDF_Font: + bool IsType1Font() const override; + const CPDF_Type1Font* AsType1Font() const override; + CPDF_Type1Font* AsType1Font() override; + int GlyphFromCharCodeExt(uint32_t charcode) override; + + int GetBase14Font() const { return m_Base14Font; } + + protected: + // CPDF_Font: + bool Load() override; + + // CPDF_SimpleFont: + void LoadGlyphMap() override; + + int m_Base14Font; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_TYPE1FONT_H_ diff --git a/core/fpdfapi/font/cpdf_type3char.cpp b/core/fpdfapi/font/cpdf_type3char.cpp new file mode 100644 index 0000000000..2114486dec --- /dev/null +++ b/core/fpdfapi/font/cpdf_type3char.cpp @@ -0,0 +1,38 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_type3char.h" + +#include "core/fpdfapi/fpdf_page/cpdf_form.h" +#include "core/fpdfapi/fpdf_page/cpdf_image.h" +#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" +#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" +#include "core/fxge/fx_dib.h" + +CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm) + : m_pForm(pForm), m_bColored(FALSE) {} + +CPDF_Type3Char::~CPDF_Type3Char() {} + +FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) { + if (m_pBitmap || !m_pForm) + return TRUE; + + if (m_pForm->GetPageObjectList()->size() != 1 || m_bColored) + return FALSE; + + auto& pPageObj = m_pForm->GetPageObjectList()->front(); + if (!pPageObj->IsImage()) + return FALSE; + + m_ImageMatrix = pPageObj->AsImage()->m_Matrix; + std::unique_ptr pSource( + pPageObj->AsImage()->GetImage()->LoadDIBSource()); + if (pSource) + m_pBitmap.reset(pSource->Clone()); + m_pForm.reset(); + return TRUE; +} diff --git a/core/fpdfapi/font/cpdf_type3char.h b/core/fpdfapi/font/cpdf_type3char.h new file mode 100644 index 0000000000..ebb5ed440c --- /dev/null +++ b/core/fpdfapi/font/cpdf_type3char.h @@ -0,0 +1,35 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_TYPE3CHAR_H_ +#define CORE_FPDFAPI_FONT_CPDF_TYPE3CHAR_H_ + +#include + +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CFX_DIBitmap; +class CPDF_Form; +class CPDF_RenderContext; + +class CPDF_Type3Char { + public: + // Takes ownership of |pForm|. + explicit CPDF_Type3Char(CPDF_Form* pForm); + ~CPDF_Type3Char(); + + FX_BOOL LoadBitmap(CPDF_RenderContext* pContext); + + std::unique_ptr m_pForm; + std::unique_ptr m_pBitmap; + FX_BOOL m_bColored; + int m_Width; + CFX_Matrix m_ImageMatrix; + FX_RECT m_BBox; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_TYPE3CHAR_H_ diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp new file mode 100644 index 0000000000..ae301c2e8c --- /dev/null +++ b/core/fpdfapi/font/cpdf_type3font.cpp @@ -0,0 +1,159 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/cpdf_type3font.h" + +#include + +#include "core/fpdfapi/font/cpdf_type3char.h" +#include "core/fpdfapi/fpdf_page/cpdf_form.h" +#include "core/fpdfapi/fpdf_page/pageint.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fxcrt/fx_system.h" +#include "third_party/base/stl_util.h" + +CPDF_Type3Font::CPDF_Type3Font() + : m_pCharProcs(nullptr), + m_pPageResources(nullptr), + m_pFontResources(nullptr), + m_CharLoadingDepth(0) { + FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL)); +} + +CPDF_Type3Font::~CPDF_Type3Font() {} + +bool CPDF_Type3Font::IsType3Font() const { + return true; +} + +const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const { + return this; +} + +CPDF_Type3Font* CPDF_Type3Font::AsType3Font() { + return this; +} + +bool CPDF_Type3Font::Load() { + m_pFontResources = m_pFontDict->GetDictFor("Resources"); + CPDF_Array* pMatrix = m_pFontDict->GetArrayFor("FontMatrix"); + FX_FLOAT xscale = 1.0f, yscale = 1.0f; + if (pMatrix) { + m_FontMatrix = pMatrix->GetMatrix(); + xscale = m_FontMatrix.a; + yscale = m_FontMatrix.d; + } + CPDF_Array* pBBox = m_pFontDict->GetArrayFor("FontBBox"); + if (pBBox) { + m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000); + m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000); + m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000); + m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000); + } + int StartChar = m_pFontDict->GetIntegerFor("FirstChar"); + CPDF_Array* pWidthArray = m_pFontDict->GetArrayFor("Widths"); + if (pWidthArray && (StartChar >= 0 && StartChar < 256)) { + size_t count = pWidthArray->GetCount(); + if (count > 256) + count = 256; + if (StartChar + count > 256) + count = 256 - StartChar; + for (size_t i = 0; i < count; i++) { + m_CharWidthL[StartChar + i] = + FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000); + } + } + m_pCharProcs = m_pFontDict->GetDictFor("CharProcs"); + CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); + if (pEncoding) { + LoadPDFEncoding(pEncoding, m_BaseEncoding, &m_CharNames, false, false); + if (!m_CharNames.empty()) { + for (int i = 0; i < 256; i++) { + m_Encoding.m_Unicodes[i] = + PDF_UnicodeFromAdobeName(m_CharNames[i].c_str()); + if (m_Encoding.m_Unicodes[i] == 0) { + m_Encoding.m_Unicodes[i] = i; + } + } + } + } + return true; +} + +void CPDF_Type3Font::CheckType3FontMetrics() { + CheckFontMetrics(); +} + +CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode) { + if (m_CharLoadingDepth >= _FPDF_MAX_TYPE3_FORM_LEVEL_) + return nullptr; + + auto it = m_CacheMap.find(charcode); + if (it != m_CacheMap.end()) + return it->second.get(); + + const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); + if (!name) + return nullptr; + + CPDF_Stream* pStream = + ToStream(m_pCharProcs ? m_pCharProcs->GetDirectObjectFor(name) : nullptr); + if (!pStream) + return nullptr; + + std::unique_ptr pNewChar(new CPDF_Type3Char(new CPDF_Form( + m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, + pStream, nullptr))); + + // This can trigger recursion into this method. The content of |m_CacheMap| + // can change as a result. Thus after it returns, check the cache again for + // a cache hit. + m_CharLoadingDepth++; + pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get()); + m_CharLoadingDepth--; + it = m_CacheMap.find(charcode); + if (it != m_CacheMap.end()) + return it->second.get(); + + FX_FLOAT scale = m_FontMatrix.GetXUnit(); + pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f); + FX_RECT& rcBBox = pNewChar->m_BBox; + CFX_FloatRect char_rect( + (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f, + (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f); + if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) + char_rect = pNewChar->m_pForm->CalcBoundingBox(); + + char_rect.Transform(&m_FontMatrix); + rcBBox.left = FXSYS_round(char_rect.left * 1000); + rcBBox.right = FXSYS_round(char_rect.right * 1000); + rcBBox.top = FXSYS_round(char_rect.top * 1000); + rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000); + + ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode)); + m_CacheMap[charcode] = std::move(pNewChar); + CPDF_Type3Char* pCachedChar = m_CacheMap[charcode].get(); + if (pCachedChar->m_pForm->GetPageObjectList()->empty()) + pCachedChar->m_pForm.reset(); + return pCachedChar; +} + +int CPDF_Type3Font::GetCharWidthF(uint32_t charcode) { + if (charcode >= FX_ArraySize(m_CharWidthL)) + charcode = 0; + + if (m_CharWidthL[charcode]) + return m_CharWidthL[charcode]; + + const CPDF_Type3Char* pChar = LoadChar(charcode); + return pChar ? pChar->m_Width : 0; +} + +FX_RECT CPDF_Type3Font::GetCharBBox(uint32_t charcode) { + const CPDF_Type3Char* pChar = LoadChar(charcode); + return pChar ? pChar->m_BBox : FX_RECT(); +} diff --git a/core/fpdfapi/font/cpdf_type3font.h b/core/fpdfapi/font/cpdf_type3font.h new file mode 100644 index 0000000000..0bae192d61 --- /dev/null +++ b/core/fpdfapi/font/cpdf_type3font.h @@ -0,0 +1,59 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_CPDF_TYPE3FONT_H_ +#define CORE_FPDFAPI_FONT_CPDF_TYPE3FONT_H_ + +#include +#include + +#include "core/fpdfapi/font/cpdf_simplefont.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Dictionary; +class CPDF_Type3Char; + +class CPDF_Type3Font : public CPDF_SimpleFont { + public: + CPDF_Type3Font(); + ~CPDF_Type3Font() override; + + // CPDF_Font: + bool IsType3Font() const override; + const CPDF_Type3Font* AsType3Font() const override; + CPDF_Type3Font* AsType3Font() override; + int GetCharWidthF(uint32_t charcode) override; + FX_RECT GetCharBBox(uint32_t charcode) override; + + void SetPageResources(CPDF_Dictionary* pResources) { + m_pPageResources = pResources; + } + CPDF_Type3Char* LoadChar(uint32_t charcode); + void CheckType3FontMetrics(); + + CFX_Matrix& GetFontMatrix() { return m_FontMatrix; } + + protected: + CFX_Matrix m_FontMatrix; + + private: + // CPDF_Font: + bool Load() override; + + // CPDF_SimpleFont: + void LoadGlyphMap() override {} + + int m_CharWidthL[256]; + CPDF_Dictionary* m_pCharProcs; + CPDF_Dictionary* m_pPageResources; + CPDF_Dictionary* m_pFontResources; + std::map> m_CacheMap; + // The depth char loading is in, to avoid recurive calling LoadChar(). + int m_CharLoadingDepth; +}; + +#endif // CORE_FPDFAPI_FONT_CPDF_TYPE3FONT_H_ diff --git a/core/fpdfapi/font/font_int.h b/core/fpdfapi/font/font_int.h new file mode 100644 index 0000000000..10c2dcada4 --- /dev/null +++ b/core/fpdfapi/font/font_int.h @@ -0,0 +1,204 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_FONT_INT_H_ +#define CORE_FPDFAPI_FONT_FONT_INT_H_ + +#include +#include + +#include "core/fpdfapi/font/cpdf_cidfont.h" +#include "core/fxcrt/fx_basic.h" + +class CPDF_CID2UnicodeMap; +class CPDF_CMap; +class CPDF_Font; +class CPDF_Stream; + +using FXFT_Library = void*; + +int TT2PDF(int m, FXFT_Face face); +bool FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id); +CIDSet CharsetFromOrdering(const CFX_ByteStringC& ordering); + +class CPDF_CMapManager { + public: + CPDF_CMapManager(); + ~CPDF_CMapManager(); + + CPDF_CMap* GetPredefinedCMap(const CFX_ByteString& name, bool bPromptCJK); + CPDF_CID2UnicodeMap* GetCID2UnicodeMap(CIDSet charset, bool bPromptCJK); + + private: + CPDF_CMap* LoadPredefinedCMap(const CFX_ByteString& name, bool bPromptCJK); + CPDF_CID2UnicodeMap* LoadCID2UnicodeMap(CIDSet charset, bool bPromptCJK); + + std::map m_CMaps; + CPDF_CID2UnicodeMap* m_CID2UnicodeMaps[6]; +}; + +class CFX_StockFontArray { + public: + CFX_StockFontArray(); + ~CFX_StockFontArray(); + + // Takes ownership of |pFont|, returns unowned pointer to it. + CPDF_Font* SetFont(uint32_t index, std::unique_ptr pFont); + CPDF_Font* GetFont(uint32_t index) const; + + private: + std::unique_ptr m_StockFonts[14]; +}; + +class CPDF_FontGlobals { + public: + CPDF_FontGlobals(); + ~CPDF_FontGlobals(); + + void Clear(CPDF_Document* pDoc); + CPDF_Font* Find(CPDF_Document* pDoc, uint32_t index); + + // Takes ownership of |pFont|, returns unowned pointer to it. + CPDF_Font* Set(CPDF_Document* key, + uint32_t index, + std::unique_ptr pFont); + + CPDF_CMapManager m_CMapManager; + struct { + const struct FXCMAP_CMap* m_pMapList; + uint32_t m_Count; + } m_EmbeddedCharsets[CIDSET_NUM_SETS]; + struct { + const uint16_t* m_pMap; + uint32_t m_Count; + } m_EmbeddedToUnicodes[CIDSET_NUM_SETS]; + + private: + std::map> m_StockMap; +}; + +struct CMap_CodeRange { + int m_CharSize; + uint8_t m_Lower[4]; + uint8_t m_Upper[4]; +}; + +class CPDF_CMapParser { + public: + CPDF_CMapParser(); + ~CPDF_CMapParser(); + void Initialize(CPDF_CMap* pMap); + void ParseWord(const CFX_ByteStringC& str); + CFX_BinaryBuf m_AddMaps; + + private: + friend class fpdf_font_cid_CMap_GetCode_Test; + friend class fpdf_font_cid_CMap_GetCodeRange_Test; + + static uint32_t CMap_GetCode(const CFX_ByteStringC& word); + static bool CMap_GetCodeRange(CMap_CodeRange& range, + const CFX_ByteStringC& first, + const CFX_ByteStringC& second); + + CPDF_CMap* m_pCMap; + int m_Status; + int m_CodeSeq; + uint32_t m_CodePoints[4]; + CFX_ArrayTemplate m_CodeRanges; + CFX_ByteString m_LastWord; +}; + +enum CIDCoding : uint8_t { + CIDCODING_UNKNOWN = 0, + CIDCODING_GB, + CIDCODING_BIG5, + CIDCODING_JIS, + CIDCODING_KOREA, + CIDCODING_UCS2, + CIDCODING_CID, + CIDCODING_UTF16, +}; + +class CPDF_CMap { + public: + enum CodingScheme : uint8_t { + OneByte, + TwoBytes, + MixedTwoBytes, + MixedFourBytes + }; + + CPDF_CMap(); + ~CPDF_CMap(); + + void LoadPredefined(CPDF_CMapManager* pMgr, + const CFX_ByteString& name, + bool bPromptCJK); + void LoadEmbedded(const uint8_t* pData, uint32_t dwSize); + + bool IsLoaded() const; + bool IsVertWriting() const; + uint16_t CIDFromCharCode(uint32_t charcode) const; + int GetCharSize(uint32_t charcode) const; + uint32_t GetNextChar(const FX_CHAR* pString, int nStrLen, int& offset) const; + int CountChar(const FX_CHAR* pString, int size) const; + int AppendChar(FX_CHAR* str, uint32_t charcode) const; + + private: + friend class CPDF_CMapParser; + friend class CPDF_CIDFont; + + CFX_ByteString m_PredefinedCMap; + bool m_bVertical; + CIDSet m_Charset; + int m_Coding; + CodingScheme m_CodingScheme; + int m_nCodeRanges; + uint8_t* m_pLeadingBytes; + uint16_t* m_pMapping; + uint8_t* m_pAddMapping; + bool m_bLoaded; + const FXCMAP_CMap* m_pEmbedMap; +}; + +class CPDF_CID2UnicodeMap { + public: + CPDF_CID2UnicodeMap(); + ~CPDF_CID2UnicodeMap(); + + bool IsLoaded(); + void Load(CPDF_CMapManager* pMgr, CIDSet charset, bool bPromptCJK); + FX_WCHAR UnicodeFromCID(uint16_t CID); + + private: + CIDSet m_Charset; + const uint16_t* m_pEmbeddedMap; + uint32_t m_EmbeddedCount; +}; + +class CPDF_ToUnicodeMap { + public: + CPDF_ToUnicodeMap(); + ~CPDF_ToUnicodeMap(); + + void Load(CPDF_Stream* pStream); + + CFX_WideString Lookup(uint32_t charcode) const; + uint32_t ReverseLookup(FX_WCHAR unicode) const; + + private: + friend class fpdf_font_StringToCode_Test; + friend class fpdf_font_StringToWideString_Test; + + static uint32_t StringToCode(const CFX_ByteStringC& str); + static CFX_WideString StringToWideString(const CFX_ByteStringC& str); + + std::map m_Map; + CPDF_CID2UnicodeMap* m_pBaseMap; + CFX_WideTextBuf m_MultiCharBuf; +}; + +#endif // CORE_FPDFAPI_FONT_FONT_INT_H_ diff --git a/core/fpdfapi/font/fpdf_font.cpp b/core/fpdfapi/font/fpdf_font.cpp new file mode 100644 index 0000000000..4763fe5c44 --- /dev/null +++ b/core/fpdfapi/font/fpdf_font.cpp @@ -0,0 +1,317 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/font_int.h" + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/fpdf_page/cpdf_form.h" +#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/fpdf_page/pageint.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_name.h" +#include "core/fpdfapi/fpdf_parser/cpdf_number.h" +#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fxcrt/fx_ext.h" +#include "core/fxcrt/fx_safe_types.h" +#include "core/fxge/fx_freetype.h" +#include "third_party/base/numerics/safe_conversions.h" +#include "third_party/base/stl_util.h" + +int TT2PDF(int m, FXFT_Face face) { + int upm = FXFT_Get_Face_UnitsPerEM(face); + if (upm == 0) + return m; + return pdfium::base::checked_cast( + (static_cast(m) * 1000 + upm / 2) / upm); +} + +bool FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) { + auto* pCharMap = FXFT_Get_Face_Charmaps(face); + for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { + if (FXFT_Get_Charmap_PlatformID(pCharMap[i]) == platform_id && + FXFT_Get_Charmap_EncodingID(pCharMap[i]) == encoding_id) { + FXFT_Set_Charmap(face, pCharMap[i]); + return true; + } + } + return false; +} + +CFX_StockFontArray::CFX_StockFontArray() {} + +CFX_StockFontArray::~CFX_StockFontArray() { + for (size_t i = 0; i < FX_ArraySize(m_StockFonts); ++i) { + if (!m_StockFonts[i]) + continue; + CPDF_Dictionary* pFontDict = m_StockFonts[i]->GetFontDict(); + if (pFontDict) + pFontDict->Release(); + } +} + +CPDF_Font* CFX_StockFontArray::GetFont(uint32_t index) const { + if (index >= FX_ArraySize(m_StockFonts)) + return nullptr; + return m_StockFonts[index].get(); +} + +CPDF_Font* CFX_StockFontArray::SetFont(uint32_t index, + std::unique_ptr pFont) { + CPDF_Font* result = pFont.get(); + if (index < FX_ArraySize(m_StockFonts)) + m_StockFonts[index] = std::move(pFont); + return result; +} + +CPDF_FontGlobals::CPDF_FontGlobals() { + FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets)); + FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes)); +} + +CPDF_FontGlobals::~CPDF_FontGlobals() {} + +CPDF_Font* CPDF_FontGlobals::Find(CPDF_Document* pDoc, uint32_t index) { + auto it = m_StockMap.find(pDoc); + if (it == m_StockMap.end()) + return nullptr; + return it->second ? it->second->GetFont(index) : nullptr; +} + +CPDF_Font* CPDF_FontGlobals::Set(CPDF_Document* pDoc, + uint32_t index, + std::unique_ptr pFont) { + if (!pdfium::ContainsKey(m_StockMap, pDoc)) + m_StockMap[pDoc].reset(new CFX_StockFontArray); + return m_StockMap[pDoc]->SetFont(index, std::move(pFont)); +} + +void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) { + m_StockMap.erase(pDoc); +} + +CFX_WideString CPDF_ToUnicodeMap::Lookup(uint32_t charcode) const { + auto it = m_Map.find(charcode); + if (it != m_Map.end()) { + uint32_t value = it->second; + FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); + if (unicode != 0xffff) { + return unicode; + } + const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer(); + uint32_t buf_len = m_MultiCharBuf.GetLength(); + if (!buf || buf_len == 0) { + return CFX_WideString(); + } + uint32_t index = value >> 16; + if (index >= buf_len) { + return CFX_WideString(); + } + uint32_t len = buf[index]; + if (index + len < index || index + len >= buf_len) { + return CFX_WideString(); + } + return CFX_WideString(buf + index + 1, len); + } + if (m_pBaseMap) { + return m_pBaseMap->UnicodeFromCID((uint16_t)charcode); + } + return CFX_WideString(); +} + +uint32_t CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) const { + for (const auto& pair : m_Map) { + if (pair.second == static_cast(unicode)) + return pair.first; + } + return 0; +} + +// Static. +uint32_t CPDF_ToUnicodeMap::StringToCode(const CFX_ByteStringC& str) { + int len = str.GetLength(); + if (len == 0) + return 0; + + uint32_t result = 0; + if (str[0] == '<') { + for (int i = 1; i < len && std::isxdigit(str[i]); ++i) + result = result * 16 + FXSYS_toHexDigit(str.CharAt(i)); + return result; + } + + for (int i = 0; i < len && std::isdigit(str[i]); ++i) + result = result * 10 + FXSYS_toDecimalDigit(str.CharAt(i)); + + return result; +} + +static CFX_WideString StringDataAdd(CFX_WideString str) { + CFX_WideString ret; + int len = str.GetLength(); + FX_WCHAR value = 1; + for (int i = len - 1; i >= 0; --i) { + FX_WCHAR ch = str[i] + value; + if (ch < str[i]) { + ret.Insert(0, 0); + } else { + ret.Insert(0, ch); + value = 0; + } + } + if (value) { + ret.Insert(0, value); + } + return ret; +} + +// Static. +CFX_WideString CPDF_ToUnicodeMap::StringToWideString( + const CFX_ByteStringC& str) { + int len = str.GetLength(); + if (len == 0) + return CFX_WideString(); + + CFX_WideString result; + if (str[0] == '<') { + int byte_pos = 0; + FX_WCHAR ch = 0; + for (int i = 1; i < len && std::isxdigit(str[i]); ++i) { + ch = ch * 16 + FXSYS_toHexDigit(str[i]); + byte_pos++; + if (byte_pos == 4) { + result += ch; + byte_pos = 0; + ch = 0; + } + } + return result; + } + return result; +} + +CPDF_ToUnicodeMap::CPDF_ToUnicodeMap() : m_pBaseMap(nullptr) {} + +CPDF_ToUnicodeMap::~CPDF_ToUnicodeMap() {} + +void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) { + CIDSet cid_set = CIDSET_UNKNOWN; + CPDF_StreamAcc stream; + stream.LoadAllData(pStream, FALSE); + CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); + while (1) { + CFX_ByteStringC word = parser.GetWord(); + if (word.IsEmpty()) { + break; + } + if (word == "beginbfchar") { + while (1) { + word = parser.GetWord(); + if (word.IsEmpty() || word == "endbfchar") { + break; + } + uint32_t srccode = StringToCode(word); + word = parser.GetWord(); + CFX_WideString destcode = StringToWideString(word); + int len = destcode.GetLength(); + if (len == 0) { + continue; + } + if (len == 1) { + m_Map[srccode] = destcode.GetAt(0); + } else { + FX_SAFE_UINT32 uni = m_MultiCharBuf.GetLength(); + uni *= 0x10000; + uni += 0xffff; + m_Map[srccode] = uni.ValueOrDie(); + m_MultiCharBuf.AppendChar(destcode.GetLength()); + m_MultiCharBuf << destcode; + } + } + } else if (word == "beginbfrange") { + while (1) { + CFX_ByteString low, high; + low = parser.GetWord(); + if (low.IsEmpty() || low == "endbfrange") { + break; + } + high = parser.GetWord(); + uint32_t lowcode = StringToCode(low.AsStringC()); + uint32_t highcode = + (lowcode & 0xffffff00) | (StringToCode(high.AsStringC()) & 0xff); + if (highcode == (uint32_t)-1) { + break; + } + CFX_ByteString start(parser.GetWord()); + if (start == "[") { + for (uint32_t code = lowcode; code <= highcode; code++) { + CFX_ByteString dest(parser.GetWord()); + CFX_WideString destcode = StringToWideString(dest.AsStringC()); + int len = destcode.GetLength(); + if (len == 0) { + continue; + } + if (len == 1) { + m_Map[code] = destcode.GetAt(0); + } else { + FX_SAFE_UINT32 uni = m_MultiCharBuf.GetLength(); + uni *= 0x10000; + uni += 0xffff; + m_Map[code] = uni.ValueOrDie(); + m_MultiCharBuf.AppendChar(destcode.GetLength()); + m_MultiCharBuf << destcode; + } + } + parser.GetWord(); + } else { + CFX_WideString destcode = StringToWideString(start.AsStringC()); + int len = destcode.GetLength(); + uint32_t value = 0; + if (len == 1) { + value = StringToCode(start.AsStringC()); + for (uint32_t code = lowcode; code <= highcode; code++) { + m_Map[code] = value++; + } + } else { + for (uint32_t code = lowcode; code <= highcode; code++) { + CFX_WideString retcode; + if (code == lowcode) { + retcode = destcode; + } else { + retcode = StringDataAdd(destcode); + } + FX_SAFE_UINT32 uni = m_MultiCharBuf.GetLength(); + uni *= 0x10000; + uni += 0xffff; + m_Map[code] = uni.ValueOrDie(); + m_MultiCharBuf.AppendChar(retcode.GetLength()); + m_MultiCharBuf << retcode; + destcode = retcode; + } + } + } + } + } else if (word == "/Adobe-Korea1-UCS2") { + cid_set = CIDSET_KOREA1; + } else if (word == "/Adobe-Japan1-UCS2") { + cid_set = CIDSET_JAPAN1; + } else if (word == "/Adobe-CNS1-UCS2") { + cid_set = CIDSET_CNS1; + } else if (word == "/Adobe-GB1-UCS2") { + cid_set = CIDSET_GB1; + } + } + if (cid_set) { + m_pBaseMap = CPDF_ModuleMgr::Get() + ->GetPageModule() + ->GetFontGlobals() + ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE); + } else { + m_pBaseMap = nullptr; + } +} diff --git a/core/fpdfapi/font/fpdf_font_cid.cpp b/core/fpdfapi/font/fpdf_font_cid.cpp new file mode 100644 index 0000000000..1d8052bc29 --- /dev/null +++ b/core/fpdfapi/font/fpdf_font_cid.cpp @@ -0,0 +1,783 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/font/font_int.h" + +#include "core/fpdfapi/cmaps/cmap_int.h" +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/ttgsubtable.h" +#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" +#include "core/fxcrt/fx_ext.h" +#include "core/fxge/fx_freetype.h" + +namespace { + +const FX_CHAR* const g_CharsetNames[CIDSET_NUM_SETS] = { + nullptr, "GB1", "CNS1", "Japan1", "Korea1", "UCS"}; + +class CPDF_PredefinedCMap { + public: + const FX_CHAR* m_pName; + CIDSet m_Charset; + CIDCoding m_Coding; + CPDF_CMap::CodingScheme m_CodingScheme; + uint8_t m_LeadingSegCount; + uint8_t m_LeadingSegs[4]; +}; + +const CPDF_PredefinedCMap g_PredefinedCMaps[] = { + {"GB-EUC", + CIDSET_GB1, + CIDCODING_GB, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfe}}, + {"GBpc-EUC", + CIDSET_GB1, + CIDCODING_GB, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfc}}, + {"GBK-EUC", + CIDSET_GB1, + CIDCODING_GB, + CPDF_CMap::MixedTwoBytes, + 1, + {0x81, 0xfe}}, + {"GBKp-EUC", + CIDSET_GB1, + CIDCODING_GB, + CPDF_CMap::MixedTwoBytes, + 1, + {0x81, 0xfe}}, + {"GBK2K-EUC", + CIDSET_GB1, + CIDCODING_GB, + CPDF_CMap::MixedTwoBytes, + 1, + {0x81, 0xfe}}, + {"GBK2K", + CIDSET_GB1, + CIDCODING_GB, + CPDF_CMap::MixedTwoBytes, + 1, + {0x81, 0xfe}}, + {"UniGB-UCS2", CIDSET_GB1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, + {"UniGB-UTF16", CIDSET_GB1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, + {"B5pc", + CIDSET_CNS1, + CIDCODING_BIG5, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfc}}, + {"HKscs-B5", + CIDSET_CNS1, + CIDCODING_BIG5, + CPDF_CMap::MixedTwoBytes, + 1, + {0x88, 0xfe}}, + {"ETen-B5", + CIDSET_CNS1, + CIDCODING_BIG5, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfe}}, + {"ETenms-B5", + CIDSET_CNS1, + CIDCODING_BIG5, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfe}}, + {"UniCNS-UCS2", CIDSET_CNS1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, + {"UniCNS-UTF16", CIDSET_CNS1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, + {"83pv-RKSJ", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x81, 0x9f, 0xe0, 0xfc}}, + {"90ms-RKSJ", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x81, 0x9f, 0xe0, 0xfc}}, + {"90msp-RKSJ", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x81, 0x9f, 0xe0, 0xfc}}, + {"90pv-RKSJ", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x81, 0x9f, 0xe0, 0xfc}}, + {"Add-RKSJ", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x81, 0x9f, 0xe0, 0xfc}}, + {"EUC", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x8e, 0x8e, 0xa1, 0xfe}}, + {"H", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}}, + {"V", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}}, + {"Ext-RKSJ", + CIDSET_JAPAN1, + CIDCODING_JIS, + CPDF_CMap::MixedTwoBytes, + 2, + {0x81, 0x9f, 0xe0, 0xfc}}, + {"UniJIS-UCS2", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, + {"UniJIS-UCS2-HW", + CIDSET_JAPAN1, + CIDCODING_UCS2, + CPDF_CMap::TwoBytes, + 0, + {}}, + {"UniJIS-UTF16", + CIDSET_JAPAN1, + CIDCODING_UTF16, + CPDF_CMap::TwoBytes, + 0, + {}}, + {"KSC-EUC", + CIDSET_KOREA1, + CIDCODING_KOREA, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfe}}, + {"KSCms-UHC", + CIDSET_KOREA1, + CIDCODING_KOREA, + CPDF_CMap::MixedTwoBytes, + 1, + {0x81, 0xfe}}, + {"KSCms-UHC-HW", + CIDSET_KOREA1, + CIDCODING_KOREA, + CPDF_CMap::MixedTwoBytes, + 1, + {0x81, 0xfe}}, + {"KSCpc-EUC", + CIDSET_KOREA1, + CIDCODING_KOREA, + CPDF_CMap::MixedTwoBytes, + 1, + {0xa1, 0xfd}}, + {"UniKS-UCS2", CIDSET_KOREA1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, + {"UniKS-UTF16", CIDSET_KOREA1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, +}; + +CIDSet CIDSetFromSizeT(size_t index) { + if (index >= CIDSET_NUM_SETS) { + NOTREACHED(); + return CIDSET_UNKNOWN; + } + return static_cast(index); +} + +CFX_ByteStringC CMap_GetString(const CFX_ByteStringC& word) { + if (word.GetLength() <= 2) + return CFX_ByteStringC(); + return CFX_ByteStringC(&word[1], word.GetLength() - 2); +} + +int CompareDWORD(const void* data1, const void* data2) { + return (*(uint32_t*)data1) - (*(uint32_t*)data2); +} + +int CompareCID(const void* key, const void* element) { + if ((*(uint32_t*)key) < (*(uint32_t*)element)) { + return -1; + } + if ((*(uint32_t*)key) > + (*(uint32_t*)element) + ((uint32_t*)element)[1] / 65536) { + return 1; + } + return 0; +} + +int CheckCodeRange(uint8_t* codes, + int size, + CMap_CodeRange* pRanges, + int nRanges) { + int iSeg = nRanges - 1; + while (iSeg >= 0) { + if (pRanges[iSeg].m_CharSize < size) { + --iSeg; + continue; + } + int iChar = 0; + while (iChar < size) { + if (codes[iChar] < pRanges[iSeg].m_Lower[iChar] || + codes[iChar] > pRanges[iSeg].m_Upper[iChar]) { + break; + } + ++iChar; + } + if (iChar == pRanges[iSeg].m_CharSize) + return 2; + + if (iChar) + return (size == pRanges[iSeg].m_CharSize) ? 2 : 1; + iSeg--; + } + return 0; +} + +int GetCharSizeImpl(uint32_t charcode, + CMap_CodeRange* pRanges, + int iRangesSize) { + if (!iRangesSize) + return 1; + + uint8_t codes[4]; + codes[0] = codes[1] = 0x00; + codes[2] = (uint8_t)(charcode >> 8 & 0xFF); + codes[3] = (uint8_t)charcode; + int offset = 0; + int size = 4; + for (int i = 0; i < 4; ++i) { + int iSeg = iRangesSize - 1; + while (iSeg >= 0) { + if (pRanges[iSeg].m_CharSize < size) { + --iSeg; + continue; + } + int iChar = 0; + while (iChar < size) { + if (codes[offset + iChar] < pRanges[iSeg].m_Lower[iChar] || + codes[offset + iChar] > pRanges[iSeg].m_Upper[iChar]) { + break; + } + ++iChar; + } + if (iChar == pRanges[iSeg].m_CharSize) + return size; + --iSeg; + } + --size; + ++offset; + } + return 1; +} + +} // namespace + +CPDF_CMapManager::CPDF_CMapManager() { + FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps); +} +CPDF_CMapManager::~CPDF_CMapManager() { + for (const auto& pair : m_CMaps) { + delete pair.second; + } + m_CMaps.clear(); + for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) { + delete m_CID2UnicodeMaps[i]; + } +} +CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name, + bool bPromptCJK) { + auto it = m_CMaps.find(name); + if (it != m_CMaps.end()) { + return it->second; + } + CPDF_CMap* pCMap = LoadPredefinedCMap(name, bPromptCJK); + if (!name.IsEmpty()) { + m_CMaps[name] = pCMap; + } + return pCMap; +} +CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name, + bool bPromptCJK) { + CPDF_CMap* pCMap = new CPDF_CMap; + const FX_CHAR* pname = name.c_str(); + if (*pname == '/') { + pname++; + } + pCMap->LoadPredefined(this, pname, bPromptCJK); + return pCMap; +} + +CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(CIDSet charset, + bool bPromptCJK) { + if (!m_CID2UnicodeMaps[charset]) + m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK); + return m_CID2UnicodeMaps[charset]; +} +CPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(CIDSet charset, + bool bPromptCJK) { + CPDF_CID2UnicodeMap* pMap = new CPDF_CID2UnicodeMap(); + pMap->Load(this, charset, bPromptCJK); + return pMap; +} + +CPDF_CMapParser::CPDF_CMapParser() + : m_pCMap(nullptr), m_Status(0), m_CodeSeq(0) {} + +CPDF_CMapParser::~CPDF_CMapParser() {} + +void CPDF_CMapParser::Initialize(CPDF_CMap* pCMap) { + m_pCMap = pCMap; + m_Status = 0; + m_CodeSeq = 0; + m_AddMaps.EstimateSize(0, 10240); +} + +void CPDF_CMapParser::ParseWord(const CFX_ByteStringC& word) { + if (word.IsEmpty()) { + return; + } + if (word == "begincidchar") { + m_Status = 1; + m_CodeSeq = 0; + } else if (word == "begincidrange") { + m_Status = 2; + m_CodeSeq = 0; + } else if (word == "endcidrange" || word == "endcidchar") { + m_Status = 0; + } else if (word == "/WMode") { + m_Status = 6; + } else if (word == "/Registry") { + m_Status = 3; + } else if (word == "/Ordering") { + m_Status = 4; + } else if (word == "/Supplement") { + m_Status = 5; + } else if (word == "begincodespacerange") { + m_Status = 7; + m_CodeSeq = 0; + } else if (word == "usecmap") { + } else if (m_Status == 1 || m_Status == 2) { + m_CodePoints[m_CodeSeq] = CMap_GetCode(word); + m_CodeSeq++; + uint32_t StartCode, EndCode; + uint16_t StartCID; + if (m_Status == 1) { + if (m_CodeSeq < 2) { + return; + } + EndCode = StartCode = m_CodePoints[0]; + StartCID = (uint16_t)m_CodePoints[1]; + } else { + if (m_CodeSeq < 3) { + return; + } + StartCode = m_CodePoints[0]; + EndCode = m_CodePoints[1]; + StartCID = (uint16_t)m_CodePoints[2]; + } + if (EndCode < 0x10000) { + for (uint32_t code = StartCode; code <= EndCode; code++) { + m_pCMap->m_pMapping[code] = (uint16_t)(StartCID + code - StartCode); + } + } else { + uint32_t buf[2]; + buf[0] = StartCode; + buf[1] = ((EndCode - StartCode) << 16) + StartCID; + m_AddMaps.AppendBlock(buf, sizeof buf); + } + m_CodeSeq = 0; + } else if (m_Status == 3) { + m_Status = 0; + } else if (m_Status == 4) { + m_pCMap->m_Charset = CharsetFromOrdering(CMap_GetString(word)); + m_Status = 0; + } else if (m_Status == 5) { + m_Status = 0; + } else if (m_Status == 6) { + m_pCMap->m_bVertical = CMap_GetCode(word) != 0; + m_Status = 0; + } else if (m_Status == 7) { + if (word == "endcodespacerange") { + int nSegs = m_CodeRanges.GetSize(); + if (nSegs > 1) { + m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes; + m_pCMap->m_nCodeRanges = nSegs; + FX_Free(m_pCMap->m_pLeadingBytes); + m_pCMap->m_pLeadingBytes = + FX_Alloc2D(uint8_t, nSegs, sizeof(CMap_CodeRange)); + FXSYS_memcpy(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(), + nSegs * sizeof(CMap_CodeRange)); + } else if (nSegs == 1) { + m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2) + ? CPDF_CMap::TwoBytes + : CPDF_CMap::OneByte; + } + m_Status = 0; + } else { + if (word.GetLength() == 0 || word.GetAt(0) != '<') { + return; + } + if (m_CodeSeq % 2) { + CMap_CodeRange range; + if (CMap_GetCodeRange(range, m_LastWord.AsStringC(), word)) { + m_CodeRanges.Add(range); + } + } + m_CodeSeq++; + } + } + m_LastWord = word; +} + +// Static. +uint32_t CPDF_CMapParser::CMap_GetCode(const CFX_ByteStringC& word) { + pdfium::base::CheckedNumeric num = 0; + if (word.GetAt(0) == '<') { + for (int i = 1; i < word.GetLength() && std::isxdigit(word.GetAt(i)); ++i) { + num = num * 16 + FXSYS_toHexDigit(word.GetAt(i)); + if (!num.IsValid()) + return 0; + } + return num.ValueOrDie(); + } + + for (int i = 0; i < word.GetLength() && std::isdigit(word.GetAt(i)); ++i) { + num = num * 10 + FXSYS_toDecimalDigit(static_cast(word.GetAt(i))); + if (!num.IsValid()) + return 0; + } + return num.ValueOrDie(); +} + +// Static. +bool CPDF_CMapParser::CMap_GetCodeRange(CMap_CodeRange& range, + const CFX_ByteStringC& first, + const CFX_ByteStringC& second) { + if (first.GetLength() == 0 || first.GetAt(0) != '<') + return false; + + int i; + for (i = 1; i < first.GetLength(); ++i) { + if (first.GetAt(i) == '>') { + break; + } + } + range.m_CharSize = (i - 1) / 2; + if (range.m_CharSize > 4) + return false; + + for (i = 0; i < range.m_CharSize; ++i) { + uint8_t digit1 = first.GetAt(i * 2 + 1); + uint8_t digit2 = first.GetAt(i * 2 + 2); + range.m_Lower[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2); + } + + uint32_t size = second.GetLength(); + for (i = 0; i < range.m_CharSize; ++i) { + uint8_t digit1 = ((uint32_t)i * 2 + 1 < size) + ? second.GetAt((FX_STRSIZE)i * 2 + 1) + : '0'; + uint8_t digit2 = ((uint32_t)i * 2 + 2 < size) + ? second.GetAt((FX_STRSIZE)i * 2 + 2) + : '0'; + range.m_Upper[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2); + } + return true; +} + +CPDF_CMap::CPDF_CMap() { + m_Charset = CIDSET_UNKNOWN; + m_Coding = CIDCODING_UNKNOWN; + m_CodingScheme = TwoBytes; + m_bVertical = false; + m_bLoaded = false; + m_pMapping = nullptr; + m_pLeadingBytes = nullptr; + m_pAddMapping = nullptr; + m_pEmbedMap = nullptr; + m_nCodeRanges = 0; +} +CPDF_CMap::~CPDF_CMap() { + FX_Free(m_pMapping); + FX_Free(m_pAddMapping); + FX_Free(m_pLeadingBytes); +} + +bool CPDF_CMap::IsLoaded() const { + return m_bLoaded; +} + +bool CPDF_CMap::IsVertWriting() const { + return m_bVertical; +} + +void CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr, + const CFX_ByteString& bsName, + bool bPromptCJK) { + m_PredefinedCMap = bsName; + if (m_PredefinedCMap == "Identity-H" || m_PredefinedCMap == "Identity-V") { + m_Coding = CIDCODING_CID; + m_bVertical = bsName[9] == 'V'; + m_bLoaded = true; + return; + } + CFX_ByteString cmapid = m_PredefinedCMap; + m_bVertical = cmapid.Right(1) == "V"; + if (cmapid.GetLength() > 2) { + cmapid = cmapid.Left(cmapid.GetLength() - 2); + } + const CPDF_PredefinedCMap* map = nullptr; + for (size_t i = 0; i < FX_ArraySize(g_PredefinedCMaps); ++i) { + if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[i].m_pName)) { + map = &g_PredefinedCMaps[i]; + break; + } + } + if (!map) + return; + + m_Charset = map->m_Charset; + m_Coding = map->m_Coding; + m_CodingScheme = map->m_CodingScheme; + if (m_CodingScheme == MixedTwoBytes) { + m_pLeadingBytes = FX_Alloc(uint8_t, 256); + for (uint32_t i = 0; i < map->m_LeadingSegCount; ++i) { + const uint8_t* segs = map->m_LeadingSegs; + for (int b = segs[i * 2]; b <= segs[i * 2 + 1]; ++b) { + m_pLeadingBytes[b] = 1; + } + } + } + FPDFAPI_FindEmbeddedCMap(bsName, m_Charset, m_Coding, m_pEmbedMap); + if (!m_pEmbedMap) + return; + + m_bLoaded = true; +} + +void CPDF_CMap::LoadEmbedded(const uint8_t* pData, uint32_t size) { + m_pMapping = FX_Alloc(uint16_t, 65536); + CPDF_CMapParser parser; + parser.Initialize(this); + CPDF_SimpleParser syntax(pData, size); + while (1) { + CFX_ByteStringC word = syntax.GetWord(); + if (word.IsEmpty()) { + break; + } + parser.ParseWord(word); + } + if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) { + m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4); + *(uint32_t*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8; + FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), + parser.m_AddMaps.GetSize()); + FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, + CompareDWORD); + } +} + +uint16_t CPDF_CMap::CIDFromCharCode(uint32_t charcode) const { + if (m_Coding == CIDCODING_CID) { + return (uint16_t)charcode; + } + if (m_pEmbedMap) { + return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode); + } + if (!m_pMapping) { + return (uint16_t)charcode; + } + if (charcode >> 16) { + if (m_pAddMapping) { + void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, + *(uint32_t*)m_pAddMapping, 8, CompareCID); + if (!found) + return 0; + return (uint16_t)(((uint32_t*)found)[1] % 65536 + charcode - + *(uint32_t*)found); + } + return 0; + } + return m_pMapping[charcode]; +} + +uint32_t CPDF_CMap::GetNextChar(const FX_CHAR* pString, + int nStrLen, + int& offset) const { + switch (m_CodingScheme) { + case OneByte: + return ((uint8_t*)pString)[offset++]; + case TwoBytes: + offset += 2; + return ((uint8_t*)pString)[offset - 2] * 256 + + ((uint8_t*)pString)[offset - 1]; + case MixedTwoBytes: { + uint8_t byte1 = ((uint8_t*)pString)[offset++]; + if (!m_pLeadingBytes[byte1]) { + return byte1; + } + uint8_t byte2 = ((uint8_t*)pString)[offset++]; + return byte1 * 256 + byte2; + } + case MixedFourBytes: { + uint8_t codes[4]; + int char_size = 1; + codes[0] = ((uint8_t*)pString)[offset++]; + CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes; + while (1) { + int ret = CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges); + if (ret == 0) { + return 0; + } + if (ret == 2) { + uint32_t charcode = 0; + for (int i = 0; i < char_size; i++) { + charcode = (charcode << 8) + codes[i]; + } + return charcode; + } + if (char_size == 4 || offset == nStrLen) { + return 0; + } + codes[char_size++] = ((uint8_t*)pString)[offset++]; + } + break; + } + } + return 0; +} +int CPDF_CMap::GetCharSize(uint32_t charcode) const { + switch (m_CodingScheme) { + case OneByte: + return 1; + case TwoBytes: + return 2; + case MixedTwoBytes: + case MixedFourBytes: + if (charcode < 0x100) { + return 1; + } + if (charcode < 0x10000) { + return 2; + } + if (charcode < 0x1000000) { + return 3; + } + return 4; + } + return 1; +} +int CPDF_CMap::CountChar(const FX_CHAR* pString, int size) const { + switch (m_CodingScheme) { + case OneByte: + return size; + case TwoBytes: + return (size + 1) / 2; + case MixedTwoBytes: { + int count = 0; + for (int i = 0; i < size; i++) { + count++; + if (m_pLeadingBytes[((uint8_t*)pString)[i]]) { + i++; + } + } + return count; + } + case MixedFourBytes: { + int count = 0, offset = 0; + while (offset < size) { + GetNextChar(pString, size, offset); + count++; + } + return count; + } + } + return size; +} + +int CPDF_CMap::AppendChar(FX_CHAR* str, uint32_t charcode) const { + switch (m_CodingScheme) { + case OneByte: + str[0] = (uint8_t)charcode; + return 1; + case TwoBytes: + str[0] = (uint8_t)(charcode / 256); + str[1] = (uint8_t)(charcode % 256); + return 2; + case MixedTwoBytes: + case MixedFourBytes: + if (charcode < 0x100) { + CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes; + int iSize = GetCharSizeImpl(charcode, pRanges, m_nCodeRanges); + if (iSize == 0) { + iSize = 1; + } + if (iSize > 1) { + FXSYS_memset(str, 0, sizeof(uint8_t) * iSize); + } + str[iSize - 1] = (uint8_t)charcode; + return iSize; + } + if (charcode < 0x10000) { + str[0] = (uint8_t)(charcode >> 8); + str[1] = (uint8_t)charcode; + return 2; + } + if (charcode < 0x1000000) { + str[0] = (uint8_t)(charcode >> 16); + str[1] = (uint8_t)(charcode >> 8); + str[2] = (uint8_t)charcode; + return 3; + } + str[0] = (uint8_t)(charcode >> 24); + str[1] = (uint8_t)(charcode >> 16); + str[2] = (uint8_t)(charcode >> 8); + str[3] = (uint8_t)charcode; + return 4; + } + return 0; +} + +CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() { + m_EmbeddedCount = 0; +} + +CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {} + +bool CPDF_CID2UnicodeMap::IsLoaded() { + return m_EmbeddedCount != 0; +} + +FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(uint16_t CID) { + if (m_Charset == CIDSET_UNICODE) { + return CID; + } + if (CID < m_EmbeddedCount) { + return m_pEmbeddedMap[CID]; + } + return 0; +} + +void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, + CIDSet charset, + bool bPromptCJK) { + m_Charset = charset; + + CPDF_FontGlobals* pFontGlobals = + CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); + m_pEmbeddedMap = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; + m_EmbeddedCount = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; +} + +CIDSet CharsetFromOrdering(const CFX_ByteStringC& ordering) { + for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) { + if (ordering == g_CharsetNames[charset]) + return CIDSetFromSizeT(charset); + } + return CIDSET_UNKNOWN; +} diff --git a/core/fpdfapi/font/fpdf_font_cid_unittest.cpp b/core/fpdfapi/font/fpdf_font_cid_unittest.cpp new file mode 100644 index 0000000000..53f5e47f92 --- /dev/null +++ b/core/fpdfapi/font/fpdf_font_cid_unittest.cpp @@ -0,0 +1,70 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fpdfapi/font/font_int.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +bool uint_ranges_equal(uint8_t* a, uint8_t* b, size_t count) { + for (size_t i = 0; i < count; ++i) { + if (a[i] != b[i]) + return false; + } + return true; +} + +} // namespace + +TEST(fpdf_font_cid, CMap_GetCode) { + EXPECT_EQ(0u, CPDF_CMapParser::CMap_GetCode("")); + EXPECT_EQ(0u, CPDF_CMapParser::CMap_GetCode("<")); + EXPECT_EQ(194u, CPDF_CMapParser::CMap_GetCode("", "")); + EXPECT_EQ(5, range.m_CharSize); + + EXPECT_TRUE( + CPDF_CMapParser::CMap_GetCodeRange(range, "<12345678>", "<87654321>")); + EXPECT_EQ(4, range.m_CharSize); + { + uint8_t lower[4] = {18, 52, 86, 120}; + uint8_t upper[4] = {135, 101, 67, 33}; + EXPECT_TRUE(uint_ranges_equal(lower, range.m_Lower, range.m_CharSize)); + EXPECT_TRUE(uint_ranges_equal(upper, range.m_Upper, range.m_CharSize)); + } + + // Hex characters + EXPECT_TRUE(CPDF_CMapParser::CMap_GetCodeRange(range, "", "")); + EXPECT_EQ(1, range.m_CharSize); + EXPECT_EQ(161, range.m_Lower[0]); + EXPECT_EQ(243, range.m_Upper[0]); + + // The second string should return 0's if it is shorter + EXPECT_TRUE(CPDF_CMapParser::CMap_GetCodeRange(range, "", "")); + EXPECT_EQ(1, range.m_CharSize); + EXPECT_EQ(161, range.m_Lower[0]); + EXPECT_EQ(0, range.m_Upper[0]); +} diff --git a/core/fpdfapi/font/fpdf_font_unittest.cpp b/core/fpdfapi/font/fpdf_font_unittest.cpp new file mode 100644 index 0000000000..977ae8a3bb --- /dev/null +++ b/core/fpdfapi/font/fpdf_font_unittest.cpp @@ -0,0 +1,30 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fpdfapi/font/font_int.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(fpdf_font, StringToCode) { + EXPECT_EQ(0u, CPDF_ToUnicodeMap::StringToCode("")); + EXPECT_EQ(194u, CPDF_ToUnicodeMap::StringToCode(" buf[count - 1].key) { + m_Buffer.AppendBlock(&pair, sizeof(_IntPair)); + return; + } + int low = 0, high = count - 1; + while (low <= high) { + int mid = (low + high) / 2; + if (buf[mid].key < key) { + low = mid + 1; + } else if (buf[mid].key > key) { + high = mid - 1; + } else { + buf[mid].value = value; + return; + } + } + m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair)); +} + +FX_BOOL CFX_GlyphMap::Lookup(int key, int& value) { + void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), + m_Buffer.GetSize() / sizeof(_IntPair), + sizeof(_IntPair), _CompareInt); + if (!pResult) { + return FALSE; + } + value = ((uint32_t*)pResult)[1]; + return TRUE; +} + +CFX_CTTGSUBTable::CFX_CTTGSUBTable() + : m_bFeautureMapLoad(FALSE), loaded(false) {} + +CFX_CTTGSUBTable::CFX_CTTGSUBTable(FT_Bytes gsub) + : m_bFeautureMapLoad(FALSE), loaded(false) { + LoadGSUBTable(gsub); +} + +CFX_CTTGSUBTable::~CFX_CTTGSUBTable() {} + +bool CFX_CTTGSUBTable::IsOk() const { + return loaded; +} + +bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub) { + header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3]; + if (header.Version != 0x00010000) { + return false; + } + header.ScriptList = gsub[4] << 8 | gsub[5]; + header.FeatureList = gsub[6] << 8 | gsub[7]; + header.LookupList = gsub[8] << 8 | gsub[9]; + return Parse(&gsub[header.ScriptList], &gsub[header.FeatureList], + &gsub[header.LookupList]); +} + +bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, + uint32_t* vglyphnum) { + uint32_t tag[] = { + (uint8_t)'v' << 24 | (uint8_t)'r' << 16 | (uint8_t)'t' << 8 | + (uint8_t)'2', + (uint8_t)'v' << 24 | (uint8_t)'e' << 16 | (uint8_t)'r' << 8 | + (uint8_t)'t', + }; + if (!m_bFeautureMapLoad) { + for (int i = 0; i < ScriptList.ScriptCount; i++) { + for (int j = 0; j < ScriptList.ScriptRecord[i].Script.LangSysCount; ++j) { + const auto& record = ScriptList.ScriptRecord[i].Script.LangSysRecord[j]; + for (int k = 0; k < record.LangSys.FeatureCount; ++k) { + uint32_t index = record.LangSys.FeatureIndex[k]; + if (FeatureList.FeatureRecord[index].FeatureTag == tag[0] || + FeatureList.FeatureRecord[index].FeatureTag == tag[1]) { + if (!pdfium::ContainsKey(m_featureMap, index)) { + m_featureMap[index] = index; + } + } + } + } + } + if (m_featureMap.empty()) { + for (int i = 0; i < FeatureList.FeatureCount; i++) { + if (FeatureList.FeatureRecord[i].FeatureTag == tag[0] || + FeatureList.FeatureRecord[i].FeatureTag == tag[1]) { + m_featureMap[i] = i; + } + } + } + m_bFeautureMapLoad = TRUE; + } + for (const auto& pair : m_featureMap) { + if (GetVerticalGlyphSub(glyphnum, vglyphnum, + &FeatureList.FeatureRecord[pair.second].Feature)) { + return true; + } + } + return false; +} + +bool CFX_CTTGSUBTable::GetVerticalGlyphSub(uint32_t glyphnum, + uint32_t* vglyphnum, + TFeature* Feature) const { + for (int i = 0; i < Feature->LookupCount; i++) { + int index = Feature->LookupListIndex[i]; + if (index < 0 || LookupList.LookupCount < index) { + continue; + } + if (LookupList.Lookup[index].LookupType == 1) { + if (GetVerticalGlyphSub2(glyphnum, vglyphnum, + &LookupList.Lookup[index])) { + return true; + } + } + } + return false; +} + +bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, + uint32_t* vglyphnum, + TLookup* Lookup) const { + for (int i = 0; i < Lookup->SubTableCount; i++) { + switch (Lookup->SubTable[i]->SubstFormat) { + case 1: { + TSingleSubstFormat1* tbl1 = (TSingleSubstFormat1*)Lookup->SubTable[i]; + if (GetCoverageIndex(tbl1->Coverage.get(), glyphnum) >= 0) { + *vglyphnum = glyphnum + tbl1->DeltaGlyphID; + return true; + } + break; + } + case 2: { + TSingleSubstFormat2* tbl2 = (TSingleSubstFormat2*)Lookup->SubTable[i]; + int index = -1; + index = GetCoverageIndex(tbl2->Coverage.get(), glyphnum); + if (0 <= index && index < tbl2->GlyphCount) { + *vglyphnum = tbl2->Substitute[index]; + return true; + } + break; + } + } + } + return false; +} + +int CFX_CTTGSUBTable::GetCoverageIndex(TCoverageFormatBase* Coverage, + uint32_t g) const { + int i = 0; + if (!Coverage) { + return -1; + } + switch (Coverage->CoverageFormat) { + case 1: { + TCoverageFormat1* c1 = (TCoverageFormat1*)Coverage; + for (i = 0; i < c1->GlyphCount; i++) { + if ((uint32_t)c1->GlyphArray[i] == g) { + return i; + } + } + return -1; + } + case 2: { + TCoverageFormat2* c2 = (TCoverageFormat2*)Coverage; + for (i = 0; i < c2->RangeCount; i++) { + uint32_t s = c2->RangeRecord[i].Start; + uint32_t e = c2->RangeRecord[i].End; + uint32_t si = c2->RangeRecord[i].StartCoverageIndex; + if (s <= g && g <= e) { + return si + g - s; + } + } + return -1; + } + } + return -1; +} + +uint8_t CFX_CTTGSUBTable::GetUInt8(FT_Bytes& p) const { + uint8_t ret = p[0]; + p += 1; + return ret; +} + +int16_t CFX_CTTGSUBTable::GetInt16(FT_Bytes& p) const { + uint16_t ret = p[0] << 8 | p[1]; + p += 2; + return *(int16_t*)&ret; +} + +uint16_t CFX_CTTGSUBTable::GetUInt16(FT_Bytes& p) const { + uint16_t ret = p[0] << 8 | p[1]; + p += 2; + return ret; +} + +int32_t CFX_CTTGSUBTable::GetInt32(FT_Bytes& p) const { + uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + p += 4; + return *(int32_t*)&ret; +} + +uint32_t CFX_CTTGSUBTable::GetUInt32(FT_Bytes& p) const { + uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + p += 4; + return ret; +} + +bool CFX_CTTGSUBTable::Parse(FT_Bytes scriptlist, + FT_Bytes featurelist, + FT_Bytes lookuplist) { + ParseScriptList(scriptlist, &ScriptList); + ParseFeatureList(featurelist, &FeatureList); + ParseLookupList(lookuplist, &LookupList); + return true; +} + +void CFX_CTTGSUBTable::ParseScriptList(FT_Bytes raw, TScriptList* rec) { + int i; + FT_Bytes sp = raw; + rec->ScriptCount = GetUInt16(sp); + if (rec->ScriptCount <= 0) { + return; + } + rec->ScriptRecord.reset(new TScriptRecord[rec->ScriptCount]); + for (i = 0; i < rec->ScriptCount; i++) { + rec->ScriptRecord[i].ScriptTag = GetUInt32(sp); + uint16_t offset = GetUInt16(sp); + ParseScript(&raw[offset], &rec->ScriptRecord[i].Script); + } +} + +void CFX_CTTGSUBTable::ParseScript(FT_Bytes raw, TScript* rec) { + int i; + FT_Bytes sp = raw; + rec->DefaultLangSys = GetUInt16(sp); + rec->LangSysCount = GetUInt16(sp); + if (rec->LangSysCount <= 0) { + return; + } + rec->LangSysRecord.reset(new TLangSysRecord[rec->LangSysCount]); + for (i = 0; i < rec->LangSysCount; i++) { + rec->LangSysRecord[i].LangSysTag = GetUInt32(sp); + uint16_t offset = GetUInt16(sp); + ParseLangSys(&raw[offset], &rec->LangSysRecord[i].LangSys); + } +} + +void CFX_CTTGSUBTable::ParseLangSys(FT_Bytes raw, TLangSys* rec) { + FT_Bytes sp = raw; + rec->LookupOrder = GetUInt16(sp); + rec->ReqFeatureIndex = GetUInt16(sp); + rec->FeatureCount = GetUInt16(sp); + if (rec->FeatureCount <= 0) { + return; + } + rec->FeatureIndex.reset(new uint16_t[rec->FeatureCount]); + FXSYS_memset(rec->FeatureIndex.get(), 0, + sizeof(uint16_t) * rec->FeatureCount); + for (int i = 0; i < rec->FeatureCount; ++i) { + rec->FeatureIndex[i] = GetUInt16(sp); + } +} + +void CFX_CTTGSUBTable::ParseFeatureList(FT_Bytes raw, TFeatureList* rec) { + int i; + FT_Bytes sp = raw; + rec->FeatureCount = GetUInt16(sp); + if (rec->FeatureCount <= 0) { + return; + } + rec->FeatureRecord.reset(new TFeatureRecord[rec->FeatureCount]); + for (i = 0; i < rec->FeatureCount; i++) { + rec->FeatureRecord[i].FeatureTag = GetUInt32(sp); + uint16_t offset = GetUInt16(sp); + ParseFeature(&raw[offset], &rec->FeatureRecord[i].Feature); + } +} + +void CFX_CTTGSUBTable::ParseFeature(FT_Bytes raw, TFeature* rec) { + int i; + FT_Bytes sp = raw; + rec->FeatureParams = GetUInt16(sp); + rec->LookupCount = GetUInt16(sp); + if (rec->LookupCount <= 0) { + return; + } + rec->LookupListIndex.reset(new uint16_t[rec->LookupCount]); + for (i = 0; i < rec->LookupCount; i++) { + rec->LookupListIndex[i] = GetUInt16(sp); + } +} + +void CFX_CTTGSUBTable::ParseLookupList(FT_Bytes raw, TLookupList* rec) { + int i; + FT_Bytes sp = raw; + rec->LookupCount = GetUInt16(sp); + if (rec->LookupCount <= 0) { + return; + } + rec->Lookup.reset(new TLookup[rec->LookupCount]); + for (i = 0; i < rec->LookupCount; i++) { + uint16_t offset = GetUInt16(sp); + ParseLookup(&raw[offset], &rec->Lookup[i]); + } +} + +void CFX_CTTGSUBTable::ParseLookup(FT_Bytes raw, TLookup* rec) { + int i; + FT_Bytes sp = raw; + rec->LookupType = GetUInt16(sp); + rec->LookupFlag = GetUInt16(sp); + rec->SubTableCount = GetUInt16(sp); + if (rec->SubTableCount <= 0) { + return; + } + rec->SubTable.reset(new TSubTableBase*[rec->SubTableCount]); + for (i = 0; i < rec->SubTableCount; i++) { + rec->SubTable[i] = nullptr; + } + if (rec->LookupType != 1) { + return; + } + for (i = 0; i < rec->SubTableCount; i++) { + uint16_t offset = GetUInt16(sp); + ParseSingleSubst(&raw[offset], &rec->SubTable[i]); + } +} + +CFX_CTTGSUBTable::TCoverageFormatBase* CFX_CTTGSUBTable::ParseCoverage( + FT_Bytes raw) { + FT_Bytes sp = raw; + uint16_t format = GetUInt16(sp); + TCoverageFormatBase* rec = nullptr; + if (format == 1) { + rec = new TCoverageFormat1(); + ParseCoverageFormat1(raw, static_cast(rec)); + } else if (format == 2) { + rec = new TCoverageFormat2(); + ParseCoverageFormat2(raw, static_cast(rec)); + } + return rec; +} + +void CFX_CTTGSUBTable::ParseCoverageFormat1(FT_Bytes raw, + TCoverageFormat1* rec) { + int i; + FT_Bytes sp = raw; + GetUInt16(sp); + rec->GlyphCount = GetUInt16(sp); + if (rec->GlyphCount <= 0) { + return; + } + rec->GlyphArray.reset(new uint16_t[rec->GlyphCount]); + for (i = 0; i < rec->GlyphCount; i++) { + rec->GlyphArray[i] = GetUInt16(sp); + } +} + +void CFX_CTTGSUBTable::ParseCoverageFormat2(FT_Bytes raw, + TCoverageFormat2* rec) { + int i; + FT_Bytes sp = raw; + GetUInt16(sp); + rec->RangeCount = GetUInt16(sp); + if (rec->RangeCount <= 0) { + return; + } + rec->RangeRecord.reset(new TRangeRecord[rec->RangeCount]); + for (i = 0; i < rec->RangeCount; i++) { + rec->RangeRecord[i].Start = GetUInt16(sp); + rec->RangeRecord[i].End = GetUInt16(sp); + rec->RangeRecord[i].StartCoverageIndex = GetUInt16(sp); + } +} + +void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec) { + FT_Bytes sp = raw; + uint16_t Format = GetUInt16(sp); + switch (Format) { + case 1: + *rec = new TSingleSubstFormat1(); + ParseSingleSubstFormat1(raw, (TSingleSubstFormat1*)*rec); + break; + case 2: + *rec = new TSingleSubstFormat2(); + ParseSingleSubstFormat2(raw, (TSingleSubstFormat2*)*rec); + break; + } +} + +void CFX_CTTGSUBTable::ParseSingleSubstFormat1(FT_Bytes raw, + TSingleSubstFormat1* rec) { + FT_Bytes sp = raw; + GetUInt16(sp); + uint16_t offset = GetUInt16(sp); + rec->Coverage.reset(ParseCoverage(&raw[offset])); + rec->DeltaGlyphID = GetInt16(sp); +} + +void CFX_CTTGSUBTable::ParseSingleSubstFormat2(FT_Bytes raw, + TSingleSubstFormat2* rec) { + int i; + FT_Bytes sp = raw; + GetUInt16(sp); + uint16_t offset = GetUInt16(sp); + rec->Coverage.reset(ParseCoverage(&raw[offset])); + rec->GlyphCount = GetUInt16(sp); + if (rec->GlyphCount <= 0) { + return; + } + rec->Substitute.reset(new uint16_t[rec->GlyphCount]); + for (i = 0; i < rec->GlyphCount; i++) { + rec->Substitute[i] = GetUInt16(sp); + } +} + +CFX_CTTGSUBTable::TCoverageFormat1::TCoverageFormat1() + : TCoverageFormatBase(1), GlyphCount(0) {} + +CFX_CTTGSUBTable::TCoverageFormat1::~TCoverageFormat1() {} + +CFX_CTTGSUBTable::TRangeRecord::TRangeRecord() + : Start(0), End(0), StartCoverageIndex(0) {} + +CFX_CTTGSUBTable::TCoverageFormat2::TCoverageFormat2() + : TCoverageFormatBase(2), RangeCount(0) {} + +CFX_CTTGSUBTable::TCoverageFormat2::~TCoverageFormat2() {} + +CFX_CTTGSUBTable::TSingleSubstFormat1::TSingleSubstFormat1() + : TSubTableBase(1), DeltaGlyphID(0) {} + +CFX_CTTGSUBTable::TSingleSubstFormat1::~TSingleSubstFormat1() {} + +CFX_CTTGSUBTable::TSingleSubstFormat2::TSingleSubstFormat2() + : TSubTableBase(2), GlyphCount(0) {} + +CFX_CTTGSUBTable::TSingleSubstFormat2::~TSingleSubstFormat2() {} + +CFX_CTTGSUBTable::TLookup::TLookup() + : LookupType(0), LookupFlag(0), SubTableCount(0) {} + +CFX_CTTGSUBTable::TLookup::~TLookup() { + if (SubTable) { + for (int i = 0; i < SubTableCount; ++i) + delete SubTable[i]; + } +} + +CFX_CTTGSUBTable::TScript::TScript() : DefaultLangSys(0), LangSysCount(0) {} + +CFX_CTTGSUBTable::TScript::~TScript() {} + +CFX_CTTGSUBTable::TScriptList::TScriptList() : ScriptCount(0) {} + +CFX_CTTGSUBTable::TScriptList::~TScriptList() {} + +CFX_CTTGSUBTable::TFeature::TFeature() : FeatureParams(0), LookupCount(0) {} + +CFX_CTTGSUBTable::TFeature::~TFeature() {} + +CFX_CTTGSUBTable::TFeatureList::TFeatureList() : FeatureCount(0) {} + +CFX_CTTGSUBTable::TFeatureList::~TFeatureList() {} + +CFX_CTTGSUBTable::TLookupList::TLookupList() : LookupCount(0) {} + +CFX_CTTGSUBTable::TLookupList::~TLookupList() {} + +CFX_CTTGSUBTable::TLangSys::TLangSys() + : LookupOrder(0), ReqFeatureIndex(0), FeatureCount(0) {} + +CFX_CTTGSUBTable::TLangSys::~TLangSys() {} diff --git a/core/fpdfapi/font/ttgsubtable.h b/core/fpdfapi/font/ttgsubtable.h new file mode 100644 index 0000000000..b3853912b2 --- /dev/null +++ b/core/fpdfapi/font/ttgsubtable.h @@ -0,0 +1,301 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_FONT_TTGSUBTABLE_H_ +#define CORE_FPDFAPI_FONT_TTGSUBTABLE_H_ + +#include + +#include +#include + +#include "core/fxcrt/fx_basic.h" +#include "core/fxge/fx_font.h" +#include "core/fxge/fx_freetype.h" + +class CFX_GlyphMap { + public: + CFX_GlyphMap(); + ~CFX_GlyphMap(); + + void SetAt(int key, int value); + FX_BOOL Lookup(int key, int& value); + + protected: + CFX_BinaryBuf m_Buffer; +}; + +class CFX_CTTGSUBTable { + public: + CFX_CTTGSUBTable(); + explicit CFX_CTTGSUBTable(FT_Bytes gsub); + virtual ~CFX_CTTGSUBTable(); + + bool IsOk() const; + bool LoadGSUBTable(FT_Bytes gsub); + bool GetVerticalGlyph(uint32_t glyphnum, uint32_t* vglyphnum); + + private: + struct tt_gsub_header { + uint32_t Version; + uint16_t ScriptList; + uint16_t FeatureList; + uint16_t LookupList; + }; + struct TLangSys { + TLangSys(); + ~TLangSys(); + + uint16_t LookupOrder; + uint16_t ReqFeatureIndex; + uint16_t FeatureCount; + std::unique_ptr FeatureIndex; + + private: + TLangSys(const TLangSys&); + TLangSys& operator=(const TLangSys&); + }; + struct TLangSysRecord { + TLangSysRecord() : LangSysTag(0) {} + + uint32_t LangSysTag; + TLangSys LangSys; + + private: + TLangSysRecord(const TLangSysRecord&); + TLangSysRecord& operator=(const TLangSysRecord&); + }; + struct TScript { + TScript(); + ~TScript(); + + uint16_t DefaultLangSys; + uint16_t LangSysCount; + std::unique_ptr LangSysRecord; + + private: + TScript(const TScript&); + TScript& operator=(const TScript&); + }; + struct TScriptRecord { + TScriptRecord() : ScriptTag(0) {} + + uint32_t ScriptTag; + TScript Script; + + private: + TScriptRecord(const TScriptRecord&); + TScriptRecord& operator=(const TScriptRecord&); + }; + struct TScriptList { + TScriptList(); + ~TScriptList(); + + uint16_t ScriptCount; + std::unique_ptr ScriptRecord; + + private: + TScriptList(const TScriptList&); + TScriptList& operator=(const TScriptList&); + }; + struct TFeature { + TFeature(); + ~TFeature(); + + uint16_t FeatureParams; + int LookupCount; + std::unique_ptr LookupListIndex; + + private: + TFeature(const TFeature&); + TFeature& operator=(const TFeature&); + }; + struct TFeatureRecord { + TFeatureRecord() : FeatureTag(0) {} + + uint32_t FeatureTag; + TFeature Feature; + + private: + TFeatureRecord(const TFeatureRecord&); + TFeatureRecord& operator=(const TFeatureRecord&); + }; + struct TFeatureList { + TFeatureList(); + ~TFeatureList(); + + int FeatureCount; + std::unique_ptr FeatureRecord; + + private: + TFeatureList(const TFeatureList&); + TFeatureList& operator=(const TFeatureList&); + }; + enum TLookupFlag { + LOOKUPFLAG_RightToLeft = 0x0001, + LOOKUPFLAG_IgnoreBaseGlyphs = 0x0002, + LOOKUPFLAG_IgnoreLigatures = 0x0004, + LOOKUPFLAG_IgnoreMarks = 0x0008, + LOOKUPFLAG_Reserved = 0x00F0, + LOOKUPFLAG_MarkAttachmentType = 0xFF00, + }; + struct TCoverageFormatBase { + TCoverageFormatBase() : CoverageFormat(0) {} + explicit TCoverageFormatBase(uint16_t format) : CoverageFormat(format) {} + virtual ~TCoverageFormatBase() {} + + uint16_t CoverageFormat; + CFX_GlyphMap m_glyphMap; + + private: + TCoverageFormatBase(const TCoverageFormatBase&); + TCoverageFormatBase& operator=(const TCoverageFormatBase&); + }; + struct TCoverageFormat1 : public TCoverageFormatBase { + TCoverageFormat1(); + ~TCoverageFormat1() override; + + uint16_t GlyphCount; + std::unique_ptr GlyphArray; + + private: + TCoverageFormat1(const TCoverageFormat1&); + TCoverageFormat1& operator=(const TCoverageFormat1&); + }; + struct TRangeRecord { + TRangeRecord(); + + friend bool operator>(const TRangeRecord& r1, const TRangeRecord& r2) { + return r1.Start > r2.Start; + } + + uint16_t Start; + uint16_t End; + uint16_t StartCoverageIndex; + + private: + TRangeRecord(const TRangeRecord&); + }; + struct TCoverageFormat2 : public TCoverageFormatBase { + TCoverageFormat2(); + ~TCoverageFormat2() override; + + uint16_t RangeCount; + std::unique_ptr RangeRecord; + + private: + TCoverageFormat2(const TCoverageFormat2&); + TCoverageFormat2& operator=(const TCoverageFormat2&); + }; + struct TDevice { + TDevice() : StartSize(0), EndSize(0), DeltaFormat(0) {} + + uint16_t StartSize; + uint16_t EndSize; + uint16_t DeltaFormat; + + private: + TDevice(const TDevice&); + TDevice& operator=(const TDevice&); + }; + struct TSubTableBase { + TSubTableBase() : SubstFormat(0) {} + explicit TSubTableBase(uint16_t format) : SubstFormat(format) {} + virtual ~TSubTableBase() {} + + uint16_t SubstFormat; + + private: + TSubTableBase(const TSubTableBase&); + TSubTableBase& operator=(const TSubTableBase&); + }; + struct TSingleSubstFormat1 : public TSubTableBase { + TSingleSubstFormat1(); + ~TSingleSubstFormat1() override; + + std::unique_ptr Coverage; + int16_t DeltaGlyphID; + + private: + TSingleSubstFormat1(const TSingleSubstFormat1&); + TSingleSubstFormat1& operator=(const TSingleSubstFormat1&); + }; + struct TSingleSubstFormat2 : public TSubTableBase { + TSingleSubstFormat2(); + ~TSingleSubstFormat2() override; + + std::unique_ptr Coverage; + uint16_t GlyphCount; + std::unique_ptr Substitute; + + private: + TSingleSubstFormat2(const TSingleSubstFormat2&); + TSingleSubstFormat2& operator=(const TSingleSubstFormat2&); + }; + struct TLookup { + TLookup(); + ~TLookup(); + + uint16_t LookupType; + uint16_t LookupFlag; + uint16_t SubTableCount; + std::unique_ptr SubTable; + + private: + TLookup(const TLookup&); + TLookup& operator=(const TLookup&); + }; + struct TLookupList { + TLookupList(); + ~TLookupList(); + + int LookupCount; + std::unique_ptr Lookup; + + private: + TLookupList(const TLookupList&); + TLookupList& operator=(const TLookupList&); + }; + + bool Parse(FT_Bytes scriptlist, FT_Bytes featurelist, FT_Bytes lookuplist); + void ParseScriptList(FT_Bytes raw, TScriptList* rec); + void ParseScript(FT_Bytes raw, TScript* rec); + void ParseLangSys(FT_Bytes raw, TLangSys* rec); + void ParseFeatureList(FT_Bytes raw, TFeatureList* rec); + void ParseFeature(FT_Bytes raw, TFeature* rec); + void ParseLookupList(FT_Bytes raw, TLookupList* rec); + void ParseLookup(FT_Bytes raw, TLookup* rec); + TCoverageFormatBase* ParseCoverage(FT_Bytes raw); + void ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1* rec); + void ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2* rec); + void ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec); + void ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1* rec); + void ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2* rec); + + bool GetVerticalGlyphSub(uint32_t glyphnum, + uint32_t* vglyphnum, + TFeature* Feature) const; + bool GetVerticalGlyphSub2(uint32_t glyphnum, + uint32_t* vglyphnum, + TLookup* Lookup) const; + int GetCoverageIndex(TCoverageFormatBase* Coverage, uint32_t g) const; + + uint8_t GetUInt8(FT_Bytes& p) const; + int16_t GetInt16(FT_Bytes& p) const; + uint16_t GetUInt16(FT_Bytes& p) const; + int32_t GetInt32(FT_Bytes& p) const; + uint32_t GetUInt32(FT_Bytes& p) const; + + std::map m_featureMap; + FX_BOOL m_bFeautureMapLoad; + bool loaded; + tt_gsub_header header; + TScriptList ScriptList; + TFeatureList FeatureList; + TLookupList LookupList; +}; + +#endif // CORE_FPDFAPI_FONT_TTGSUBTABLE_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp deleted file mode 100644 index cb21d2023a..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp +++ /dev/null @@ -1,852 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" - -#include -#include - -#include "core/fpdfapi/cmaps/cmap_int.h" -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "core/fpdfapi/fpdf_font/ttgsubtable.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "third_party/base/numerics/safe_math.h" - -namespace { - -const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200}; - -const struct CIDTransform { - uint16_t cid; - uint8_t a; - uint8_t b; - uint8_t c; - uint8_t d; - uint8_t e; - uint8_t f; -} g_Japan1_VertCIDs[] = { - {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89}, - {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127}, - {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127}, - {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127}, - {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127}, - {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127}, - {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104}, - {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104}, - {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127}, - {7904, 0, 129, 127, 0, 17, 127}, {7905, 0, 129, 127, 0, 17, 114}, - {7906, 0, 129, 127, 0, 17, 127}, {7907, 0, 129, 127, 0, 17, 127}, - {7908, 0, 129, 127, 0, 17, 127}, {7909, 0, 129, 127, 0, 17, 127}, - {7910, 0, 129, 127, 0, 17, 127}, {7911, 0, 129, 127, 0, 17, 127}, - {7912, 0, 129, 127, 0, 17, 127}, {7913, 0, 129, 127, 0, 17, 127}, - {7914, 0, 129, 127, 0, 17, 127}, {7915, 0, 129, 127, 0, 17, 114}, - {7916, 0, 129, 127, 0, 17, 127}, {7917, 0, 129, 127, 0, 17, 127}, - {7918, 127, 0, 0, 127, 18, 25}, {7919, 127, 0, 0, 127, 18, 25}, - {7920, 127, 0, 0, 127, 18, 25}, {7921, 127, 0, 0, 127, 18, 25}, - {7922, 127, 0, 0, 127, 18, 25}, {7923, 127, 0, 0, 127, 18, 25}, - {7924, 127, 0, 0, 127, 18, 25}, {7925, 127, 0, 0, 127, 18, 25}, - {7926, 127, 0, 0, 127, 18, 25}, {7927, 127, 0, 0, 127, 18, 25}, - {7928, 127, 0, 0, 127, 18, 25}, {7929, 127, 0, 0, 127, 18, 25}, - {7930, 127, 0, 0, 127, 18, 25}, {7931, 127, 0, 0, 127, 18, 25}, - {7932, 127, 0, 0, 127, 18, 25}, {7933, 127, 0, 0, 127, 18, 25}, - {7934, 127, 0, 0, 127, 18, 25}, {7935, 127, 0, 0, 127, 18, 25}, - {7936, 127, 0, 0, 127, 18, 25}, {7937, 127, 0, 0, 127, 18, 25}, - {7938, 127, 0, 0, 127, 18, 25}, {7939, 127, 0, 0, 127, 18, 25}, - {8720, 0, 129, 127, 0, 19, 102}, {8721, 0, 129, 127, 0, 13, 127}, - {8722, 0, 129, 127, 0, 19, 108}, {8723, 0, 129, 127, 0, 19, 102}, - {8724, 0, 129, 127, 0, 19, 102}, {8725, 0, 129, 127, 0, 19, 102}, - {8726, 0, 129, 127, 0, 19, 102}, {8727, 0, 129, 127, 0, 19, 102}, - {8728, 0, 129, 127, 0, 19, 114}, {8729, 0, 129, 127, 0, 19, 114}, - {8730, 0, 129, 127, 0, 38, 108}, {8731, 0, 129, 127, 0, 13, 108}, - {8732, 0, 129, 127, 0, 19, 108}, {8733, 0, 129, 127, 0, 19, 108}, - {8734, 0, 129, 127, 0, 19, 108}, {8735, 0, 129, 127, 0, 19, 108}, - {8736, 0, 129, 127, 0, 19, 102}, {8737, 0, 129, 127, 0, 19, 102}, - {8738, 0, 129, 127, 0, 19, 102}, {8739, 0, 129, 127, 0, 19, 102}, - {8740, 0, 129, 127, 0, 19, 102}, {8741, 0, 129, 127, 0, 19, 102}, - {8742, 0, 129, 127, 0, 19, 102}, {8743, 0, 129, 127, 0, 19, 102}, - {8744, 0, 129, 127, 0, 19, 102}, {8745, 0, 129, 127, 0, 19, 102}, - {8746, 0, 129, 127, 0, 19, 114}, {8747, 0, 129, 127, 0, 19, 114}, - {8748, 0, 129, 127, 0, 19, 102}, {8749, 0, 129, 127, 0, 19, 102}, - {8750, 0, 129, 127, 0, 19, 102}, {8751, 0, 129, 127, 0, 19, 102}, - {8752, 0, 129, 127, 0, 19, 102}, {8753, 0, 129, 127, 0, 19, 102}, - {8754, 0, 129, 127, 0, 19, 102}, {8755, 0, 129, 127, 0, 19, 102}, - {8756, 0, 129, 127, 0, 19, 102}, {8757, 0, 129, 127, 0, 19, 102}, - {8758, 0, 129, 127, 0, 19, 102}, {8759, 0, 129, 127, 0, 19, 102}, - {8760, 0, 129, 127, 0, 19, 102}, {8761, 0, 129, 127, 0, 19, 102}, - {8762, 0, 129, 127, 0, 19, 102}, {8763, 0, 129, 127, 0, 19, 102}, - {8764, 0, 129, 127, 0, 19, 102}, {8765, 0, 129, 127, 0, 19, 102}, - {8766, 0, 129, 127, 0, 19, 102}, {8767, 0, 129, 127, 0, 19, 102}, - {8768, 0, 129, 127, 0, 19, 102}, {8769, 0, 129, 127, 0, 19, 102}, - {8770, 0, 129, 127, 0, 19, 102}, {8771, 0, 129, 127, 0, 19, 102}, - {8772, 0, 129, 127, 0, 19, 102}, {8773, 0, 129, 127, 0, 19, 102}, - {8774, 0, 129, 127, 0, 19, 102}, {8775, 0, 129, 127, 0, 19, 102}, - {8776, 0, 129, 127, 0, 19, 102}, {8777, 0, 129, 127, 0, 19, 102}, - {8778, 0, 129, 127, 0, 19, 102}, {8779, 0, 129, 127, 0, 19, 114}, - {8780, 0, 129, 127, 0, 19, 108}, {8781, 0, 129, 127, 0, 19, 114}, - {8782, 0, 129, 127, 0, 13, 114}, {8783, 0, 129, 127, 0, 19, 108}, - {8784, 0, 129, 127, 0, 13, 114}, {8785, 0, 129, 127, 0, 19, 108}, - {8786, 0, 129, 127, 0, 19, 108}, {8787, 0, 129, 127, 0, 19, 108}, - {8788, 0, 129, 127, 0, 19, 108}, {8789, 0, 129, 127, 0, 19, 108}, - {8790, 0, 129, 127, 0, 19, 108}, {8791, 0, 129, 127, 0, 19, 108}, - {8792, 0, 129, 127, 0, 19, 108}, {8793, 0, 129, 127, 0, 19, 108}, - {8794, 0, 129, 127, 0, 19, 108}, {8795, 0, 129, 127, 0, 19, 108}, - {8796, 0, 129, 127, 0, 19, 108}, {8797, 0, 129, 127, 0, 19, 108}, - {8798, 0, 129, 127, 0, 19, 108}, {8799, 0, 129, 127, 0, 19, 108}, - {8800, 0, 129, 127, 0, 19, 108}, {8801, 0, 129, 127, 0, 19, 108}, - {8802, 0, 129, 127, 0, 19, 108}, {8803, 0, 129, 127, 0, 19, 108}, - {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108}, - {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108}, - {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108}, - {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114}, - {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114}, - {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121}, - {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127}, - {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108}, -}; - -CPDF_FontGlobals* GetFontGlobals() { - return CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); -} - -#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ - -bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) { - switch (charset) { - case CIDSET_GB1: - case CIDSET_CNS1: - case CIDSET_JAPAN1: - case CIDSET_KOREA1: - return true; - - default: - return false; - } -} - -FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, - CIDSet charset, - uint32_t charcode) { - if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) - return 0; - - uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode); - const auto& codes = GetFontGlobals()->m_EmbeddedToUnicodes[charset]; - if (codes.m_pMap && cid && cid < codes.m_Count) - return codes.m_pMap[cid]; - return 0; -} - -uint32_t EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, - CIDSet charset, - FX_WCHAR unicode) { - if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset)) - return 0; - - const auto& codes = GetFontGlobals()->m_EmbeddedToUnicodes[charset]; - const uint16_t* pCodes = codes.m_pMap; - if (!pCodes) - return 0; - - for (uint32_t i = 0; i < codes.m_Count; ++i) { - if (pCodes[i] == unicode) { - uint32_t CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i); - if (CharCode) - return CharCode; - } - } - return 0; -} - -#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ - -void FT_UseCIDCharmap(FXFT_Face face, int coding) { - int encoding; - switch (coding) { - case CIDCODING_GB: - encoding = FXFT_ENCODING_GB2312; - break; - case CIDCODING_BIG5: - encoding = FXFT_ENCODING_BIG5; - break; - case CIDCODING_JIS: - encoding = FXFT_ENCODING_SJIS; - break; - case CIDCODING_KOREA: - encoding = FXFT_ENCODING_JOHAB; - break; - default: - encoding = FXFT_ENCODING_UNICODE; - } - int err = FXFT_Select_Charmap(face, encoding); - if (err) - err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); - if (err && FXFT_Get_Face_Charmaps(face)) - FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face)); -} - -bool IsMetricForCID(const uint32_t* pEntry, uint16_t CID) { - return pEntry[0] <= CID && pEntry[1] >= CID; -} - -} // namespace - -CPDF_CIDFont::CPDF_CIDFont() - : m_pCMap(nullptr), - m_pCID2UnicodeMap(nullptr), - m_bCIDIsGID(false), - m_bAnsiWidthsFixed(false), - m_bAdobeCourierStd(false) { - for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i) - m_CharBBox[i] = FX_RECT(-1, -1, -1, -1); -} - -CPDF_CIDFont::~CPDF_CIDFont() {} - -bool CPDF_CIDFont::IsCIDFont() const { - return true; -} - -const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const { - return this; -} - -CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() { - return this; -} - -uint16_t CPDF_CIDFont::CIDFromCharCode(uint32_t charcode) const { - return m_pCMap ? m_pCMap->CIDFromCharCode(charcode) - : static_cast(charcode); -} - -bool CPDF_CIDFont::IsVertWriting() const { - return m_pCMap && m_pCMap->IsVertWriting(); -} - -CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(uint32_t charcode) const { - CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode); - if (!str.IsEmpty()) - return str; - FX_WCHAR ret = GetUnicodeFromCharCode(charcode); - return ret ? ret : CFX_WideString(); -} - -FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(uint32_t charcode) const { - switch (m_pCMap->m_Coding) { - case CIDCODING_UCS2: - case CIDCODING_UTF16: - return static_cast(charcode); - case CIDCODING_CID: - if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) - return 0; - return m_pCID2UnicodeMap->UnicodeFromCID(static_cast(charcode)); - } - if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded()) - return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode)); - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - FX_WCHAR unicode; - int charsize = 1; - if (charcode > 255) { - charcode = (charcode % 256) * 256 + (charcode / 256); - charsize = 2; - } - int ret = FXSYS_MultiByteToWideChar( - g_CharsetCPs[m_pCMap->m_Coding], 0, - reinterpret_cast(&charcode), charsize, &unicode, 1); - return ret == 1 ? unicode : 0; -#else - if (!m_pCMap->m_pEmbedMap) - return 0; - return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, - charcode); -#endif -} - -uint32_t CPDF_CIDFont::CharCodeFromUnicode(FX_WCHAR unicode) const { - uint32_t charcode = CPDF_Font::CharCodeFromUnicode(unicode); - if (charcode) - return charcode; - switch (m_pCMap->m_Coding) { - case CIDCODING_UNKNOWN: - return 0; - case CIDCODING_UCS2: - case CIDCODING_UTF16: - return unicode; - case CIDCODING_CID: { - if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) - return 0; - uint32_t CID = 0; - while (CID < 65536) { - FX_WCHAR this_unicode = - m_pCID2UnicodeMap->UnicodeFromCID(static_cast(CID)); - if (this_unicode == unicode) - return CID; - CID++; - } - break; - } - } - - if (unicode < 0x80) - return static_cast(unicode); - if (m_pCMap->m_Coding == CIDCODING_CID) - return 0; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ - uint8_t buffer[32]; - int ret = FXSYS_WideCharToMultiByte( - g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1, - reinterpret_cast(buffer), 4, nullptr, nullptr); - if (ret == 1) - return buffer[0]; - if (ret == 2) - return buffer[0] * 256 + buffer[1]; -#else - if (m_pCMap->m_pEmbedMap) { - return EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, - unicode); - } -#endif - return 0; -} - -bool CPDF_CIDFont::Load() { - if (m_pFontDict->GetStringFor("Subtype") == "TrueType") { - LoadGB2312(); - return true; - } - - CPDF_Array* pFonts = m_pFontDict->GetArrayFor("DescendantFonts"); - if (!pFonts || pFonts->GetCount() != 1) - return false; - - CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0); - if (!pCIDFontDict) - return false; - - m_BaseFont = pCIDFontDict->GetStringFor("BaseFont"); - if ((m_BaseFont.Compare("CourierStd") == 0 || - m_BaseFont.Compare("CourierStd-Bold") == 0 || - m_BaseFont.Compare("CourierStd-BoldOblique") == 0 || - m_BaseFont.Compare("CourierStd-Oblique") == 0) && - !IsEmbedded()) { - m_bAdobeCourierStd = true; - } - CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictFor("FontDescriptor"); - if (pFontDesc) - LoadFontDescriptor(pFontDesc); - - CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); - if (!pEncoding) - return false; - - CFX_ByteString subtype = pCIDFontDict->GetStringFor("Subtype"); - m_bType1 = (subtype == "CIDFontType0"); - - CPDF_CMapManager& manager = GetFontGlobals()->m_CMapManager; - if (pEncoding->IsName()) { - CFX_ByteString cmap = pEncoding->GetString(); - bool bPromptCJK = m_pFontFile && m_bType1; - m_pCMap = manager.GetPredefinedCMap(cmap, bPromptCJK); - if (!m_pCMap) - return false; - } else if (CPDF_Stream* pStream = pEncoding->AsStream()) { - m_pCMap = new CPDF_CMap; - m_pAllocatedCMap.reset(m_pCMap); - CPDF_StreamAcc acc; - acc.LoadAllData(pStream, FALSE); - m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize()); - } else { - return false; - } - - m_Charset = m_pCMap->m_Charset; - if (m_Charset == CIDSET_UNKNOWN) { - CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictFor("CIDSystemInfo"); - if (pCIDInfo) { - m_Charset = - CharsetFromOrdering(pCIDInfo->GetStringFor("Ordering").AsStringC()); - } - } - if (m_Charset != CIDSET_UNKNOWN) { - bool bPromptCJK = !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID || - pCIDFontDict->KeyExist("W")); - m_pCID2UnicodeMap = manager.GetCID2UnicodeMap(m_Charset, bPromptCJK); - } - if (m_Font.GetFace()) { - if (m_bType1) - FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); - else - FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding); - } - m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000); - CPDF_Array* pWidthArray = pCIDFontDict->GetArrayFor("W"); - if (pWidthArray) - LoadMetricsArray(pWidthArray, m_WidthList, 1); - if (!IsEmbedded()) - LoadSubstFont(); - - if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) { - CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap"); - if (pmap) { - if (CPDF_Stream* pStream = pmap->AsStream()) { - m_pStreamAcc.reset(new CPDF_StreamAcc); - m_pStreamAcc->LoadAllData(pStream, FALSE); - } else if (pmap->GetString() == "Identity") { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (m_pFontFile) - m_bCIDIsGID = true; -#else - m_bCIDIsGID = true; -#endif - } - } - } - - CheckFontMetrics(); - if (IsVertWriting()) { - pWidthArray = pCIDFontDict->GetArrayFor("W2"); - if (pWidthArray) - LoadMetricsArray(pWidthArray, m_VertMetrics, 3); - CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayFor("DW2"); - if (pDefaultArray) { - m_DefaultVY = pDefaultArray->GetIntegerAt(0); - m_DefaultW1 = pDefaultArray->GetIntegerAt(1); - } else { - m_DefaultVY = 880; - m_DefaultW1 = -1000; - } - } - return true; -} - -FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) { - if (charcode < 256 && m_CharBBox[charcode].right != -1) - return m_CharBBox[charcode]; - - FX_RECT rect; - bool bVert = false; - int glyph_index = GlyphFromCharCode(charcode, &bVert); - FXFT_Face face = m_Font.GetFace(); - if (face) { - if (FXFT_Is_Face_Tricky(face)) { - int err = FXFT_Load_Glyph(face, glyph_index, - FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - if (!err) { - FXFT_BBox cbox; - FXFT_Glyph glyph; - err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph); - if (!err) { - FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); - int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem; - int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem; - if (pixel_size_x == 0 || pixel_size_y == 0) { - rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin); - } else { - rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x, - cbox.yMax * 1000 / pixel_size_y, - cbox.xMax * 1000 / pixel_size_x, - cbox.yMin * 1000 / pixel_size_y); - } - rect.top = std::min(rect.top, - static_cast(FXFT_Get_Face_Ascender(face))); - rect.bottom = std::max( - rect.bottom, static_cast(FXFT_Get_Face_Descender(face))); - FXFT_Done_Glyph(glyph); - } - } - } else { - int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE); - if (err == 0) { - rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face), - TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face), - TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + - FXFT_Get_Glyph_Width(face), - face), - TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - - FXFT_Get_Glyph_Height(face), - face)); - rect.top += rect.top / 64; - } - } - } - if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) { - uint16_t CID = CIDFromCharCode(charcode); - const uint8_t* pTransform = GetCIDTransform(CID); - if (pTransform && !bVert) { - CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]), - CIDTransformToFloat(pTransform[1]), - CIDTransformToFloat(pTransform[2]), - CIDTransformToFloat(pTransform[3]), - CIDTransformToFloat(pTransform[4]) * 1000, - CIDTransformToFloat(pTransform[5]) * 1000); - CFX_FloatRect rect_f(rect); - rect_f.Transform(&matrix); - rect = rect_f.GetOuterRect(); - } - } - if (charcode < 256) - m_CharBBox[charcode] = rect; - - return rect; -} - -int CPDF_CIDFont::GetCharWidthF(uint32_t charcode) { - if (charcode < 0x80 && m_bAnsiWidthsFixed) - return (charcode >= 32 && charcode < 127) ? 500 : 0; - - uint16_t cid = CIDFromCharCode(charcode); - int size = m_WidthList.GetSize(); - const uint32_t* pList = m_WidthList.GetData(); - for (int i = 0; i < size; i += 3) { - const uint32_t* pEntry = pList + i; - if (IsMetricForCID(pEntry, cid)) - return static_cast(pEntry[2]); - } - return m_DefaultWidth; -} - -short CPDF_CIDFont::GetVertWidth(uint16_t CID) const { - uint32_t vertsize = m_VertMetrics.GetSize() / 5; - if (vertsize) { - const uint32_t* pTable = m_VertMetrics.GetData(); - for (uint32_t i = 0; i < vertsize; i++) { - const uint32_t* pEntry = pTable + (i * 5); - if (IsMetricForCID(pEntry, CID)) - return static_cast(pEntry[2]); - } - } - return m_DefaultW1; -} - -void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const { - uint32_t vertsize = m_VertMetrics.GetSize() / 5; - if (vertsize) { - const uint32_t* pTable = m_VertMetrics.GetData(); - for (uint32_t i = 0; i < vertsize; i++) { - const uint32_t* pEntry = pTable + (i * 5); - if (IsMetricForCID(pEntry, CID)) { - vx = static_cast(pEntry[3]); - vy = static_cast(pEntry[4]); - return; - } - } - } - uint32_t dwWidth = m_DefaultWidth; - int size = m_WidthList.GetSize(); - const uint32_t* pList = m_WidthList.GetData(); - for (int i = 0; i < size; i += 3) { - const uint32_t* pEntry = pList + i; - if (IsMetricForCID(pEntry, CID)) { - dwWidth = pEntry[2]; - break; - } - } - vx = static_cast(dwWidth) / 2; - vy = m_DefaultVY; -} - -int CPDF_CIDFont::GetGlyphIndex(uint32_t unicode, bool* pVertGlyph) { - if (pVertGlyph) - *pVertGlyph = false; - - FXFT_Face face = m_Font.GetFace(); - int index = FXFT_Get_Char_Index(face, unicode); - if (unicode == 0x2502) - return index; - - if (!index || !IsVertWriting()) - return index; - - if (m_pTTGSUBTable) - return GetVerticalGlyph(index, pVertGlyph); - - if (!m_Font.GetSubData()) { - unsigned long length = 0; - int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, - nullptr, &length); - if (!error) - m_Font.SetSubData(FX_Alloc(uint8_t, length)); - } - int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, - m_Font.GetSubData(), nullptr); - if (error || !m_Font.GetSubData()) - return index; - - m_pTTGSUBTable.reset(new CFX_CTTGSUBTable); - m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData()); - return GetVerticalGlyph(index, pVertGlyph); -} - -int CPDF_CIDFont::GetVerticalGlyph(int index, bool* pVertGlyph) { - uint32_t vindex = 0; - m_pTTGSUBTable->GetVerticalGlyph(index, &vindex); - if (!vindex) - return index; - - index = vindex; - if (pVertGlyph) - *pVertGlyph = true; - return index; -} - -int CPDF_CIDFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { - if (pVertGlyph) - *pVertGlyph = FALSE; - - if (!m_pFontFile && !m_pStreamAcc) { - uint16_t cid = CIDFromCharCode(charcode); - FX_WCHAR unicode = 0; - if (m_bCIDIsGID) { -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ - return cid; -#else - if (m_Flags & PDFFONT_SYMBOLIC) - return cid; - - CFX_WideString uni_str = UnicodeFromCharCode(charcode); - if (uni_str.IsEmpty()) - return cid; - - unicode = uni_str.GetAt(0); -#endif - } else { - if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) - unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid); - if (unicode == 0) - unicode = GetUnicodeFromCharCode(charcode); - if (unicode == 0) { - CFX_WideString unicode_str = UnicodeFromCharCode(charcode); - if (!unicode_str.IsEmpty()) - unicode = unicode_str.GetAt(0); - } - } - FXFT_Face face = m_Font.GetFace(); - if (unicode == 0) { - if (!m_bAdobeCourierStd) - return charcode ? static_cast(charcode) : -1; - - charcode += 31; - bool bMSUnicode = FT_UseTTCharmap(face, 3, 1); - bool bMacRoman = !bMSUnicode && FT_UseTTCharmap(face, 1, 0); - int iBaseEncoding = PDFFONT_ENCODING_STANDARD; - if (bMSUnicode) - iBaseEncoding = PDFFONT_ENCODING_WINANSI; - else if (bMacRoman) - iBaseEncoding = PDFFONT_ENCODING_MACROMAN; - const FX_CHAR* name = GetAdobeCharName( - iBaseEncoding, std::vector(), charcode); - if (!name) - return charcode ? static_cast(charcode) : -1; - - int index = 0; - uint16_t name_unicode = PDF_UnicodeFromAdobeName(name); - if (!name_unicode) - return charcode ? static_cast(charcode) : -1; - - if (iBaseEncoding == PDFFONT_ENCODING_STANDARD) - return FXFT_Get_Char_Index(face, name_unicode); - - if (iBaseEncoding == PDFFONT_ENCODING_WINANSI) { - index = FXFT_Get_Char_Index(face, name_unicode); - } else { - ASSERT(iBaseEncoding == PDFFONT_ENCODING_MACROMAN); - uint32_t maccode = - FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, name_unicode); - index = maccode ? FXFT_Get_Char_Index(face, maccode) - : FXFT_Get_Name_Index(face, const_cast(name)); - } - if (index == 0 || index == 0xffff) - return charcode ? static_cast(charcode) : -1; - return index; - } - if (m_Charset == CIDSET_JAPAN1) { - if (unicode == '\\') { - unicode = '/'; -#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ - } else if (unicode == 0xa5) { - unicode = 0x5c; -#endif - } - } - if (!face) - return unicode; - - int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); - if (err) { - int i; - for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { - uint32_t ret = FT_CharCodeFromUnicode( - FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]), - static_cast(charcode)); - if (ret == 0) - continue; - FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); - unicode = static_cast(ret); - break; - } - if (i == FXFT_Get_Face_CharmapCount(face) && i) { - FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); - unicode = static_cast(charcode); - } - } - if (FXFT_Get_Face_Charmap(face)) { - int index = GetGlyphIndex(unicode, pVertGlyph); - return index != 0 ? index : -1; - } - return unicode; - } - - if (!m_Font.GetFace()) - return -1; - - uint16_t cid = CIDFromCharCode(charcode); - if (!m_pStreamAcc) { - if (m_bType1) - return cid; - - if (m_pFontFile && !m_pCMap->m_pMapping) - return cid; - if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || - !FXFT_Get_Face_Charmap(m_Font.GetFace())) { - return cid; - } - if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) == - FXFT_ENCODING_UNICODE) { - CFX_WideString unicode_str = UnicodeFromCharCode(charcode); - if (unicode_str.IsEmpty()) - return -1; - - charcode = unicode_str.GetAt(0); - } - return GetGlyphIndex(charcode, pVertGlyph); - } - uint32_t byte_pos = cid * 2; - if (byte_pos + 2 > m_pStreamAcc->GetSize()) - return -1; - - const uint8_t* pdata = m_pStreamAcc->GetData() + byte_pos; - return pdata[0] * 256 + pdata[1]; -} - -uint32_t CPDF_CIDFont::GetNextChar(const FX_CHAR* pString, - int nStrLen, - int& offset) const { - return m_pCMap->GetNextChar(pString, nStrLen, offset); -} - -int CPDF_CIDFont::GetCharSize(uint32_t charcode) const { - return m_pCMap->GetCharSize(charcode); -} - -int CPDF_CIDFont::CountChar(const FX_CHAR* pString, int size) const { - return m_pCMap->CountChar(pString, size); -} - -int CPDF_CIDFont::AppendChar(FX_CHAR* str, uint32_t charcode) const { - return m_pCMap->AppendChar(str, charcode); -} - -bool CPDF_CIDFont::IsUnicodeCompatible() const { - if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded()) - return true; - return m_pCMap->m_Coding != CIDCODING_UNKNOWN; -} - -void CPDF_CIDFont::LoadSubstFont() { - pdfium::base::CheckedNumeric safeStemV(m_StemV); - safeStemV *= 5; - m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, - safeStemV.ValueOrDefault(FXFONT_FW_NORMAL), m_ItalicAngle, - g_CharsetCPs[m_Charset], IsVertWriting()); -} - -void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray, - CFX_ArrayTemplate& result, - int nElements) { - int width_status = 0; - int iCurElement = 0; - int first_code = 0; - int last_code = 0; - for (size_t i = 0; i < pArray->GetCount(); i++) { - CPDF_Object* pObj = pArray->GetDirectObjectAt(i); - if (!pObj) - continue; - - if (CPDF_Array* pObjArray = pObj->AsArray()) { - if (width_status != 1) - return; - - for (size_t j = 0; j < pObjArray->GetCount(); j += nElements) { - result.Add(first_code); - result.Add(first_code); - for (int k = 0; k < nElements; k++) - result.Add(pObjArray->GetIntegerAt(j + k)); - first_code++; - } - width_status = 0; - } else { - if (width_status == 0) { - first_code = pObj->GetInteger(); - width_status = 1; - } else if (width_status == 1) { - last_code = pObj->GetInteger(); - width_status = 2; - iCurElement = 0; - } else { - if (!iCurElement) { - result.Add(first_code); - result.Add(last_code); - } - result.Add(pObj->GetInteger()); - iCurElement++; - if (iCurElement == nElements) - width_status = 0; - } - } - } -} - -// static -FX_FLOAT CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) { - return (ch < 128 ? ch : ch - 255) * (1.0f / 127); -} - -void CPDF_CIDFont::LoadGB2312() { - m_BaseFont = m_pFontDict->GetStringFor("BaseFont"); - CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); - if (pFontDesc) - LoadFontDescriptor(pFontDesc); - - m_Charset = CIDSET_GB1; - m_bType1 = false; - CPDF_CMapManager& manager = GetFontGlobals()->m_CMapManager; - m_pCMap = manager.GetPredefinedCMap("GBK-EUC-H", false); - m_pCID2UnicodeMap = manager.GetCID2UnicodeMap(m_Charset, false); - if (!IsEmbedded()) - LoadSubstFont(); - - CheckFontMetrics(); - m_DefaultWidth = 1000; - m_bAnsiWidthsFixed = true; -} - -const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const { - if (m_Charset != CIDSET_JAPAN1 || m_pFontFile) - return nullptr; - - const auto* pEnd = g_Japan1_VertCIDs + FX_ArraySize(g_Japan1_VertCIDs); - const auto* pTransform = std::lower_bound( - g_Japan1_VertCIDs, pEnd, CID, - [](const CIDTransform& entry, uint16_t cid) { return entry.cid < cid; }); - return (pTransform < pEnd && CID == pTransform->cid) ? &pTransform->a - : nullptr; -} diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.h b/core/fpdfapi/fpdf_font/cpdf_cidfont.h deleted file mode 100644 index 3e8c042c75..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_cidfont.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_CIDFONT_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_CIDFONT_H_ - -#include - -#include "core/fpdfapi/fpdf_font/cpdf_font.h" -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/fx_system.h" - -enum CIDSet { - CIDSET_UNKNOWN, - CIDSET_GB1, - CIDSET_CNS1, - CIDSET_JAPAN1, - CIDSET_KOREA1, - CIDSET_UNICODE, - CIDSET_NUM_SETS -}; - -class CFX_CTTGSUBTable; -class CPDF_Array; -class CPDF_CID2UnicodeMap; -class CPDF_CMap; -class CPDF_StreamAcc; - -class CPDF_CIDFont : public CPDF_Font { - public: - CPDF_CIDFont(); - ~CPDF_CIDFont() override; - - static FX_FLOAT CIDTransformToFloat(uint8_t ch); - - // CPDF_Font: - bool IsCIDFont() const override; - const CPDF_CIDFont* AsCIDFont() const override; - CPDF_CIDFont* AsCIDFont() override; - int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) override; - int GetCharWidthF(uint32_t charcode) override; - FX_RECT GetCharBBox(uint32_t charcode) override; - uint32_t GetNextChar(const FX_CHAR* pString, - int nStrLen, - int& offset) const override; - int CountChar(const FX_CHAR* pString, int size) const override; - int AppendChar(FX_CHAR* str, uint32_t charcode) const override; - int GetCharSize(uint32_t charcode) const override; - bool IsVertWriting() const override; - bool IsUnicodeCompatible() const override; - bool Load() override; - CFX_WideString UnicodeFromCharCode(uint32_t charcode) const override; - uint32_t CharCodeFromUnicode(FX_WCHAR Unicode) const override; - - uint16_t CIDFromCharCode(uint32_t charcode) const; - const uint8_t* GetCIDTransform(uint16_t CID) const; - short GetVertWidth(uint16_t CID) const; - void GetVertOrigin(uint16_t CID, short& vx, short& vy) const; - - protected: - void LoadGB2312(); - int GetGlyphIndex(uint32_t unicodeb, bool* pVertGlyph); - int GetVerticalGlyph(int index, bool* pVertGlyph); - void LoadMetricsArray(CPDF_Array* pArray, - CFX_ArrayTemplate& result, - int nElements); - void LoadSubstFont(); - FX_WCHAR GetUnicodeFromCharCode(uint32_t charcode) const; - - CPDF_CMap* m_pCMap; - std::unique_ptr m_pAllocatedCMap; - CPDF_CID2UnicodeMap* m_pCID2UnicodeMap; - CIDSet m_Charset; - bool m_bType1; - bool m_bCIDIsGID; - uint16_t m_DefaultWidth; - std::unique_ptr m_pStreamAcc; - bool m_bAnsiWidthsFixed; - FX_RECT m_CharBBox[256]; - CFX_ArrayTemplate m_WidthList; - short m_DefaultVY; - short m_DefaultW1; - CFX_ArrayTemplate m_VertMetrics; - bool m_bAdobeCourierStd; - std::unique_ptr m_pTTGSUBTable; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_CIDFONT_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_font.cpp b/core/fpdfapi/fpdf_font/cpdf_font.cpp deleted file mode 100644 index 96ebda740a..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_font.cpp +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_font.h" - -#include -#include - -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" -#include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h" -#include "core/fpdfapi/fpdf_font/cpdf_type1font.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_name.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fxcrt/fx_memory.h" -#include "core/fxge/fx_freetype.h" -#include "third_party/base/ptr_util.h" -#include "third_party/base/stl_util.h" - -namespace { - -const uint8_t kChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00}, - {0xBF, 0xAC, 0xCC, 0xE5, 0x00}, - {0xBA, 0xDA, 0xCC, 0xE5, 0x00}, - {0xB7, 0xC2, 0xCB, 0xCE, 0x00}, - {0xD0, 0xC2, 0xCB, 0xCE, 0x00}}; - -void GetPredefinedEncoding(const CFX_ByteString& value, int* basemap) { - if (value == "WinAnsiEncoding") - *basemap = PDFFONT_ENCODING_WINANSI; - else if (value == "MacRomanEncoding") - *basemap = PDFFONT_ENCODING_MACROMAN; - else if (value == "MacExpertEncoding") - *basemap = PDFFONT_ENCODING_MACEXPERT; - else if (value == "PDFDocEncoding") - *basemap = PDFFONT_ENCODING_PDFDOC; -} - -} // namespace - -CPDF_Font::CPDF_Font() - : m_pFontFile(nullptr), - m_pFontDict(nullptr), - m_bToUnicodeLoaded(false), - m_Flags(0), - m_StemV(0), - m_Ascent(0), - m_Descent(0), - m_ItalicAngle(0) {} - -CPDF_Font::~CPDF_Font() { - if (m_pFontFile) { - m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( - m_pFontFile->GetStream()->AsStream()); - } -} - -bool CPDF_Font::IsType1Font() const { - return false; -} - -bool CPDF_Font::IsTrueTypeFont() const { - return false; -} - -bool CPDF_Font::IsType3Font() const { - return false; -} - -bool CPDF_Font::IsCIDFont() const { - return false; -} - -const CPDF_Type1Font* CPDF_Font::AsType1Font() const { - return nullptr; -} - -CPDF_Type1Font* CPDF_Font::AsType1Font() { - return nullptr; -} - -const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const { - return nullptr; -} - -CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() { - return nullptr; -} - -const CPDF_Type3Font* CPDF_Font::AsType3Font() const { - return nullptr; -} - -CPDF_Type3Font* CPDF_Font::AsType3Font() { - return nullptr; -} - -const CPDF_CIDFont* CPDF_Font::AsCIDFont() const { - return nullptr; -} - -CPDF_CIDFont* CPDF_Font::AsCIDFont() { - return nullptr; -} - -bool CPDF_Font::IsUnicodeCompatible() const { - return false; -} - -int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const { - return size; -} - -int CPDF_Font::GetCharSize(uint32_t charcode) const { - return 1; -} - -int CPDF_Font::GlyphFromCharCodeExt(uint32_t charcode) { - return GlyphFromCharCode(charcode, nullptr); -} - -bool CPDF_Font::IsVertWriting() const { - const CPDF_CIDFont* pCIDFont = AsCIDFont(); - return pCIDFont ? pCIDFont->IsVertWriting() : m_Font.IsVertical(); -} - -int CPDF_Font::AppendChar(FX_CHAR* buf, uint32_t charcode) const { - *buf = static_cast(charcode); - return 1; -} - -void CPDF_Font::AppendChar(CFX_ByteString& str, uint32_t charcode) const { - char buf[4]; - int len = AppendChar(buf, charcode); - if (len == 1) { - str += buf[0]; - } else { - str += CFX_ByteString(buf, len); - } -} - -CFX_WideString CPDF_Font::UnicodeFromCharCode(uint32_t charcode) const { - if (!m_bToUnicodeLoaded) - LoadUnicodeMap(); - - return m_pToUnicodeMap ? m_pToUnicodeMap->Lookup(charcode) : CFX_WideString(); -} - -uint32_t CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { - if (!m_bToUnicodeLoaded) - LoadUnicodeMap(); - - return m_pToUnicodeMap ? m_pToUnicodeMap->ReverseLookup(unicode) : 0; -} - -void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { - m_Flags = pFontDesc->GetIntegerFor("Flags", PDFFONT_NONSYMBOLIC); - int ItalicAngle = 0; - FX_BOOL bExistItalicAngle = FALSE; - if (pFontDesc->KeyExist("ItalicAngle")) { - ItalicAngle = pFontDesc->GetIntegerFor("ItalicAngle"); - bExistItalicAngle = TRUE; - } - if (ItalicAngle < 0) { - m_Flags |= PDFFONT_ITALIC; - m_ItalicAngle = ItalicAngle; - } - FX_BOOL bExistStemV = FALSE; - if (pFontDesc->KeyExist("StemV")) { - m_StemV = pFontDesc->GetIntegerFor("StemV"); - bExistStemV = TRUE; - } - FX_BOOL bExistAscent = FALSE; - if (pFontDesc->KeyExist("Ascent")) { - m_Ascent = pFontDesc->GetIntegerFor("Ascent"); - bExistAscent = TRUE; - } - FX_BOOL bExistDescent = FALSE; - if (pFontDesc->KeyExist("Descent")) { - m_Descent = pFontDesc->GetIntegerFor("Descent"); - bExistDescent = TRUE; - } - FX_BOOL bExistCapHeight = FALSE; - if (pFontDesc->KeyExist("CapHeight")) { - bExistCapHeight = TRUE; - } - if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && - bExistStemV) { - m_Flags |= PDFFONT_USEEXTERNATTR; - } - if (m_Descent > 10) { - m_Descent = -m_Descent; - } - CPDF_Array* pBBox = pFontDesc->GetArrayFor("FontBBox"); - if (pBBox) { - m_FontBBox.left = pBBox->GetIntegerAt(0); - m_FontBBox.bottom = pBBox->GetIntegerAt(1); - m_FontBBox.right = pBBox->GetIntegerAt(2); - m_FontBBox.top = pBBox->GetIntegerAt(3); - } - - CPDF_Stream* pFontFile = pFontDesc->GetStreamFor("FontFile"); - if (!pFontFile) - pFontFile = pFontDesc->GetStreamFor("FontFile2"); - if (!pFontFile) - pFontFile = pFontDesc->GetStreamFor("FontFile3"); - if (!pFontFile) - return; - - m_pFontFile = m_pDocument->LoadFontFile(pFontFile); - if (!m_pFontFile) - return; - - const uint8_t* pFontData = m_pFontFile->GetData(); - uint32_t dwFontSize = m_pFontFile->GetSize(); - if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) { - m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( - m_pFontFile->GetStream()->AsStream()); - m_pFontFile = nullptr; - } -} - -void CPDF_Font::CheckFontMetrics() { - if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && - m_FontBBox.right == 0) { - FXFT_Face face = m_Font.GetFace(); - if (face) { - m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face); - m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face); - m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face); - m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face); - m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face); - m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face); - } else { - FX_BOOL bFirst = TRUE; - for (int i = 0; i < 256; i++) { - FX_RECT rect = GetCharBBox(i); - if (rect.left == rect.right) { - continue; - } - if (bFirst) { - m_FontBBox = rect; - bFirst = FALSE; - } else { - if (m_FontBBox.top < rect.top) { - m_FontBBox.top = rect.top; - } - if (m_FontBBox.right < rect.right) { - m_FontBBox.right = rect.right; - } - if (m_FontBBox.left > rect.left) { - m_FontBBox.left = rect.left; - } - if (m_FontBBox.bottom > rect.bottom) { - m_FontBBox.bottom = rect.bottom; - } - } - } - } - } - if (m_Ascent == 0 && m_Descent == 0) { - FX_RECT rect = GetCharBBox('A'); - m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top; - rect = GetCharBBox('g'); - m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom; - } -} - -void CPDF_Font::LoadUnicodeMap() const { - m_bToUnicodeLoaded = true; - CPDF_Stream* pStream = m_pFontDict->GetStreamFor("ToUnicode"); - if (!pStream) { - return; - } - m_pToUnicodeMap.reset(new CPDF_ToUnicodeMap); - m_pToUnicodeMap->Load(pStream); -} - -int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) { - int offset = 0; - int width = 0; - while (offset < size) { - uint32_t charcode = GetNextChar(pString, size, offset); - width += GetCharWidthF(charcode); - } - return width; -} - -CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, - const CFX_ByteStringC& name) { - CFX_ByteString fontname(name); - int font_id = PDF_GetStandardFontName(&fontname); - if (font_id < 0) - return nullptr; - - CPDF_FontGlobals* pFontGlobals = - CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); - CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); - if (pFont) - return pFont; - - CPDF_Dictionary* pDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); - pDict->SetNameFor("Type", "Font"); - pDict->SetNameFor("Subtype", "Type1"); - pDict->SetNameFor("BaseFont", fontname); - pDict->SetNameFor("Encoding", "WinAnsiEncoding"); - return pFontGlobals->Set(pDoc, font_id, CPDF_Font::Create(nullptr, pDict)); -} - -std::unique_ptr CPDF_Font::Create(CPDF_Document* pDoc, - CPDF_Dictionary* pFontDict) { - CFX_ByteString type = pFontDict->GetStringFor("Subtype"); - std::unique_ptr pFont; - if (type == "TrueType") { - CFX_ByteString tag = pFontDict->GetStringFor("BaseFont").Left(4); - for (size_t i = 0; i < FX_ArraySize(kChineseFontNames); ++i) { - if (tag == CFX_ByteString(kChineseFontNames[i], 4)) { - CPDF_Dictionary* pFontDesc = pFontDict->GetDictFor("FontDescriptor"); - if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) - pFont.reset(new CPDF_CIDFont); - break; - } - } - if (!pFont) - pFont.reset(new CPDF_TrueTypeFont); - } else if (type == "Type3") { - pFont.reset(new CPDF_Type3Font); - } else if (type == "Type0") { - pFont.reset(new CPDF_CIDFont); - } else { - pFont.reset(new CPDF_Type1Font); - } - pFont->m_pFontDict = pFontDict; - pFont->m_pDocument = pDoc; - pFont->m_BaseFont = pFontDict->GetStringFor("BaseFont"); - return pFont->Load() ? std::move(pFont) : std::unique_ptr(); -} - -uint32_t CPDF_Font::GetNextChar(const FX_CHAR* pString, - int nStrLen, - int& offset) const { - if (offset < 0 || nStrLen < 1) { - return 0; - } - uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1]; - return static_cast(ch); -} - -void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, - int& iBaseEncoding, - std::vector* pCharNames, - bool bEmbedded, - bool bTrueType) { - if (!pEncoding) { - if (m_BaseFont == "Symbol") { - iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL - : PDFFONT_ENCODING_ADOBE_SYMBOL; - } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { - iBaseEncoding = PDFFONT_ENCODING_WINANSI; - } - return; - } - if (pEncoding->IsName()) { - if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || - iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { - return; - } - if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") { - if (!bTrueType) { - iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; - } - return; - } - CFX_ByteString bsEncoding = pEncoding->GetString(); - if (bsEncoding.Compare("MacExpertEncoding") == 0) { - bsEncoding = "WinAnsiEncoding"; - } - GetPredefinedEncoding(bsEncoding, &iBaseEncoding); - return; - } - - CPDF_Dictionary* pDict = pEncoding->AsDictionary(); - if (!pDict) - return; - - if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && - iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { - CFX_ByteString bsEncoding = pDict->GetStringFor("BaseEncoding"); - if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) { - bsEncoding = "WinAnsiEncoding"; - } - GetPredefinedEncoding(bsEncoding, &iBaseEncoding); - } - if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) - iBaseEncoding = PDFFONT_ENCODING_STANDARD; - - CPDF_Array* pDiffs = pDict->GetArrayFor("Differences"); - if (!pDiffs) - return; - - pCharNames->resize(256); - uint32_t cur_code = 0; - for (uint32_t i = 0; i < pDiffs->GetCount(); i++) { - CPDF_Object* pElement = pDiffs->GetDirectObjectAt(i); - if (!pElement) - continue; - - if (CPDF_Name* pName = pElement->AsName()) { - if (cur_code < 256) - (*pCharNames)[cur_code] = pName->GetString(); - cur_code++; - } else { - cur_code = pElement->GetInteger(); - } - } -} - -bool CPDF_Font::IsStandardFont() const { - if (!IsType1Font()) - return false; - if (m_pFontFile) - return false; - if (AsType1Font()->GetBase14Font() < 0) - return false; - return true; -} - -const FX_CHAR* CPDF_Font::GetAdobeCharName( - int iBaseEncoding, - const std::vector& charnames, - int charcode) { - if (charcode < 0 || charcode >= 256) { - ASSERT(false); - return nullptr; - } - - if (!charnames.empty() && !charnames[charcode].IsEmpty()) - return charnames[charcode].c_str(); - - const FX_CHAR* name = nullptr; - if (iBaseEncoding) - name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); - return name && name[0] ? name : nullptr; -} - -uint32_t CPDF_Font::FallbackFontFromCharcode(uint32_t charcode) { - if (m_FontFallbacks.empty()) { - m_FontFallbacks.push_back(pdfium::MakeUnique()); - m_FontFallbacks[0]->LoadSubst("Arial", IsTrueTypeFont(), m_Flags, - m_StemV * 5, m_ItalicAngle, 0, - IsVertWriting()); - } - return 0; -} - -int CPDF_Font::FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode) { - if (fallbackFont < 0 || - fallbackFont >= pdfium::CollectionSize(m_FontFallbacks)) { - return -1; - } - int glyph = - FXFT_Get_Char_Index(m_FontFallbacks[fallbackFont]->GetFace(), charcode); - if (glyph == 0 || glyph == 0xffff) - return -1; - return glyph; -} diff --git a/core/fpdfapi/fpdf_font/cpdf_font.h b/core/fpdfapi/fpdf_font/cpdf_font.h deleted file mode 100644 index 0d2f50b61a..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_font.h +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_FONT_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_FONT_H_ - -#include -#include - -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/fx_system.h" -#include "core/fxge/fx_font.h" - -#define PDFFONT_FIXEDPITCH 1 -#define PDFFONT_SERIF 2 -#define PDFFONT_SYMBOLIC 4 -#define PDFFONT_SCRIPT 8 -#define PDFFONT_NONSYMBOLIC 32 -#define PDFFONT_ITALIC 64 -#define PDFFONT_ALLCAP 0x10000 -#define PDFFONT_SMALLCAP 0x20000 -#define PDFFONT_FORCEBOLD 0x40000 -#define PDFFONT_USEEXTERNATTR 0x80000 - -class CFX_SubstFont; -class CPDF_CIDFont; -class CPDF_Dictionary; -class CPDF_Document; -class CPDF_Object; -class CPDF_StreamAcc; -class CPDF_TrueTypeFont; -class CPDF_Type1Font; -class CPDF_Type3Font; -class CPDF_ToUnicodeMap; - -class CPDF_Font { - public: - static std::unique_ptr Create(CPDF_Document* pDoc, - CPDF_Dictionary* pFontDict); - static CPDF_Font* GetStockFont(CPDF_Document* pDoc, - const CFX_ByteStringC& fontname); - static const uint32_t kInvalidCharCode = static_cast(-1); - - virtual ~CPDF_Font(); - - virtual bool IsType1Font() const; - virtual bool IsTrueTypeFont() const; - virtual bool IsType3Font() const; - virtual bool IsCIDFont() const; - virtual const CPDF_Type1Font* AsType1Font() const; - virtual CPDF_Type1Font* AsType1Font(); - virtual const CPDF_TrueTypeFont* AsTrueTypeFont() const; - virtual CPDF_TrueTypeFont* AsTrueTypeFont(); - virtual const CPDF_Type3Font* AsType3Font() const; - virtual CPDF_Type3Font* AsType3Font(); - virtual const CPDF_CIDFont* AsCIDFont() const; - virtual CPDF_CIDFont* AsCIDFont(); - - virtual bool IsVertWriting() const; - virtual bool IsUnicodeCompatible() const; - virtual uint32_t GetNextChar(const FX_CHAR* pString, - int nStrLen, - int& offset) const; - virtual int CountChar(const FX_CHAR* pString, int size) const; - virtual int AppendChar(FX_CHAR* buf, uint32_t charcode) const; - virtual int GetCharSize(uint32_t charcode) const; - virtual int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) = 0; - virtual int GlyphFromCharCodeExt(uint32_t charcode); - virtual CFX_WideString UnicodeFromCharCode(uint32_t charcode) const; - virtual uint32_t CharCodeFromUnicode(FX_WCHAR Unicode) const; - - const CFX_ByteString& GetBaseFont() const { return m_BaseFont; } - CFX_SubstFont* GetSubstFont() const { return m_Font.GetSubstFont(); } - uint32_t GetFlags() const { return m_Flags; } - bool IsEmbedded() const { return IsType3Font() || m_pFontFile != nullptr; } - CPDF_StreamAcc* GetFontFile() const { return m_pFontFile; } - CPDF_Dictionary* GetFontDict() const { return m_pFontDict; } - bool IsStandardFont() const; - FXFT_Face GetFace() const { return m_Font.GetFace(); } - void AppendChar(CFX_ByteString& str, uint32_t charcode) const; - - void GetFontBBox(FX_RECT& rect) const { rect = m_FontBBox; } - int GetTypeAscent() const { return m_Ascent; } - int GetTypeDescent() const { return m_Descent; } - int GetItalicAngle() const { return m_ItalicAngle; } - int GetStemV() const { return m_StemV; } - int GetStringWidth(const FX_CHAR* pString, int size); - uint32_t FallbackFontFromCharcode(uint32_t charcode); - int FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode); - - virtual int GetCharWidthF(uint32_t charcode) = 0; - virtual FX_RECT GetCharBBox(uint32_t charcode) = 0; - - CPDF_Document* m_pDocument; - CFX_Font m_Font; - std::vector> m_FontFallbacks; - - protected: - CPDF_Font(); - - virtual bool Load() = 0; - - void LoadUnicodeMap() const; // logically const only. - void LoadPDFEncoding(CPDF_Object* pEncoding, - int& iBaseEncoding, - std::vector* pCharNames, - bool bEmbedded, - bool bTrueType); - void LoadFontDescriptor(CPDF_Dictionary* pDict); - void CheckFontMetrics(); - - const FX_CHAR* GetAdobeCharName(int iBaseEncoding, - const std::vector& charnames, - int charcode); - - CFX_ByteString m_BaseFont; - CPDF_StreamAcc* m_pFontFile; - CPDF_Dictionary* m_pFontDict; - mutable std::unique_ptr m_pToUnicodeMap; - mutable bool m_bToUnicodeLoaded; - int m_Flags; - FX_RECT m_FontBBox; - int m_StemV; - int m_Ascent; - int m_Descent; - int m_ItalicAngle; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_FONT_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp deleted file mode 100644 index e373e01233..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp +++ /dev/null @@ -1,1818 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" - -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_name.h" -#include "core/fpdfapi/fpdf_parser/cpdf_number.h" -#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" -#include "core/fxge/fx_freetype.h" - -namespace { - -const uint16_t MSSymbolEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 32, 33, 8704, 35, - 8707, 37, 38, 8715, 40, 41, 8727, 43, 44, - 8722, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 8773, 913, 914, 935, 916, 917, 934, 915, - 919, 921, 977, 922, 923, 924, 925, 927, 928, - 920, 929, 931, 932, 933, 962, 937, 926, 936, - 918, 91, 8756, 93, 8869, 95, 8254, 945, 946, - 967, 948, 949, 966, 947, 951, 953, 981, 954, - 955, 956, 957, 959, 960, 952, 961, 963, 964, - 965, 982, 969, 958, 968, 950, 123, 124, 125, - 8764, 0, 0, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 978, - 8242, 8804, 8725, 8734, 402, 9827, 9830, 9828, 9824, - 8596, 8592, 8593, 8594, 8595, 176, 177, 8243, 8805, - 215, 8733, 8706, 8729, 247, 8800, 8801, 8776, 8943, - 0, 0, 8629, 0, 8465, 8476, 8472, 8855, 8853, - 8709, 8745, 8746, 8835, 8839, 8836, 8834, 8838, 8712, - 8713, 8736, 8711, 174, 169, 8482, 8719, 8730, 8901, - 172, 8743, 8744, 8660, 8656, 8657, 8658, 8659, 9674, - 9001, 0, 0, 0, 8721, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0x0000, 9002, 8747, - 8992, 0, 8993, 0, 0, 0, 0, 0, 0, - 0x0000, 0x0000, 0x0000, 0x0000}; - -const uint16_t StandardEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x2019, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x2018, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00a1, - 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, 0x00a4, 0x0027, 0x201c, - 0x00ab, 0x2039, 0x203a, 0xfb01, 0xfb02, 0x0000, 0x2013, 0x2020, 0x2021, - 0x00b7, 0x0000, 0x00b6, 0x2022, 0x201a, 0x201e, 0x201d, 0x00bb, 0x2026, - 0x2030, 0x0000, 0x00bf, 0x0000, 0x0060, 0x00b4, 0x02c6, 0x02dc, 0x00af, - 0x02d8, 0x02d9, 0x00a8, 0x0000, 0x02da, 0x00b8, 0x0000, 0x02dd, 0x02db, - 0x02c7, 0x2014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00c6, 0x0000, 0x00aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0141, 0x00d8, - 0x0152, 0x00ba, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00e6, 0x0000, - 0x0000, 0x0000, 0x0131, 0x0000, 0x0000, 0x0142, 0x00f8, 0x0153, 0x00df, - 0x0000, 0x0000, 0x0000, 0x0000}; - -const uint16_t MacRomanEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x0000, 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, - 0x00e1, 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, - 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, 0x00f2, - 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, 0x2020, 0x00b0, - 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, 0x00ae, 0x00a9, 0x2122, - 0x00b4, 0x00a8, 0x0000, 0x00c6, 0x00d8, 0x0000, 0x00b1, 0x0000, 0x0000, - 0x00a5, 0x00b5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00aa, 0x00ba, - 0x0000, 0x00e6, 0x00f8, 0x00bf, 0x00a3, 0x00ac, 0x0000, 0x0192, 0x0000, - 0x0000, 0x00ab, 0x00bb, 0x2026, 0x0020, 0x00c0, 0x00c3, 0x00d5, 0x0152, - 0x0153, 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x0000, - 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, 0x2021, - 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, 0x00cb, 0x00c8, - 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, 0x0000, 0x00d2, 0x00da, - 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da, - 0x00b8, 0x02dd, 0x02db, 0x02c7}; - -const uint16_t AdobeWinAnsiEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, - 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, - 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, - 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, - 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, - 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, - 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, - 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, - 0x007e, 0x2022, 0x20ac, 0x2022, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, - 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x2022, 0x017d, 0x2022, - 0x2022, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, - 0x2122, 0x0161, 0x203a, 0x0153, 0x2022, 0x017e, 0x0178, 0x0020, 0x00a1, - 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, - 0x00ab, 0x00ac, 0x002d, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, - 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, - 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, - 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, - 0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, - 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, - 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, - 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, - 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, - 0x00fc, 0x00fd, 0x00fe, 0x00ff}; - -const uint16_t MacExpertEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0xf721, 0xf6f8, 0xf7a2, - 0xf724, 0xf6e4, 0xf726, 0xf7b4, 0x207d, 0x207e, 0x2025, 0x2024, 0x002c, - 0x002d, 0x002e, 0x2044, 0xf730, 0xf731, 0xf732, 0xf733, 0xf734, 0xf735, - 0xf736, 0xf737, 0xf738, 0xf739, 0x003a, 0x003b, 0x0000, 0xf6de, 0x0000, - 0xf73f, 0x0000, 0x0000, 0x0000, 0x0000, 0xf7f0, 0x0000, 0x0000, 0x00bc, - 0x00bd, 0x00be, 0x215b, 0x215c, 0x215d, 0x215e, 0x2153, 0x2154, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfb00, 0xfb01, 0xfb02, 0xfb03, - 0xfb04, 0x208d, 0x0000, 0x208e, 0xf6f6, 0xf6e5, 0xf760, 0xf761, 0xf762, - 0xf763, 0xf764, 0xf765, 0xf766, 0xf767, 0xf768, 0xf769, 0xf76a, 0xf76b, - 0xf76c, 0xf76d, 0xf76e, 0xf76f, 0xf770, 0xf771, 0xf772, 0xf773, 0xf774, - 0xf775, 0xf776, 0xf777, 0xf778, 0xf779, 0xf77a, 0x20a1, 0xf6dc, 0xf6dd, - 0xf6fe, 0x0000, 0x0000, 0xf6e9, 0xf6e0, 0x0000, 0x0000, 0x0000, 0x0000, - 0xf7e1, 0xf7e0, 0xf7e2, 0xf7e4, 0xf7e3, 0xf7e5, 0xf7e7, 0xf7e9, 0xf7e8, - 0xf7ea, 0xf7eb, 0xf7ed, 0xf7ec, 0xf7ee, 0xf7ef, 0xf7f1, 0xf7f3, 0xf7f2, - 0xf7f4, 0xf7f6, 0xf7f5, 0xf7fa, 0xf7f9, 0xf7fb, 0xf7fc, 0x0000, 0x2078, - 0x2084, 0x2083, 0x2086, 0x2088, 0x2087, 0xf6fd, 0x0000, 0xf6df, 0x2082, - 0x0000, 0xf7a8, 0x0000, 0xf6f5, 0xf6fd, 0x2085, 0x0000, 0xf6e1, 0xf6e7, - 0xf7fd, 0x0000, 0xf6e3, 0x0000, 0x0000, 0xf7fe, 0x0000, 0x2089, 0x2080, - 0xf6ff, 0xf7e6, 0xf7f8, 0xf7bf, 0x2081, 0xf6e9, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0xf7b8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xf6fa, 0x2012, 0xf6e6, 0x0000, 0x0000, 0x0000, 0x0000, 0xf7a1, 0x0000, - 0xf7ff, 0x0000, 0x00b9, 0x00b2, 0x00b3, 0x2074, 0x2075, 0x2076, 0x2077, - 0x2079, 0x2070, 0x0000, 0xf6ec, 0xf6f1, 0x0000, 0x0000, 0x0000, 0xf6ed, - 0xf6f2, 0xf6eb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf6ee, 0xf6fb, - 0xf6f4, 0xf7af, 0xf6ea, 0x207f, 0xf6ef, 0xf6e2, 0xf6e8, 0xf6f7, 0xf6fc, - 0x0000, 0x0000, 0x0000, 0x0000}; - -const uint16_t AdobeSymbolEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0021, 0x2200, 0x0023, - 0x2203, 0x0025, 0x0026, 0x220B, 0x0028, 0x0029, 0x2217, 0x002B, 0x002C, - 0x2212, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, - 0x003F, 0x2245, 0x0391, 0x0392, 0x03A7, 0x0394, 0x0395, 0x03A6, 0x0393, - 0x0397, 0x0399, 0x03D1, 0x039A, 0x039B, 0x039C, 0x039D, 0x039F, 0x03A0, - 0x0398, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03C2, 0x03A9, 0x039E, 0x03A8, - 0x0396, 0x005B, 0x2234, 0x005D, 0x22A5, 0x005F, 0xF8E5, 0x03B1, 0x03B2, - 0x03C7, 0x03B4, 0x03B5, 0x03C6, 0x03B3, 0x03B7, 0x03B9, 0x03D5, 0x03BA, - 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0, 0x03B8, 0x03C1, 0x03C3, 0x03C4, - 0x03C5, 0x03D6, 0x03C9, 0x03BE, 0x03C8, 0x03B6, 0x007B, 0x007C, 0x007D, - 0x223C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x20AC, 0x03D2, - 0x2032, 0x2264, 0x2044, 0x221E, 0x0192, 0x2663, 0x2666, 0x2665, 0x2660, - 0x2194, 0x2190, 0x2191, 0x2192, 0x2193, 0x00B0, 0x00B1, 0x2033, 0x2265, - 0x00D7, 0x221D, 0x2202, 0x2022, 0x00F7, 0x2260, 0x2261, 0x2248, 0x2026, - 0xF8E6, 0xF8E7, 0x21B5, 0x2135, 0x2111, 0x211C, 0x2118, 0x2297, 0x2295, - 0x2205, 0x2229, 0x222A, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, - 0x2209, 0x2220, 0x2207, 0xF6DA, 0xF6D9, 0xF6DB, 0x220F, 0x221A, 0x22C5, - 0x00AC, 0x2227, 0x2228, 0x21D4, 0x21D0, 0x21D1, 0x21D2, 0x21D3, 0x25CA, - 0x2329, 0xF8E8, 0xF8E9, 0xF8EA, 0x2211, 0xF8EB, 0xF8EC, 0xF8ED, 0xF8EE, - 0xF8EF, 0xF8F0, 0xF8F1, 0xF8F2, 0xF8F3, 0xF8F4, 0x0000, 0x232A, 0x222B, - 0x2320, 0xF8F5, 0x2321, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, 0xF8FA, 0xF8FB, - 0xF8FC, 0xF8FD, 0xF8FE, 0x0000, -}; - -const uint16_t ZapfEncoding[256] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x2701, 0x2702, 0x2703, - 0x2704, 0x260E, 0x2706, 0x2707, 0x2708, 0x2709, 0x261B, 0x261E, 0x270C, - 0x270D, 0x270E, 0x270F, 0x2710, 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, - 0x2716, 0x2717, 0x2718, 0x2719, 0x271A, 0x271B, 0x271C, 0x271D, 0x271E, - 0x271F, 0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2727, - 0x2605, 0x2729, 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F, 0x2730, - 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, - 0x273A, 0x273B, 0x273C, 0x273D, 0x273E, 0x273F, 0x2740, 0x2741, 0x2742, - 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274A, 0x274B, - 0x25CF, 0x274D, 0x25A0, 0x274F, 0x2750, 0x2751, 0x2752, 0x25B2, 0x25BC, - 0x25C6, 0x2756, 0x25D7, 0x2758, 0x2759, 0x275A, 0x275B, 0x275C, 0x275D, - 0x275E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2761, - 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2663, 0x2666, 0x2665, - 0x2660, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, - 0x2468, 0x2469, 0x2776, 0x2777, 0x2778, 0x2779, 0x277A, 0x277B, 0x277C, - 0x277D, 0x277E, 0x277F, 0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, - 0x2786, 0x2787, 0x2788, 0x2789, 0x278A, 0x278B, 0x278C, 0x278D, 0x278E, - 0x278F, 0x2790, 0x2791, 0x2792, 0x2793, 0x2794, 0x2192, 0x2194, 0x2195, - 0x2798, 0x2799, 0x279A, 0x279B, 0x279C, 0x279D, 0x279E, 0x279F, 0x27A0, - 0x27A1, 0x27A2, 0x27A3, 0x27A4, 0x27A5, 0x27A6, 0x27A7, 0x27A8, 0x27A9, - 0x27AA, 0x27AB, 0x27AC, 0x27AD, 0x27AE, 0x27AF, 0x0000, 0x27B1, 0x27B2, - 0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, 0x27B8, 0x27B9, 0x27BA, 0x27BB, - 0x27BC, 0x27BD, 0x27BE, 0x0000, -}; - -const FX_CHAR* const StandardEncodingNames[224] = { - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quoteright", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "quoteleft", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "exclamdown", - "cent", - "sterling", - "fraction", - "yen", - "florin", - "section", - "currency", - "quotesingle", - "quotedblleft", - "guillemotleft", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - nullptr, - "endash", - "dagger", - "daggerdbl", - "periodcentered", - nullptr, - "paragraph", - "bullet", - "quotesinglbase", - "quotedblbase", - "quotedblright", - "guillemotright", - "ellipsis", - "perthousand", - nullptr, - "questiondown", - nullptr, - "grave", - "acute", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "dieresis", - nullptr, - "ring", - "cedilla", - nullptr, - "hungarumlaut", - "ogonek", - "caron", - "emdash", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "AE", - nullptr, - "ordfeminine", - nullptr, - nullptr, - nullptr, - nullptr, - "Lslash", - "Oslash", - "OE", - "ordmasculine", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "ae", - nullptr, - nullptr, - nullptr, - "dotlessi", - nullptr, - nullptr, - "lslash", - "oslash", - "oe", - "germandbls", - nullptr, - nullptr, - nullptr, - nullptr, -}; - -const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = { - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - "bullet", - "Euro", - "bullet", - "quotesinglbase", - "florin", - "quotedblbase", - "ellipsis", - "dagger", - "daggerdbl", - "circumflex", - "perthousand", - "Scaron", - "guilsinglleft", - "OE", - "bullet", - "Zcaron", - "bullet", - "bullet", - "quoteleft", - "quoteright", - "quotedblleft", - "quotedblright", - "bullet", - "endash", - "emdash", - "tilde", - "trademark", - "scaron", - "guilsinglright", - "oe", - "bullet", - "zcaron", - "Ydieresis", - "space", - "exclamdown", - "cent", - "sterling", - "currency", - "yen", - "brokenbar", - "section", - "dieresis", - "copyright", - "ordfeminine", - "guillemotleft", - "logicalnot", - "hyphen", - "registered", - "macron", - "degree", - "plusminus", - "twosuperior", - "threesuperior", - "acute", - "mu", - "paragraph", - "periodcentered", - "cedilla", - "onesuperior", - "ordmasculine", - "guillemotright", - "onequarter", - "onehalf", - "threequarters", - "questiondown", - "Agrave", - "Aacute", - "Acircumflex", - "Atilde", - "Adieresis", - "Aring", - "AE", - "Ccedilla", - "Egrave", - "Eacute", - "Ecircumflex", - "Edieresis", - "Igrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Eth", - "Ntilde", - "Ograve", - "Oacute", - "Ocircumflex", - "Otilde", - "Odieresis", - "multiply", - "Oslash", - "Ugrave", - "Uacute", - "Ucircumflex", - "Udieresis", - "Yacute", - "Thorn", - "germandbls", - "agrave", - "aacute", - "acircumflex", - "atilde", - "adieresis", - "aring", - "ae", - "ccedilla", - "egrave", - "eacute", - "ecircumflex", - "edieresis", - "igrave", - "iacute", - "icircumflex", - "idieresis", - "eth", - "ntilde", - "ograve", - "oacute", - "ocircumflex", - "otilde", - "odieresis", - "divide", - "oslash", - "ugrave", - "uacute", - "ucircumflex", - "udieresis", - "yacute", - "thorn", - "ydieresis", -}; - -const FX_CHAR* const MacRomanEncodingNames[224] = { - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - nullptr, - "Adieresis", - "Aring", - "Ccedilla", - "Eacute", - "Ntilde", - "Odieresis", - "Udieresis", - "aacute", - "agrave", - "acircumflex", - "adieresis", - "atilde", - "aring", - "ccedilla", - "eacute", - "egrave", - "ecircumflex", - "edieresis", - "iacute", - "igrave", - "icircumflex", - "idieresis", - "ntilde", - "oacute", - "ograve", - "ocircumflex", - "odieresis", - "otilde", - "uacute", - "ugrave", - "ucircumflex", - "udieresis", - "dagger", - "degree", - "cent", - "sterling", - "section", - "bullet", - "paragraph", - "germandbls", - "registered", - "copyright", - "trademark", - "acute", - "dieresis", - "notequal", - "AE", - "Oslash", - "infinity", - "plusminus", - "lessequal", - "greaterequal", - "yen", - "mu", - "partialdiff", - "summation", - "product", - "pi", - "integral", - "ordfeminine", - "ordmasculine", - "Omega", - "ae", - "oslash", - "questiondown", - "exclamdown", - "logicalnot", - "radical", - "florin", - "approxequal", - "Delta", - "guillemotleft", - "guillemotright", - "ellipsis", - "space", - "Agrave", - "Atilde", - "Otilde", - "OE", - "oe", - "endash", - "emdash", - "quotedblleft", - "quotedblright", - "quoteleft", - "quoteright", - "divide", - "lozenge", - "ydieresis", - "Ydieresis", - "fraction", - "currency", - "guilsinglleft", - "guilsinglright", - "fi", - "fl", - "daggerdbl", - "periodcentered", - "quotesinglbase", - "quotedblbase", - "perthousand", - "Acircumflex", - "Ecircumflex", - "Aacute", - "Edieresis", - "Egrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Igrave", - "Oacute", - "Ocircumflex", - "apple", - "Ograve", - "Uacute", - "Ucircumflex", - "Ugrave", - "dotlessi", - "circumflex", - "tilde", - "macron", - "breve", - "dotaccent", - "ring", - "cedilla", - "hungarumlaut", - "ogonek", - "caron", -}; - -const FX_CHAR* const MacExpertEncodingNames[224] = { - "space", - "exclamsmall", - "Hungarumlautsmall", - "centoldstyle", - "dollaroldstyle", - "dollarsuperior", - "ampersandsmall", - "Acutesmall", - "parenleftsuperior", - "parenrightsuperior", - "twodotenleader", - "onedotenleader", - "comma", - "hyphen", - "period", - "fraction", - "zerooldstyle", - "oneoldstyle", - "twooldstyle", - "threeoldstyle", - "fouroldstyle", - "fiveoldstyle", - "sixoldstyle", - "sevenoldstyle", - "eightoldstyle", - "nineoldstyle", - "colon", - "semicolon", - nullptr, - "threequartersemdash", - nullptr, - "questionsmall", - nullptr, - nullptr, - nullptr, - nullptr, - "Ethsmall", - nullptr, - nullptr, - "onequarter", - "onehalf", - "threequarters", - "oneeighth", - "threeeighths", - "fiveeighths", - "seveneighths", - "onethird", - "twothirds", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "ff", - "fi", - "fl", - "ffi", - "ffl", - "parenleftinferior", - nullptr, - "parenrightinferior", - "Circumflexsmall", - "hypheninferior", - "Gravesmall", - "Asmall", - "Bsmall", - "Csmall", - "Dsmall", - "Esmall", - "Fsmall", - "Gsmall", - "Hsmall", - "Ismall", - "Jsmall", - "Ksmall", - "Lsmall", - "Msmall", - "Nsmall", - "Osmall", - "Psmall", - "Qsmall", - "Rsmall", - "Ssmall", - "Tsmall", - "Usmall", - "Vsmall", - "Wsmall", - "Xsmall", - "Ysmall", - "Zsmall", - "colonmonetary", - "onefitted", - "rupiah", - "Tildesmall", - nullptr, - nullptr, - "asuperior", - "centsuperior", - nullptr, - nullptr, - nullptr, - nullptr, - "Aacutesmall", - "Agravesmall", - "Acircumflexsmall", - "Adieresissmall", - "Atildesmall", - "Aringsmall", - "Ccedillasmall", - "Eacutesmall", - "Egravesmall", - "Ecircumflexsmall", - "Edieresissmall", - "Iacutesmall", - "Igravesmall", - "Icircumflexsmall", - "Idieresissmall", - "Ntildesmall", - "Oacutesmall", - "Ogravesmall", - "Ocircumflexsmall", - "Odieresissmall", - "Otildesmall", - "Uacutesmall", - "Ugravesmall", - "Ucircumflexsmall", - "Udieresissmall", - nullptr, - "eightsuperior", - "fourinferior", - "threeinferior", - "sixinferior", - "eightinferior", - "seveninferior", - "Scaronsmall", - nullptr, - "centinferior", - "twoinferior", - nullptr, - "Dieresissmall", - nullptr, - "Caronsmall", - "Scaronsmall", - "fiveinferior", - nullptr, - "commainferior", - "periodinferior", - "Yacutesmall", - nullptr, - "dollarinferior", - nullptr, - nullptr, - "Thornsmall", - nullptr, - "nineinferior", - "zeroinferior", - "Zcaronsmall", - "AEsmall", - "Oslashsmall", - "questiondownsmall", - "oneinferior", - "asuperior", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "Cedillasmall", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "OEsmall", - "figuredash", - "hyphensuperior", - nullptr, - nullptr, - nullptr, - nullptr, - "exclamdownsmall", - nullptr, - "Ydieresissmall", - nullptr, - "onesuperior", - "twosuperior", - "threesuperior", - "foursuperior", - "fivesuperior", - "sixsuperior", - "sevensuperior", - "ninesuperior", - "zerosuperior", - nullptr, - "esuperior", - "rsuperior", - nullptr, - nullptr, - nullptr, - "isuperior", - "ssuperior", - "dsuperior", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "lsuperior", - "Ogoneksmall", - "Brevesmall", - "Macronsmall", - "bsuperior", - "nsuperior", - "msuperior", - "commasuperior", - "periodsuperior", - "Dotaccentsmall", - "Ringsmall", - nullptr, - nullptr, - nullptr, - nullptr, -}; - -const FX_CHAR* const PDFDocEncodingNames[232] = { - "breve", - "caron", - "circumflex", - "dotaccent", - "hungarumlaut", - "ogonek", - "ring", - "tilde", - "space", - "exclam", - "quotedbl", - "numbersign", - "dollar", - "percent", - "ampersand", - "quotesingle", - "parenleft", - "parenright", - "asterisk", - "plus", - "comma", - "hyphen", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "at", - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", - "bracketleft", - "backslash", - "bracketright", - "asciicircum", - "underscore", - "grave", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "braceleft", - "bar", - "braceright", - "asciitilde", - nullptr, - "bullet3", - "dagger", - "daggerdbl", - "ellipsis", - "emdash", - "endash", - "florin", - "fraction", - "guilsinglleft", - "guilsinglright", - "minus", - "perthousand", - "quotedblbase", - "quotedblleft", - "quotedblright", - "quoteleft", - "quoteright", - "quotesinglbase", - "trademark", - "fi", - "fl", - "Lslash", - "OE", - "Scaron", - "Ydieresis", - "Zcaron2", - "dotlessi", - "lslash", - "oe", - "scaron", - "zcaron2", - nullptr, - "Euro", - "exclamdown", - "cent", - "sterling", - "currency", - "yen", - "brokenbar", - "section", - "dieresis", - "copyright", - "ordfeminine", - "guillemotleft4", - "logicalnot", - nullptr, - "registered", - "macron", - "degree", - "plusminus", - "twosuperior", - "threesuperior", - "acute", - "mu", - "paragraph", - "periodcentered", - "cedilla", - "onesuperior", - "ordmasculine", - "guillemotright4", - "onequarter", - "onehalf", - "threequarters", - "questiondown", - "Agrave", - "Aacute", - "Acircumflex", - "Atilde", - "Adieresis", - "Aring", - "AE", - "Ccedilla", - "Egrave", - "Eacute", - "Ecircumflex", - "Edieresis", - "Igrave", - "Iacute", - "Icircumflex", - "Idieresis", - "Eth", - "Ntilde", - "Ograve", - "Oacute", - "Ocircumflex", - "Otilde", - "Odieresis", - "multiply", - "Oslash", - "Ugrave", - "Uacute", - "Ucircumflex", - "Udieresis", - "Yacute", - "Thorn", - "germandbls", - "agrave", - "aacute", - "acircumflex", - "atilde", - "adieresis", - "aring", - "ae", - "ccedilla", - "egrave", - "eacute", - "ecircumflex", - "edieresis", - "igrave", - "iacute", - "icircumflex", - "idieresis", - "eth", - "ntilde", - "ograve", - "oacute", - "ocircumflex", - "otilde", - "odieresis", - "divide", - "oslash", - "ugrave", - "uacute", - "ucircumflex", - "udieresis", - "yacute", - "thorn", - "ydieresis", -}; - -const FX_CHAR* const AdobeSymbolEncodingNames[224] = { - "space", - "exclam", - "universal", - "numbersign", - "existential", - "percent", - "ampersand", - "suchthat", - "parenleft", - "parenright", - "asteriskmath", - "plus", - "comma", - "minus", - "period", - "slash", - "zero", - "one", - "two", - "three", - "four", - "five", - "six", - "seven", - "eight", - "nine", - "colon", - "semicolon", - "less", - "equal", - "greater", - "question", - "congruent", - "Alpha", - "Beta", - "Chi", - "Delta", - "Epsilon", - "Phi", - "Gamma", - "Eta", - "Iota", - "theta1", - "Kappa", - "Lambda", - "Mu", - "Nu", - "Omicron", - "Pi", - "Theta", - "Rho", - "Sigma", - "Tau", - "Upsilon", - "sigma1", - "Omega", - "Xi", - "Psi", - "Zeta", - "bracketleft", - "therefore", - "bracketright", - "perpendicular", - "underscore", - "radicalex", - "alpha", - "beta", - "chi", - "delta", - "epsilon", - "phi", - "gamma", - "eta", - "iota", - "phi1", - "kappa", - "lambda", - "mu", - "nu", - "omicron", - "pi", - "theta", - "rho", - "sigma", - "tau", - "upsilon", - "omega1", - "omega", - "xi", - "psi", - "zeta", - "braceleft", - "bar", - "braceright", - "similar", - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - "Euro", - "Upsilon1", - "minute", - "lessequal", - "fraction", - "infinity", - "florin", - "club", - "diamond", - "heart", - "spade", - "arrowboth", - "arrowleft", - "arrowup", - "arrowright", - "arrowdown", - "degree", - "plusminus", - "second", - "greaterequal", - "multiply", - "proportional", - "partialdiff", - "bullet", - "divide", - "notequal", - "equivalence", - "approxequal", - "ellipsis", - "arrowvertex", - "arrowhorizex", - "carriagereturn", - "aleph", - "Ifraktur", - "Rfraktur", - "weierstrass", - "circlemultiply", - "circleplus", - "emptyset", - "intersection", - "union", - "propersuperset", - "reflexsuperset", - "notsubset", - "propersubset", - "reflexsubset", - "element", - "notelement", - "angle", - "gradient", - "registerserif", - "copyrightserif", - "trademarkserif", - "product", - "radical", - "dotmath", - "logicalnot", - "logicaland", - "logicalor", - "arrowdblboth", - "arrowdblleft", - "arrowdblup", - "arrowdblright", - "arrowdbldown", - "lozenge", - "angleleft", - "registersans", - "copyrightsans", - "trademarksans", - "summation", - "parenlefttp", - "parenleftex", - "parenleftbt", - "bracketlefttp", - "bracketleftex", - "bracketleftbt", - "bracelefttp", - "braceleftmid", - "braceleftbt", - "braceex", - nullptr, - "angleright", - "integral", - "integraltp", - "integralex", - "integralbt", - "parenrighttp", - "parenrightex", - "parenrightbt", - "bracketrighttp", - "bracketrightex", - "bracketrightbt", - "bracerighttp", - "bracerightmid", - "bracerightbt", - nullptr, -}; - -const FX_CHAR* const ZapfEncodingNames[224] = { - "space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", - "a118", "a117", "a11", "a12", "a13", "a14", "a15", "a16", - "a105", "a17", "a18", "a19", "a20", "a21", "a22", "a23", - "a24", "a25", "a26", "a27", "a28", "a6", "a7", "a8", - "a9", "a10", "a29", "a30", "a31", "a32", "a33", "a34", - "a35", "a36", "a37", "a38", "a39", "a40", "a41", "a42", - "a43", "a44", "a45", "a46", "a47", "a48", "a49", "a50", - "a51", "a52", "a53", "a54", "a55", "a56", "a57", "a58", - "a59", "a60", "a61", "a62", "a63", "a64", "a65", "a66", - "a67", "a68", "a69", "a70", "a71", "a72", "a73", "a74", - "a203", "a75", "a204", "a76", "a77", "a78", "a79", "a81", - "a82", "a83", "a84", "a97", "a98", "a99", "a100", nullptr, - "a89", "a90", "a93", "a94", "a91", "a92", "a205", "a85", - "a206", "a86", "a87", "a88", "a95", "a96", nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, "a101", "a102", "a103", "a104", "a106", "a107", "a108", - "a112", "a111", "a110", "a109", "a120", "a121", "a122", "a123", - "a124", "a125", "a126", "a127", "a128", "a129", "a130", "a131", - "a132", "a133", "a134", "a135", "a136", "a137", "a138", "a139", - "a140", "a141", "a142", "a143", "a144", "a145", "a146", "a147", - "a148", "a149", "a150", "a151", "a152", "a153", "a154", "a155", - "a156", "a157", "a158", "a159", "a160", "a161", "a163", "a164", - "a196", "a165", "a192", "a166", "a167", "a168", "a169", "a170", - "a171", "a172", "a173", "a162", "a174", "a175", "a176", "a177", - "a178", "a179", "a193", "a180", "a199", "a181", "a200", "a182", - nullptr, "a201", "a183", "a184", "a197", "a185", "a194", "a198", - "a186", "a195", "a187", "a188", "a189", "a190", "a191", nullptr}; - -uint32_t PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) { - for (uint32_t i = 0; i < 256; i++) - if (pCodes[i] == unicode) - return i; - return 0; -} - -} // namespace - -CPDF_FontEncoding::CPDF_FontEncoding() { - FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); -} - -int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const { - for (int i = 0; i < 256; i++) - if (m_Unicodes[i] == unicode) { - return i; - } - return -1; -} - -CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) { - const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); - if (!pSrc) { - FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); - } else { - for (int i = 0; i < 256; i++) - m_Unicodes[i] = pSrc[i]; - } -} - -FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const { - return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == - 0; -} - -CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr pPool) { - int predefined = 0; - for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; - cs++) { - const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(cs); - FX_BOOL match = TRUE; - for (int i = 0; i < 256; ++i) { - if (m_Unicodes[i] != pSrc[i]) { - match = FALSE; - break; - } - } - if (match) { - predefined = cs; - break; - } - } - if (predefined) { - if (predefined == PDFFONT_ENCODING_WINANSI) { - return new CPDF_Name(pPool->Intern("WinAnsiEncoding")); - } - if (predefined == PDFFONT_ENCODING_MACROMAN) { - return new CPDF_Name(pPool->Intern("MacRomanEncoding")); - } - if (predefined == PDFFONT_ENCODING_MACEXPERT) { - return new CPDF_Name(pPool->Intern("MacExpertEncoding")); - } - return nullptr; - } - const uint16_t* pStandard = - PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); - CPDF_Array* pDiff = new CPDF_Array; - for (int i = 0; i < 256; i++) { - if (pStandard[i] == m_Unicodes[i]) { - continue; - } - pDiff->Add(new CPDF_Number(i)); - pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); - } - - CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool); - pDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); - pDict->SetFor("Differences", pDiff); - return pDict; -} - -uint32_t FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode) { - switch (encoding) { - case FXFT_ENCODING_UNICODE: - return unicode; - case FXFT_ENCODING_ADOBE_STANDARD: - return PDF_FindCode(StandardEncoding, unicode); - case FXFT_ENCODING_ADOBE_EXPERT: - return PDF_FindCode(MacExpertEncoding, unicode); - case FXFT_ENCODING_ADOBE_LATIN_1: - return PDF_FindCode(AdobeWinAnsiEncoding, unicode); - case FXFT_ENCODING_APPLE_ROMAN: - return PDF_FindCode(MacRomanEncoding, unicode); - case FXFT_ENCODING_ADOBE_CUSTOM: - return PDF_FindCode(PDFDocEncoding, unicode); - case FXFT_ENCODING_MS_SYMBOL: - return PDF_FindCode(MSSymbolEncoding, unicode); - } - return 0; -} -const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding) { - switch (encoding) { - case PDFFONT_ENCODING_WINANSI: - return AdobeWinAnsiEncoding; - case PDFFONT_ENCODING_MACROMAN: - return MacRomanEncoding; - case PDFFONT_ENCODING_MACEXPERT: - return MacExpertEncoding; - case PDFFONT_ENCODING_STANDARD: - return StandardEncoding; - case PDFFONT_ENCODING_ADOBE_SYMBOL: - return AdobeSymbolEncoding; - case PDFFONT_ENCODING_ZAPFDINGBATS: - return ZapfEncoding; - case PDFFONT_ENCODING_PDFDOC: - return PDFDocEncoding; - case PDFFONT_ENCODING_MS_SYMBOL: - return MSSymbolEncoding; - } - return nullptr; -} - -FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name) { - return (FX_WCHAR)(FXFT_unicode_from_adobe_name(name) & 0x7FFFFFFF); -} - -CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode) { - char glyph_name[64]; - FXFT_adobe_name_from_unicode(glyph_name, unicode); - return CFX_ByteString(glyph_name); -} - -const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding, - uint8_t charcode) { - if (encoding == PDFFONT_ENCODING_PDFDOC) { - if (charcode < 24) - return nullptr; - - charcode -= 24; - } else { - if (charcode < 32) - return nullptr; - - charcode -= 32; - } - switch (encoding) { - case PDFFONT_ENCODING_WINANSI: - return AdobeWinAnsiEncodingNames[charcode]; - case PDFFONT_ENCODING_MACROMAN: - return MacRomanEncodingNames[charcode]; - case PDFFONT_ENCODING_MACEXPERT: - return MacExpertEncodingNames[charcode]; - case PDFFONT_ENCODING_STANDARD: - return StandardEncodingNames[charcode]; - case PDFFONT_ENCODING_ADOBE_SYMBOL: - return AdobeSymbolEncodingNames[charcode]; - case PDFFONT_ENCODING_ZAPFDINGBATS: - return ZapfEncodingNames[charcode]; - case PDFFONT_ENCODING_PDFDOC: - return PDFDocEncodingNames[charcode]; - } - return nullptr; -} - -FX_WCHAR FT_UnicodeFromCharCode(int encoding, uint32_t charcode) { - switch (encoding) { - case FXFT_ENCODING_UNICODE: - return (uint16_t)charcode; - case FXFT_ENCODING_ADOBE_STANDARD: - return StandardEncoding[(uint8_t)charcode]; - case FXFT_ENCODING_ADOBE_EXPERT: - return MacExpertEncoding[(uint8_t)charcode]; - case FXFT_ENCODING_ADOBE_LATIN_1: - return AdobeWinAnsiEncoding[(uint8_t)charcode]; - case FXFT_ENCODING_APPLE_ROMAN: - return MacRomanEncoding[(uint8_t)charcode]; - case PDFFONT_ENCODING_PDFDOC: - return PDFDocEncoding[(uint8_t)charcode]; - } - return 0; -} diff --git a/core/fpdfapi/fpdf_font/cpdf_fontencoding.h b/core/fpdfapi/fpdf_font/cpdf_fontencoding.h deleted file mode 100644 index f8db9e5ea7..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_fontencoding.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_FONTENCODING_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_FONTENCODING_H_ - -#include "core/fxcrt/cfx_string_pool_template.h" -#include "core/fxcrt/cfx_weak_ptr.h" -#include "core/fxcrt/fx_string.h" - -#define PDFFONT_ENCODING_BUILTIN 0 -#define PDFFONT_ENCODING_WINANSI 1 -#define PDFFONT_ENCODING_MACROMAN 2 -#define PDFFONT_ENCODING_MACEXPERT 3 -#define PDFFONT_ENCODING_STANDARD 4 -#define PDFFONT_ENCODING_ADOBE_SYMBOL 5 -#define PDFFONT_ENCODING_ZAPFDINGBATS 6 -#define PDFFONT_ENCODING_PDFDOC 7 -#define PDFFONT_ENCODING_MS_SYMBOL 8 -#define PDFFONT_ENCODING_UNICODE 9 - -uint32_t FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode); -FX_WCHAR FT_UnicodeFromCharCode(int encoding, uint32_t charcode); - -FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name); -CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode); - -const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding); -const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding, - uint8_t charcode); - -class CPDF_Object; - -class CPDF_FontEncoding { - public: - CPDF_FontEncoding(); - explicit CPDF_FontEncoding(int PredefinedEncoding); - - void LoadEncoding(CPDF_Object* pEncoding); - - FX_BOOL IsIdentical(CPDF_FontEncoding* pAnother) const; - - FX_WCHAR UnicodeFromCharCode(uint8_t charcode) const { - return m_Unicodes[charcode]; - } - int CharCodeFromUnicode(FX_WCHAR unicode) const; - - void SetUnicode(uint8_t charcode, FX_WCHAR unicode) { - m_Unicodes[charcode] = unicode; - } - - CPDF_Object* Realize(CFX_WeakPtr pPool); - - public: - FX_WCHAR m_Unicodes[256]; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_FONTENCODING_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp deleted file mode 100644 index 3bb3730fb5..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h" - -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fxge/fx_freetype.h" -#include "third_party/base/numerics/safe_math.h" - -CPDF_SimpleFont::CPDF_SimpleFont() : m_BaseEncoding(PDFFONT_ENCODING_BUILTIN) { - FXSYS_memset(m_CharWidth, 0xff, sizeof(m_CharWidth)); - FXSYS_memset(m_GlyphIndex, 0xff, sizeof(m_GlyphIndex)); - FXSYS_memset(m_ExtGID, 0xff, sizeof(m_ExtGID)); - for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i) - m_CharBBox[i] = FX_RECT(-1, -1, -1, -1); -} - -CPDF_SimpleFont::~CPDF_SimpleFont() {} - -int CPDF_SimpleFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { - if (pVertGlyph) - *pVertGlyph = false; - - if (charcode > 0xff) - return -1; - - int index = m_GlyphIndex[(uint8_t)charcode]; - return index != 0xffff ? index : -1; -} - -void CPDF_SimpleFont::LoadCharMetrics(int charcode) { - if (!m_Font.GetFace()) - return; - - if (charcode < 0 || charcode > 0xff) { - return; - } - int glyph_index = m_GlyphIndex[charcode]; - if (glyph_index == 0xffff) { - if (!m_pFontFile && charcode != 32) { - LoadCharMetrics(32); - m_CharBBox[charcode] = m_CharBBox[32]; - if (m_bUseFontWidth) { - m_CharWidth[charcode] = m_CharWidth[32]; - } - } - return; - } - FXFT_Face face = m_Font.GetFace(); - int err = FXFT_Load_Glyph( - face, glyph_index, - FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); - if (err) - return; - - int iHoriBearingX = FXFT_Get_Glyph_HoriBearingX(face); - int iHoriBearingY = FXFT_Get_Glyph_HoriBearingY(face); - m_CharBBox[charcode] = - FX_RECT(TT2PDF(iHoriBearingX, face), TT2PDF(iHoriBearingY, face), - TT2PDF(iHoriBearingX + FXFT_Get_Glyph_Width(face), face), - TT2PDF(iHoriBearingY - FXFT_Get_Glyph_Height(face), face)); - - if (m_bUseFontWidth) { - int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face); - if (m_CharWidth[charcode] == 0xffff) { - m_CharWidth[charcode] = TT_Width; - } else if (TT_Width && !IsEmbedded()) { - m_CharBBox[charcode].right = - m_CharBBox[charcode].right * m_CharWidth[charcode] / TT_Width; - m_CharBBox[charcode].left = - m_CharBBox[charcode].left * m_CharWidth[charcode] / TT_Width; - } - } -} - -int CPDF_SimpleFont::GetCharWidthF(uint32_t charcode) { - if (charcode > 0xff) - charcode = 0; - - if (m_CharWidth[charcode] == 0xffff) { - LoadCharMetrics(charcode); - if (m_CharWidth[charcode] == 0xffff) { - m_CharWidth[charcode] = 0; - } - } - return m_CharWidth[charcode]; -} - -FX_RECT CPDF_SimpleFont::GetCharBBox(uint32_t charcode) { - if (charcode > 0xff) - charcode = 0; - - if (m_CharBBox[charcode].left == -1) - LoadCharMetrics(charcode); - - return m_CharBBox[charcode]; -} - -bool CPDF_SimpleFont::LoadCommon() { - CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); - if (pFontDesc) { - LoadFontDescriptor(pFontDesc); - } - CPDF_Array* pWidthArray = m_pFontDict->GetArrayFor("Widths"); - m_bUseFontWidth = !pWidthArray; - if (pWidthArray) { - if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) { - int MissingWidth = pFontDesc->GetIntegerFor("MissingWidth"); - for (int i = 0; i < 256; i++) { - m_CharWidth[i] = MissingWidth; - } - } - size_t width_start = m_pFontDict->GetIntegerFor("FirstChar", 0); - size_t width_end = m_pFontDict->GetIntegerFor("LastChar", 0); - if (width_start <= 255) { - if (width_end == 0 || width_end >= width_start + pWidthArray->GetCount()) - width_end = width_start + pWidthArray->GetCount() - 1; - if (width_end > 255) - width_end = 255; - for (size_t i = width_start; i <= width_end; i++) - m_CharWidth[i] = pWidthArray->GetIntegerAt(i - width_start); - } - } - if (m_pFontFile) { - if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { - m_BaseFont = m_BaseFont.Mid(8); - } - } else { - LoadSubstFont(); - } - if (!(m_Flags & PDFFONT_SYMBOLIC)) { - m_BaseEncoding = PDFFONT_ENCODING_STANDARD; - } - CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); - LoadPDFEncoding(pEncoding, m_BaseEncoding, &m_CharNames, !!m_pFontFile, - m_Font.IsTTFont()); - LoadGlyphMap(); - m_CharNames.clear(); - if (!m_Font.GetFace()) - return true; - - if (m_Flags & PDFFONT_ALLCAP) { - unsigned char kLowercases[][2] = {{'a', 'z'}, {0xe0, 0xf6}, {0xf8, 0xfd}}; - for (size_t range = 0; range < FX_ArraySize(kLowercases); ++range) { - const auto& lower = kLowercases[range]; - for (int i = lower[0]; i <= lower[1]; ++i) { - if (m_GlyphIndex[i] != 0xffff && m_pFontFile) - continue; - - int j = i - 32; - m_GlyphIndex[i] = m_GlyphIndex[j]; - if (m_CharWidth[j]) { - m_CharWidth[i] = m_CharWidth[j]; - m_CharBBox[i] = m_CharBBox[j]; - } - } - } - } - CheckFontMetrics(); - return true; -} - -void CPDF_SimpleFont::LoadSubstFont() { - if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { - int width = 0, i; - for (i = 0; i < 256; i++) { - if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { - continue; - } - if (width == 0) { - width = m_CharWidth[i]; - } else if (width != m_CharWidth[i]) { - break; - } - } - if (i == 256 && width) { - m_Flags |= PDFFONT_FIXEDPITCH; - } - } - pdfium::base::CheckedNumeric safeStemV(m_StemV); - if (m_StemV < 140) - safeStemV *= 5; - else - safeStemV = safeStemV * 4 + 140; - m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, - safeStemV.ValueOrDefault(FXFONT_FW_NORMAL), m_ItalicAngle, 0, - false); -} - -bool CPDF_SimpleFont::IsUnicodeCompatible() const { - return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && - m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && - m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS; -} - -CFX_WideString CPDF_SimpleFont::UnicodeFromCharCode(uint32_t charcode) const { - CFX_WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode); - if (!unicode.IsEmpty()) - return unicode; - FX_WCHAR ret = m_Encoding.UnicodeFromCharCode((uint8_t)charcode); - if (ret == 0) - return CFX_WideString(); - return ret; -} - -uint32_t CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const { - uint32_t ret = CPDF_Font::CharCodeFromUnicode(unicode); - if (ret) - return ret; - return m_Encoding.CharCodeFromUnicode(unicode); -} diff --git a/core/fpdfapi/fpdf_font/cpdf_simplefont.h b/core/fpdfapi/fpdf_font/cpdf_simplefont.h deleted file mode 100644 index f286c1a228..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_simplefont.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_SIMPLEFONT_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_SIMPLEFONT_H_ - -#include - -#include "core/fpdfapi/fpdf_font/cpdf_font.h" -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_SimpleFont : public CPDF_Font { - public: - CPDF_SimpleFont(); - ~CPDF_SimpleFont() override; - - // CPDF_Font - int GetCharWidthF(uint32_t charcode) override; - FX_RECT GetCharBBox(uint32_t charcode) override; - int GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) override; - bool IsUnicodeCompatible() const override; - CFX_WideString UnicodeFromCharCode(uint32_t charcode) const override; - uint32_t CharCodeFromUnicode(FX_WCHAR Unicode) const override; - - CPDF_FontEncoding* GetEncoding() { return &m_Encoding; } - - protected: - virtual void LoadGlyphMap() = 0; - - bool LoadCommon(); - void LoadSubstFont(); - void LoadCharMetrics(int charcode); - - CPDF_FontEncoding m_Encoding; - uint16_t m_GlyphIndex[256]; - uint16_t m_ExtGID[256]; - std::vector m_CharNames; - int m_BaseEncoding; - uint16_t m_CharWidth[256]; - FX_RECT m_CharBBox[256]; - bool m_bUseFontWidth; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_SIMPLEFONT_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp b/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp deleted file mode 100644 index 08c3e11974..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h" - -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fxge/fx_font.h" - -namespace { - -const uint8_t kPrefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; - -} // namespace - -CPDF_TrueTypeFont::CPDF_TrueTypeFont() {} - -bool CPDF_TrueTypeFont::IsTrueTypeFont() const { - return true; -} - -const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const { - return this; -} - -CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() { - return this; -} - -bool CPDF_TrueTypeFont::Load() { - return LoadCommon(); -} - -void CPDF_TrueTypeFont::LoadGlyphMap() { - if (!m_Font.GetFace()) - return; - - int baseEncoding = m_BaseEncoding; - if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 && - (baseEncoding == PDFFONT_ENCODING_MACROMAN || - baseEncoding == PDFFONT_ENCODING_WINANSI) && - (m_Flags & PDFFONT_SYMBOLIC)) { - FX_BOOL bSupportWin = FALSE; - FX_BOOL bSupportMac = FALSE; - for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) { - int platform_id = FXFT_Get_Charmap_PlatformID( - FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]); - if (platform_id == 0 || platform_id == 3) { - bSupportWin = TRUE; - } else if (platform_id == 0 || platform_id == 1) { - bSupportMac = TRUE; - } - } - if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { - baseEncoding = - bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; - } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { - baseEncoding = - bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; - } - } - if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || - baseEncoding == PDFFONT_ENCODING_WINANSI) && - m_CharNames.empty()) || - (m_Flags & PDFFONT_NONSYMBOLIC)) { - if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && - (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { - int nStartChar = m_pFontDict->GetIntegerFor("FirstChar"); - if (nStartChar < 0 || nStartChar > 255) - return; - - int charcode = 0; - for (; charcode < nStartChar; charcode++) { - m_GlyphIndex[charcode] = 0; - } - uint16_t nGlyph = charcode - nStartChar + 3; - for (; charcode < 256; charcode++, nGlyph++) { - m_GlyphIndex[charcode] = nGlyph; - } - return; - } - bool bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); - bool bMacRoman = false; - bool bMSSymbol = false; - if (!bMSUnicode) { - if (m_Flags & PDFFONT_NONSYMBOLIC) { - bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); - bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); - } else { - bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0); - bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0); - } - } - FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode"); - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(baseEncoding, m_CharNames, charcode); - if (!name) { - m_GlyphIndex[charcode] = - m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1; - continue; - } - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - if (bMSSymbol) { - for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { - uint16_t unicode = kPrefix[j] * 256 + charcode; - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), unicode); - if (m_GlyphIndex[charcode]) { - break; - } - } - } else if (m_Encoding.m_Unicodes[charcode]) { - if (bMSUnicode) { - m_GlyphIndex[charcode] = FXFT_Get_Char_Index( - m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); - } else if (bMacRoman) { - uint32_t maccode = FT_CharCodeFromUnicode( - FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); - if (!maccode) { - m_GlyphIndex[charcode] = - FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); - } else { - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), maccode); - } - } - } - if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && - name) { - if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { - m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32); - } else { - m_GlyphIndex[charcode] = - FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); - if (m_GlyphIndex[charcode] == 0) { - if (bToUnicode) { - CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); - if (!wsUnicode.IsEmpty()) { - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]); - m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; - } - } - if (m_GlyphIndex[charcode] == 0) { - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), charcode); - } - } - } - } - } - return; - } - if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { - bool bFound = false; - for (int charcode = 0; charcode < 256; charcode++) { - for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { - uint16_t unicode = kPrefix[j] * 256 + charcode; - m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); - if (m_GlyphIndex[charcode]) { - bFound = true; - break; - } - } - } - if (bFound) { - if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(baseEncoding, m_CharNames, charcode); - if (name) - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - } - } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { - for (int charcode = 0; charcode < 256; charcode++) { - m_Encoding.m_Unicodes[charcode] = - FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); - } - } - return; - } - } - if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { - bool bFound = false; - for (int charcode = 0; charcode < 256; charcode++) { - m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); - m_Encoding.m_Unicodes[charcode] = - FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); - if (m_GlyphIndex[charcode]) { - bFound = true; - } - } - if (m_pFontFile || bFound) - return; - } - if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { - bool bFound = false; - const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); - for (int charcode = 0; charcode < 256; charcode++) { - if (m_pFontFile) { - m_Encoding.m_Unicodes[charcode] = charcode; - } else { - const FX_CHAR* name = GetAdobeCharName(0, m_CharNames, charcode); - if (name) - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - else if (pUnicodes) - m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; - } - m_GlyphIndex[charcode] = FXFT_Get_Char_Index( - m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); - if (m_GlyphIndex[charcode]) - bFound = true; - } - if (bFound) - return; - } - for (int charcode = 0; charcode < 256; charcode++) - m_GlyphIndex[charcode] = charcode; -} diff --git a/core/fpdfapi/fpdf_font/cpdf_truetypefont.h b/core/fpdfapi/fpdf_font/cpdf_truetypefont.h deleted file mode 100644 index 8711b8f53d..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_truetypefont.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_ - -#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_TrueTypeFont : public CPDF_SimpleFont { - public: - CPDF_TrueTypeFont(); - - // CPDF_Font: - bool IsTrueTypeFont() const override; - const CPDF_TrueTypeFont* AsTrueTypeFont() const override; - CPDF_TrueTypeFont* AsTrueTypeFont() override; - - protected: - // CPDF_Font: - bool Load() override; - - // CPDF_SimpleFont: - void LoadGlyphMap() override; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_type1font.cpp b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp deleted file mode 100644 index d80d59ae9d..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_type1font.cpp +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_type1font.h" - -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fxge/cfx_gemodule.h" -#include "core/fxge/fx_freetype.h" - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ -#include "core/fxge/apple/apple_int.h" -#endif - -namespace { - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ -struct GlyphNameMap { - const FX_CHAR* m_pStrAdobe; - const FX_CHAR* m_pStrUnicode; -}; - -const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"}, - {"ffi", "uniFB03"}, - {"ffl", "uniFB04"}, - {"fi", "uniFB01"}, - {"fl", "uniFB02"}}; - -int compareString(const void* key, const void* element) { - return FXSYS_stricmp(static_cast(key), - static_cast(element)->m_pStrAdobe); -} - -const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) { - const GlyphNameMap* found = static_cast(FXSYS_bsearch( - pStrAdobe, g_GlyphNameSubsts, FX_ArraySize(g_GlyphNameSubsts), - sizeof(GlyphNameMap), compareString)); - return found ? found->m_pStrUnicode : nullptr; -} - -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - -FX_BOOL FT_UseType1Charmap(FXFT_Face face) { - if (FXFT_Get_Face_CharmapCount(face) == 0) { - return FALSE; - } - if (FXFT_Get_Face_CharmapCount(face) == 1 && - FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == - FXFT_ENCODING_UNICODE) { - return FALSE; - } - if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == - FXFT_ENCODING_UNICODE) { - FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); - } else { - FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); - } - return TRUE; -} - -} // namespace - -CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {} - -bool CPDF_Type1Font::IsType1Font() const { - return true; -} - -const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const { - return this; -} - -CPDF_Type1Font* CPDF_Type1Font::AsType1Font() { - return this; -} - -bool CPDF_Type1Font::Load() { - m_Base14Font = PDF_GetStandardFontName(&m_BaseFont); - if (m_Base14Font >= 0) { - CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); - if (pFontDesc && pFontDesc->KeyExist("Flags")) - m_Flags = pFontDesc->GetIntegerFor("Flags"); - else - m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC; - - if (m_Base14Font < 4) { - for (int i = 0; i < 256; i++) - m_CharWidth[i] = 600; - } - if (m_Base14Font == 12) - m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; - else if (m_Base14Font == 13) - m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; - else if (m_Flags & PDFFONT_NONSYMBOLIC) - m_BaseEncoding = PDFFONT_ENCODING_STANDARD; - } - return LoadCommon(); -} - -int CPDF_Type1Font::GlyphFromCharCodeExt(uint32_t charcode) { - if (charcode > 0xff) { - return -1; - } - int index = m_ExtGID[(uint8_t)charcode]; - if (index == 0xffff) { - return -1; - } - return index; -} - -void CPDF_Type1Font::LoadGlyphMap() { - if (!m_Font.GetFace()) - return; - -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - bool bCoreText = true; - CQuartz2D& quartz2d = - static_cast(CFX_GEModule::Get()->GetPlatformData()) - ->m_quartz2d; - if (!m_Font.GetPlatformFont()) { - if (m_Font.GetPsName() == "DFHeiStd-W5") - bCoreText = false; - - m_Font.SetPlatformFont( - quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize())); - if (!m_Font.GetPlatformFont()) - bCoreText = false; - } -#endif - if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { - if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { - FX_BOOL bGotOne = FALSE; - for (int charcode = 0; charcode < 256; charcode++) { - const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; - for (int j = 0; j < 4; j++) { - uint16_t unicode = prefix[j] * 256 + charcode; - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), unicode); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - FX_CHAR name_glyph[256]; - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], - name_glyph, 256); - name_glyph[255] = 0; - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } -#endif - if (m_GlyphIndex[charcode]) { - bGotOne = TRUE; - break; - } - } - } - if (bGotOne) { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!bCoreText) - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); -#endif - return; - } - } - FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); - if (m_BaseEncoding == 0) { - m_BaseEncoding = PDFFONT_ENCODING_STANDARD; - } - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); - if (!name) - continue; - - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - m_GlyphIndex[charcode] = FXFT_Get_Char_Index( - m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - FX_CHAR name_glyph[256]; - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph, - 256); - name_glyph[255] = 0; - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } -#endif - if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) { - m_Encoding.m_Unicodes[charcode] = 0x20; - m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - FX_CHAR name_glyph[256]; - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], - name_glyph, 256); - name_glyph[255] = 0; - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } -#endif - } - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!bCoreText) - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); -#endif - return; - } - FT_UseType1Charmap(m_Font.GetFace()); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (bCoreText) { - if (m_Flags & PDFFONT_SYMBOLIC) { - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); - if (name) { - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - m_GlyphIndex[charcode] = - FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } - } else { - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), charcode); - FX_WCHAR unicode = 0; - if (m_GlyphIndex[charcode]) { - unicode = - FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); - } - FX_CHAR name_glyph[256]; - FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], - name_glyph, 256); - name_glyph[255] = 0; - if (unicode == 0 && name_glyph[0] != 0) { - unicode = PDF_UnicodeFromAdobeName(name_glyph); - } - m_Encoding.m_Unicodes[charcode] = unicode; - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } - } - } - return; - } - FX_BOOL bUnicode = FALSE; - if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { - bUnicode = TRUE; - } - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); - if (!name) { - continue; - } - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - const FX_CHAR* pStrUnicode = GlyphNameRemap(name); - if (pStrUnicode && - 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) { - name = pStrUnicode; - } - m_GlyphIndex[charcode] = - FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } - if (m_GlyphIndex[charcode] == 0) { - if (FXSYS_strcmp(name, ".notdef") != 0 && - FXSYS_strcmp(name, "space") != 0) { - m_GlyphIndex[charcode] = FXFT_Get_Char_Index( - m_Font.GetFace(), - bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); - FX_CHAR name_glyph[256]; - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], - name_glyph, 256); - name_glyph[255] = 0; - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } - } else { - m_Encoding.m_Unicodes[charcode] = 0x20; - m_GlyphIndex[charcode] = - bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff; - FX_CHAR name_glyph[256]; - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], - name_glyph, 256); - name_glyph[255] = 0; - CFStringRef name_ct = CFStringCreateWithCStringNoCopy( - kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, - kCFAllocatorNull); - m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( - (CGFontRef)m_Font.GetPlatformFont(), name_ct); - if (name_ct) { - CFRelease(name_ct); - } - } - } - } - return; - } -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (m_Flags & PDFFONT_SYMBOLIC) { - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); - if (name) { - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - m_GlyphIndex[charcode] = - FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); - } else { - m_GlyphIndex[charcode] = - FXFT_Get_Char_Index(m_Font.GetFace(), charcode); - if (m_GlyphIndex[charcode]) { - FX_WCHAR unicode = - FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); - if (unicode == 0) { - FX_CHAR name_glyph[256]; - FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); - FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], - name_glyph, 256); - name_glyph[255] = 0; - if (name_glyph[0] != 0) { - unicode = PDF_UnicodeFromAdobeName(name_glyph); - } - } - m_Encoding.m_Unicodes[charcode] = unicode; - } - } - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!bCoreText) - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); - -#endif - return; - } - FX_BOOL bUnicode = FALSE; - if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { - bUnicode = TRUE; - } - for (int charcode = 0; charcode < 256; charcode++) { - const FX_CHAR* name = - GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); - if (!name) { - continue; - } - m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); - m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); - if (m_GlyphIndex[charcode] == 0) { - if (FXSYS_strcmp(name, ".notdef") != 0 && - FXSYS_strcmp(name, "space") != 0) { - m_GlyphIndex[charcode] = FXFT_Get_Char_Index( - m_Font.GetFace(), - bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); - } else { - m_Encoding.m_Unicodes[charcode] = 0x20; - m_GlyphIndex[charcode] = 0xffff; - } - } - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!bCoreText) - FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); -#endif -} diff --git a/core/fpdfapi/fpdf_font/cpdf_type1font.h b/core/fpdfapi/fpdf_font/cpdf_type1font.h deleted file mode 100644 index 3cc59aa85b..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_type1font.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_ - -#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Type1Font : public CPDF_SimpleFont { - public: - CPDF_Type1Font(); - - // CPDF_Font: - bool IsType1Font() const override; - const CPDF_Type1Font* AsType1Font() const override; - CPDF_Type1Font* AsType1Font() override; - int GlyphFromCharCodeExt(uint32_t charcode) override; - - int GetBase14Font() const { return m_Base14Font; } - - protected: - // CPDF_Font: - bool Load() override; - - // CPDF_SimpleFont: - void LoadGlyphMap() override; - - int m_Base14Font; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_type3char.cpp b/core/fpdfapi/fpdf_font/cpdf_type3char.cpp deleted file mode 100644 index a11f319b78..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_type3char.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_type3char.h" - -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fxge/fx_dib.h" - -CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm) - : m_pForm(pForm), m_bColored(FALSE) {} - -CPDF_Type3Char::~CPDF_Type3Char() { -} - -FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) { - if (m_pBitmap || !m_pForm) - return TRUE; - - if (m_pForm->GetPageObjectList()->size() != 1 || m_bColored) - return FALSE; - - auto& pPageObj = m_pForm->GetPageObjectList()->front(); - if (!pPageObj->IsImage()) - return FALSE; - - m_ImageMatrix = pPageObj->AsImage()->m_Matrix; - std::unique_ptr pSource( - pPageObj->AsImage()->GetImage()->LoadDIBSource()); - if (pSource) - m_pBitmap.reset(pSource->Clone()); - m_pForm.reset(); - return TRUE; -} diff --git a/core/fpdfapi/fpdf_font/cpdf_type3char.h b/core/fpdfapi/fpdf_font/cpdf_type3char.h deleted file mode 100644 index 325490678d..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_type3char.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3CHAR_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3CHAR_H_ - -#include - -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CFX_DIBitmap; -class CPDF_Form; -class CPDF_RenderContext; - -class CPDF_Type3Char { - public: - // Takes ownership of |pForm|. - explicit CPDF_Type3Char(CPDF_Form* pForm); - ~CPDF_Type3Char(); - - FX_BOOL LoadBitmap(CPDF_RenderContext* pContext); - - std::unique_ptr m_pForm; - std::unique_ptr m_pBitmap; - FX_BOOL m_bColored; - int m_Width; - CFX_Matrix m_ImageMatrix; - FX_RECT m_BBox; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3CHAR_H_ diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.cpp b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp deleted file mode 100644 index e43ccda904..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_type3font.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" - -#include - -#include "core/fpdfapi/fpdf_font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fxcrt/fx_system.h" -#include "third_party/base/stl_util.h" - -CPDF_Type3Font::CPDF_Type3Font() - : m_pCharProcs(nullptr), - m_pPageResources(nullptr), - m_pFontResources(nullptr), - m_CharLoadingDepth(0) { - FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL)); -} - -CPDF_Type3Font::~CPDF_Type3Font() {} - -bool CPDF_Type3Font::IsType3Font() const { - return true; -} - -const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const { - return this; -} - -CPDF_Type3Font* CPDF_Type3Font::AsType3Font() { - return this; -} - -bool CPDF_Type3Font::Load() { - m_pFontResources = m_pFontDict->GetDictFor("Resources"); - CPDF_Array* pMatrix = m_pFontDict->GetArrayFor("FontMatrix"); - FX_FLOAT xscale = 1.0f, yscale = 1.0f; - if (pMatrix) { - m_FontMatrix = pMatrix->GetMatrix(); - xscale = m_FontMatrix.a; - yscale = m_FontMatrix.d; - } - CPDF_Array* pBBox = m_pFontDict->GetArrayFor("FontBBox"); - if (pBBox) { - m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000); - m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000); - m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000); - m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000); - } - int StartChar = m_pFontDict->GetIntegerFor("FirstChar"); - CPDF_Array* pWidthArray = m_pFontDict->GetArrayFor("Widths"); - if (pWidthArray && (StartChar >= 0 && StartChar < 256)) { - size_t count = pWidthArray->GetCount(); - if (count > 256) - count = 256; - if (StartChar + count > 256) - count = 256 - StartChar; - for (size_t i = 0; i < count; i++) { - m_CharWidthL[StartChar + i] = - FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000); - } - } - m_pCharProcs = m_pFontDict->GetDictFor("CharProcs"); - CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); - if (pEncoding) { - LoadPDFEncoding(pEncoding, m_BaseEncoding, &m_CharNames, false, false); - if (!m_CharNames.empty()) { - for (int i = 0; i < 256; i++) { - m_Encoding.m_Unicodes[i] = - PDF_UnicodeFromAdobeName(m_CharNames[i].c_str()); - if (m_Encoding.m_Unicodes[i] == 0) { - m_Encoding.m_Unicodes[i] = i; - } - } - } - } - return true; -} - -void CPDF_Type3Font::CheckType3FontMetrics() { - CheckFontMetrics(); -} - -CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode) { - if (m_CharLoadingDepth >= _FPDF_MAX_TYPE3_FORM_LEVEL_) - return nullptr; - - auto it = m_CacheMap.find(charcode); - if (it != m_CacheMap.end()) - return it->second.get(); - - const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); - if (!name) - return nullptr; - - CPDF_Stream* pStream = - ToStream(m_pCharProcs ? m_pCharProcs->GetDirectObjectFor(name) : nullptr); - if (!pStream) - return nullptr; - - std::unique_ptr pNewChar(new CPDF_Type3Char(new CPDF_Form( - m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, - pStream, nullptr))); - - // This can trigger recursion into this method. The content of |m_CacheMap| - // can change as a result. Thus after it returns, check the cache again for - // a cache hit. - m_CharLoadingDepth++; - pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get()); - m_CharLoadingDepth--; - it = m_CacheMap.find(charcode); - if (it != m_CacheMap.end()) - return it->second.get(); - - FX_FLOAT scale = m_FontMatrix.GetXUnit(); - pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f); - FX_RECT& rcBBox = pNewChar->m_BBox; - CFX_FloatRect char_rect( - (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f, - (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f); - if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) - char_rect = pNewChar->m_pForm->CalcBoundingBox(); - - char_rect.Transform(&m_FontMatrix); - rcBBox.left = FXSYS_round(char_rect.left * 1000); - rcBBox.right = FXSYS_round(char_rect.right * 1000); - rcBBox.top = FXSYS_round(char_rect.top * 1000); - rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000); - - ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode)); - m_CacheMap[charcode] = std::move(pNewChar); - CPDF_Type3Char* pCachedChar = m_CacheMap[charcode].get(); - if (pCachedChar->m_pForm->GetPageObjectList()->empty()) - pCachedChar->m_pForm.reset(); - return pCachedChar; -} - -int CPDF_Type3Font::GetCharWidthF(uint32_t charcode) { - if (charcode >= FX_ArraySize(m_CharWidthL)) - charcode = 0; - - if (m_CharWidthL[charcode]) - return m_CharWidthL[charcode]; - - const CPDF_Type3Char* pChar = LoadChar(charcode); - return pChar ? pChar->m_Width : 0; -} - -FX_RECT CPDF_Type3Font::GetCharBBox(uint32_t charcode) { - const CPDF_Type3Char* pChar = LoadChar(charcode); - return pChar ? pChar->m_BBox : FX_RECT(); -} diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.h b/core/fpdfapi/fpdf_font/cpdf_type3font.h deleted file mode 100644 index 03078298f1..0000000000 --- a/core/fpdfapi/fpdf_font/cpdf_type3font.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_ -#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_ - -#include -#include - -#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Dictionary; -class CPDF_Type3Char; - -class CPDF_Type3Font : public CPDF_SimpleFont { - public: - CPDF_Type3Font(); - ~CPDF_Type3Font() override; - - // CPDF_Font: - bool IsType3Font() const override; - const CPDF_Type3Font* AsType3Font() const override; - CPDF_Type3Font* AsType3Font() override; - int GetCharWidthF(uint32_t charcode) override; - FX_RECT GetCharBBox(uint32_t charcode) override; - - void SetPageResources(CPDF_Dictionary* pResources) { - m_pPageResources = pResources; - } - CPDF_Type3Char* LoadChar(uint32_t charcode); - void CheckType3FontMetrics(); - - CFX_Matrix& GetFontMatrix() { return m_FontMatrix; } - - protected: - CFX_Matrix m_FontMatrix; - - private: - // CPDF_Font: - bool Load() override; - - // CPDF_SimpleFont: - void LoadGlyphMap() override {} - - int m_CharWidthL[256]; - CPDF_Dictionary* m_pCharProcs; - CPDF_Dictionary* m_pPageResources; - CPDF_Dictionary* m_pFontResources; - std::map> m_CacheMap; - // The depth char loading is in, to avoid recurive calling LoadChar(). - int m_CharLoadingDepth; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_ diff --git a/core/fpdfapi/fpdf_font/font_int.h b/core/fpdfapi/fpdf_font/font_int.h deleted file mode 100644 index dce9e0c48f..0000000000 --- a/core/fpdfapi/fpdf_font/font_int.h +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_FONT_INT_H_ -#define CORE_FPDFAPI_FPDF_FONT_FONT_INT_H_ - -#include -#include - -#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" -#include "core/fxcrt/fx_basic.h" - -class CPDF_CID2UnicodeMap; -class CPDF_CMap; -class CPDF_Font; -class CPDF_Stream; - -using FXFT_Library = void*; - -int TT2PDF(int m, FXFT_Face face); -bool FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id); -CIDSet CharsetFromOrdering(const CFX_ByteStringC& ordering); - -class CPDF_CMapManager { - public: - CPDF_CMapManager(); - ~CPDF_CMapManager(); - - CPDF_CMap* GetPredefinedCMap(const CFX_ByteString& name, bool bPromptCJK); - CPDF_CID2UnicodeMap* GetCID2UnicodeMap(CIDSet charset, bool bPromptCJK); - - private: - CPDF_CMap* LoadPredefinedCMap(const CFX_ByteString& name, bool bPromptCJK); - CPDF_CID2UnicodeMap* LoadCID2UnicodeMap(CIDSet charset, bool bPromptCJK); - - std::map m_CMaps; - CPDF_CID2UnicodeMap* m_CID2UnicodeMaps[6]; -}; - -class CFX_StockFontArray { - public: - CFX_StockFontArray(); - ~CFX_StockFontArray(); - - // Takes ownership of |pFont|, returns unowned pointer to it. - CPDF_Font* SetFont(uint32_t index, std::unique_ptr pFont); - CPDF_Font* GetFont(uint32_t index) const; - - private: - std::unique_ptr m_StockFonts[14]; -}; - -class CPDF_FontGlobals { - public: - CPDF_FontGlobals(); - ~CPDF_FontGlobals(); - - void Clear(CPDF_Document* pDoc); - CPDF_Font* Find(CPDF_Document* pDoc, uint32_t index); - - // Takes ownership of |pFont|, returns unowned pointer to it. - CPDF_Font* Set(CPDF_Document* key, - uint32_t index, - std::unique_ptr pFont); - - CPDF_CMapManager m_CMapManager; - struct { - const struct FXCMAP_CMap* m_pMapList; - uint32_t m_Count; - } m_EmbeddedCharsets[CIDSET_NUM_SETS]; - struct { - const uint16_t* m_pMap; - uint32_t m_Count; - } m_EmbeddedToUnicodes[CIDSET_NUM_SETS]; - - private: - std::map> m_StockMap; -}; - -struct CMap_CodeRange { - int m_CharSize; - uint8_t m_Lower[4]; - uint8_t m_Upper[4]; -}; - -class CPDF_CMapParser { - public: - CPDF_CMapParser(); - ~CPDF_CMapParser(); - void Initialize(CPDF_CMap* pMap); - void ParseWord(const CFX_ByteStringC& str); - CFX_BinaryBuf m_AddMaps; - - private: - friend class fpdf_font_cid_CMap_GetCode_Test; - friend class fpdf_font_cid_CMap_GetCodeRange_Test; - - static uint32_t CMap_GetCode(const CFX_ByteStringC& word); - static bool CMap_GetCodeRange(CMap_CodeRange& range, - const CFX_ByteStringC& first, - const CFX_ByteStringC& second); - - CPDF_CMap* m_pCMap; - int m_Status; - int m_CodeSeq; - uint32_t m_CodePoints[4]; - CFX_ArrayTemplate m_CodeRanges; - CFX_ByteString m_LastWord; -}; - -enum CIDCoding : uint8_t { - CIDCODING_UNKNOWN = 0, - CIDCODING_GB, - CIDCODING_BIG5, - CIDCODING_JIS, - CIDCODING_KOREA, - CIDCODING_UCS2, - CIDCODING_CID, - CIDCODING_UTF16, -}; - -class CPDF_CMap { - public: - enum CodingScheme : uint8_t { - OneByte, - TwoBytes, - MixedTwoBytes, - MixedFourBytes - }; - - CPDF_CMap(); - ~CPDF_CMap(); - - void LoadPredefined(CPDF_CMapManager* pMgr, - const CFX_ByteString& name, - bool bPromptCJK); - void LoadEmbedded(const uint8_t* pData, uint32_t dwSize); - - bool IsLoaded() const; - bool IsVertWriting() const; - uint16_t CIDFromCharCode(uint32_t charcode) const; - int GetCharSize(uint32_t charcode) const; - uint32_t GetNextChar(const FX_CHAR* pString, int nStrLen, int& offset) const; - int CountChar(const FX_CHAR* pString, int size) const; - int AppendChar(FX_CHAR* str, uint32_t charcode) const; - - private: - friend class CPDF_CMapParser; - friend class CPDF_CIDFont; - - CFX_ByteString m_PredefinedCMap; - bool m_bVertical; - CIDSet m_Charset; - int m_Coding; - CodingScheme m_CodingScheme; - int m_nCodeRanges; - uint8_t* m_pLeadingBytes; - uint16_t* m_pMapping; - uint8_t* m_pAddMapping; - bool m_bLoaded; - const FXCMAP_CMap* m_pEmbedMap; -}; - -class CPDF_CID2UnicodeMap { - public: - CPDF_CID2UnicodeMap(); - ~CPDF_CID2UnicodeMap(); - - bool IsLoaded(); - void Load(CPDF_CMapManager* pMgr, CIDSet charset, bool bPromptCJK); - FX_WCHAR UnicodeFromCID(uint16_t CID); - - private: - CIDSet m_Charset; - const uint16_t* m_pEmbeddedMap; - uint32_t m_EmbeddedCount; -}; - -class CPDF_ToUnicodeMap { - public: - CPDF_ToUnicodeMap(); - ~CPDF_ToUnicodeMap(); - - void Load(CPDF_Stream* pStream); - - CFX_WideString Lookup(uint32_t charcode) const; - uint32_t ReverseLookup(FX_WCHAR unicode) const; - - private: - friend class fpdf_font_StringToCode_Test; - friend class fpdf_font_StringToWideString_Test; - - static uint32_t StringToCode(const CFX_ByteStringC& str); - static CFX_WideString StringToWideString(const CFX_ByteStringC& str); - - std::map m_Map; - CPDF_CID2UnicodeMap* m_pBaseMap; - CFX_WideTextBuf m_MultiCharBuf; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_FONT_INT_H_ diff --git a/core/fpdfapi/fpdf_font/fpdf_font.cpp b/core/fpdfapi/fpdf_font/fpdf_font.cpp deleted file mode 100644 index 825cd61b52..0000000000 --- a/core/fpdfapi/fpdf_font/fpdf_font.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/font_int.h" - -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_name.h" -#include "core/fpdfapi/fpdf_parser/cpdf_number.h" -#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fxcrt/fx_ext.h" -#include "core/fxcrt/fx_safe_types.h" -#include "core/fxge/fx_freetype.h" -#include "third_party/base/numerics/safe_conversions.h" -#include "third_party/base/stl_util.h" - -int TT2PDF(int m, FXFT_Face face) { - int upm = FXFT_Get_Face_UnitsPerEM(face); - if (upm == 0) - return m; - return pdfium::base::checked_cast( - (static_cast(m) * 1000 + upm / 2) / upm); -} - -bool FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) { - auto* pCharMap = FXFT_Get_Face_Charmaps(face); - for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { - if (FXFT_Get_Charmap_PlatformID(pCharMap[i]) == platform_id && - FXFT_Get_Charmap_EncodingID(pCharMap[i]) == encoding_id) { - FXFT_Set_Charmap(face, pCharMap[i]); - return true; - } - } - return false; -} - -CFX_StockFontArray::CFX_StockFontArray() {} - -CFX_StockFontArray::~CFX_StockFontArray() { - for (size_t i = 0; i < FX_ArraySize(m_StockFonts); ++i) { - if (!m_StockFonts[i]) - continue; - CPDF_Dictionary* pFontDict = m_StockFonts[i]->GetFontDict(); - if (pFontDict) - pFontDict->Release(); - } -} - -CPDF_Font* CFX_StockFontArray::GetFont(uint32_t index) const { - if (index >= FX_ArraySize(m_StockFonts)) - return nullptr; - return m_StockFonts[index].get(); -} - -CPDF_Font* CFX_StockFontArray::SetFont(uint32_t index, - std::unique_ptr pFont) { - CPDF_Font* result = pFont.get(); - if (index < FX_ArraySize(m_StockFonts)) - m_StockFonts[index] = std::move(pFont); - return result; -} - -CPDF_FontGlobals::CPDF_FontGlobals() { - FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets)); - FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes)); -} - -CPDF_FontGlobals::~CPDF_FontGlobals() {} - -CPDF_Font* CPDF_FontGlobals::Find(CPDF_Document* pDoc, uint32_t index) { - auto it = m_StockMap.find(pDoc); - if (it == m_StockMap.end()) - return nullptr; - return it->second ? it->second->GetFont(index) : nullptr; -} - -CPDF_Font* CPDF_FontGlobals::Set(CPDF_Document* pDoc, - uint32_t index, - std::unique_ptr pFont) { - if (!pdfium::ContainsKey(m_StockMap, pDoc)) - m_StockMap[pDoc].reset(new CFX_StockFontArray); - return m_StockMap[pDoc]->SetFont(index, std::move(pFont)); -} - -void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) { - m_StockMap.erase(pDoc); -} - -CFX_WideString CPDF_ToUnicodeMap::Lookup(uint32_t charcode) const { - auto it = m_Map.find(charcode); - if (it != m_Map.end()) { - uint32_t value = it->second; - FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); - if (unicode != 0xffff) { - return unicode; - } - const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer(); - uint32_t buf_len = m_MultiCharBuf.GetLength(); - if (!buf || buf_len == 0) { - return CFX_WideString(); - } - uint32_t index = value >> 16; - if (index >= buf_len) { - return CFX_WideString(); - } - uint32_t len = buf[index]; - if (index + len < index || index + len >= buf_len) { - return CFX_WideString(); - } - return CFX_WideString(buf + index + 1, len); - } - if (m_pBaseMap) { - return m_pBaseMap->UnicodeFromCID((uint16_t)charcode); - } - return CFX_WideString(); -} - -uint32_t CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) const { - for (const auto& pair : m_Map) { - if (pair.second == static_cast(unicode)) - return pair.first; - } - return 0; -} - -// Static. -uint32_t CPDF_ToUnicodeMap::StringToCode(const CFX_ByteStringC& str) { - int len = str.GetLength(); - if (len == 0) - return 0; - - uint32_t result = 0; - if (str[0] == '<') { - for (int i = 1; i < len && std::isxdigit(str[i]); ++i) - result = result * 16 + FXSYS_toHexDigit(str.CharAt(i)); - return result; - } - - for (int i = 0; i < len && std::isdigit(str[i]); ++i) - result = result * 10 + FXSYS_toDecimalDigit(str.CharAt(i)); - - return result; -} - -static CFX_WideString StringDataAdd(CFX_WideString str) { - CFX_WideString ret; - int len = str.GetLength(); - FX_WCHAR value = 1; - for (int i = len - 1; i >= 0; --i) { - FX_WCHAR ch = str[i] + value; - if (ch < str[i]) { - ret.Insert(0, 0); - } else { - ret.Insert(0, ch); - value = 0; - } - } - if (value) { - ret.Insert(0, value); - } - return ret; -} - -// Static. -CFX_WideString CPDF_ToUnicodeMap::StringToWideString( - const CFX_ByteStringC& str) { - int len = str.GetLength(); - if (len == 0) - return CFX_WideString(); - - CFX_WideString result; - if (str[0] == '<') { - int byte_pos = 0; - FX_WCHAR ch = 0; - for (int i = 1; i < len && std::isxdigit(str[i]); ++i) { - ch = ch * 16 + FXSYS_toHexDigit(str[i]); - byte_pos++; - if (byte_pos == 4) { - result += ch; - byte_pos = 0; - ch = 0; - } - } - return result; - } - return result; -} - -CPDF_ToUnicodeMap::CPDF_ToUnicodeMap() : m_pBaseMap(nullptr) {} - -CPDF_ToUnicodeMap::~CPDF_ToUnicodeMap() {} - -void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) { - CIDSet cid_set = CIDSET_UNKNOWN; - CPDF_StreamAcc stream; - stream.LoadAllData(pStream, FALSE); - CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); - while (1) { - CFX_ByteStringC word = parser.GetWord(); - if (word.IsEmpty()) { - break; - } - if (word == "beginbfchar") { - while (1) { - word = parser.GetWord(); - if (word.IsEmpty() || word == "endbfchar") { - break; - } - uint32_t srccode = StringToCode(word); - word = parser.GetWord(); - CFX_WideString destcode = StringToWideString(word); - int len = destcode.GetLength(); - if (len == 0) { - continue; - } - if (len == 1) { - m_Map[srccode] = destcode.GetAt(0); - } else { - FX_SAFE_UINT32 uni = m_MultiCharBuf.GetLength(); - uni *= 0x10000; - uni += 0xffff; - m_Map[srccode] = uni.ValueOrDie(); - m_MultiCharBuf.AppendChar(destcode.GetLength()); - m_MultiCharBuf << destcode; - } - } - } else if (word == "beginbfrange") { - while (1) { - CFX_ByteString low, high; - low = parser.GetWord(); - if (low.IsEmpty() || low == "endbfrange") { - break; - } - high = parser.GetWord(); - uint32_t lowcode = StringToCode(low.AsStringC()); - uint32_t highcode = - (lowcode & 0xffffff00) | (StringToCode(high.AsStringC()) & 0xff); - if (highcode == (uint32_t)-1) { - break; - } - CFX_ByteString start(parser.GetWord()); - if (start == "[") { - for (uint32_t code = lowcode; code <= highcode; code++) { - CFX_ByteString dest(parser.GetWord()); - CFX_WideString destcode = StringToWideString(dest.AsStringC()); - int len = destcode.GetLength(); - if (len == 0) { - continue; - } - if (len == 1) { - m_Map[code] = destcode.GetAt(0); - } else { - FX_SAFE_UINT32 uni = m_MultiCharBuf.GetLength(); - uni *= 0x10000; - uni += 0xffff; - m_Map[code] = uni.ValueOrDie(); - m_MultiCharBuf.AppendChar(destcode.GetLength()); - m_MultiCharBuf << destcode; - } - } - parser.GetWord(); - } else { - CFX_WideString destcode = StringToWideString(start.AsStringC()); - int len = destcode.GetLength(); - uint32_t value = 0; - if (len == 1) { - value = StringToCode(start.AsStringC()); - for (uint32_t code = lowcode; code <= highcode; code++) { - m_Map[code] = value++; - } - } else { - for (uint32_t code = lowcode; code <= highcode; code++) { - CFX_WideString retcode; - if (code == lowcode) { - retcode = destcode; - } else { - retcode = StringDataAdd(destcode); - } - FX_SAFE_UINT32 uni = m_MultiCharBuf.GetLength(); - uni *= 0x10000; - uni += 0xffff; - m_Map[code] = uni.ValueOrDie(); - m_MultiCharBuf.AppendChar(retcode.GetLength()); - m_MultiCharBuf << retcode; - destcode = retcode; - } - } - } - } - } else if (word == "/Adobe-Korea1-UCS2") { - cid_set = CIDSET_KOREA1; - } else if (word == "/Adobe-Japan1-UCS2") { - cid_set = CIDSET_JAPAN1; - } else if (word == "/Adobe-CNS1-UCS2") { - cid_set = CIDSET_CNS1; - } else if (word == "/Adobe-GB1-UCS2") { - cid_set = CIDSET_GB1; - } - } - if (cid_set) { - m_pBaseMap = CPDF_ModuleMgr::Get() - ->GetPageModule() - ->GetFontGlobals() - ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE); - } else { - m_pBaseMap = nullptr; - } -} diff --git a/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp b/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp deleted file mode 100644 index 91117122aa..0000000000 --- a/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp +++ /dev/null @@ -1,784 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_font/font_int.h" - -#include "core/fpdfapi/cmaps/cmap_int.h" -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/ttgsubtable.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" -#include "core/fxcrt/fx_ext.h" -#include "core/fxge/fx_freetype.h" - -namespace { - -const FX_CHAR* const g_CharsetNames[CIDSET_NUM_SETS] = { - nullptr, "GB1", "CNS1", "Japan1", "Korea1", "UCS"}; - - -class CPDF_PredefinedCMap { - public: - const FX_CHAR* m_pName; - CIDSet m_Charset; - CIDCoding m_Coding; - CPDF_CMap::CodingScheme m_CodingScheme; - uint8_t m_LeadingSegCount; - uint8_t m_LeadingSegs[4]; -}; - -const CPDF_PredefinedCMap g_PredefinedCMaps[] = { - {"GB-EUC", - CIDSET_GB1, - CIDCODING_GB, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfe}}, - {"GBpc-EUC", - CIDSET_GB1, - CIDCODING_GB, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfc}}, - {"GBK-EUC", - CIDSET_GB1, - CIDCODING_GB, - CPDF_CMap::MixedTwoBytes, - 1, - {0x81, 0xfe}}, - {"GBKp-EUC", - CIDSET_GB1, - CIDCODING_GB, - CPDF_CMap::MixedTwoBytes, - 1, - {0x81, 0xfe}}, - {"GBK2K-EUC", - CIDSET_GB1, - CIDCODING_GB, - CPDF_CMap::MixedTwoBytes, - 1, - {0x81, 0xfe}}, - {"GBK2K", - CIDSET_GB1, - CIDCODING_GB, - CPDF_CMap::MixedTwoBytes, - 1, - {0x81, 0xfe}}, - {"UniGB-UCS2", CIDSET_GB1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, - {"UniGB-UTF16", CIDSET_GB1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, - {"B5pc", - CIDSET_CNS1, - CIDCODING_BIG5, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfc}}, - {"HKscs-B5", - CIDSET_CNS1, - CIDCODING_BIG5, - CPDF_CMap::MixedTwoBytes, - 1, - {0x88, 0xfe}}, - {"ETen-B5", - CIDSET_CNS1, - CIDCODING_BIG5, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfe}}, - {"ETenms-B5", - CIDSET_CNS1, - CIDCODING_BIG5, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfe}}, - {"UniCNS-UCS2", CIDSET_CNS1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, - {"UniCNS-UTF16", CIDSET_CNS1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, - {"83pv-RKSJ", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x81, 0x9f, 0xe0, 0xfc}}, - {"90ms-RKSJ", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x81, 0x9f, 0xe0, 0xfc}}, - {"90msp-RKSJ", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x81, 0x9f, 0xe0, 0xfc}}, - {"90pv-RKSJ", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x81, 0x9f, 0xe0, 0xfc}}, - {"Add-RKSJ", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x81, 0x9f, 0xe0, 0xfc}}, - {"EUC", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x8e, 0x8e, 0xa1, 0xfe}}, - {"H", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}}, - {"V", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}}, - {"Ext-RKSJ", - CIDSET_JAPAN1, - CIDCODING_JIS, - CPDF_CMap::MixedTwoBytes, - 2, - {0x81, 0x9f, 0xe0, 0xfc}}, - {"UniJIS-UCS2", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, - {"UniJIS-UCS2-HW", - CIDSET_JAPAN1, - CIDCODING_UCS2, - CPDF_CMap::TwoBytes, - 0, - {}}, - {"UniJIS-UTF16", - CIDSET_JAPAN1, - CIDCODING_UTF16, - CPDF_CMap::TwoBytes, - 0, - {}}, - {"KSC-EUC", - CIDSET_KOREA1, - CIDCODING_KOREA, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfe}}, - {"KSCms-UHC", - CIDSET_KOREA1, - CIDCODING_KOREA, - CPDF_CMap::MixedTwoBytes, - 1, - {0x81, 0xfe}}, - {"KSCms-UHC-HW", - CIDSET_KOREA1, - CIDCODING_KOREA, - CPDF_CMap::MixedTwoBytes, - 1, - {0x81, 0xfe}}, - {"KSCpc-EUC", - CIDSET_KOREA1, - CIDCODING_KOREA, - CPDF_CMap::MixedTwoBytes, - 1, - {0xa1, 0xfd}}, - {"UniKS-UCS2", CIDSET_KOREA1, CIDCODING_UCS2, CPDF_CMap::TwoBytes, 0, {}}, - {"UniKS-UTF16", CIDSET_KOREA1, CIDCODING_UTF16, CPDF_CMap::TwoBytes, 0, {}}, -}; - -CIDSet CIDSetFromSizeT(size_t index) { - if (index >= CIDSET_NUM_SETS) { - NOTREACHED(); - return CIDSET_UNKNOWN; - } - return static_cast(index); -} - -CFX_ByteStringC CMap_GetString(const CFX_ByteStringC& word) { - if (word.GetLength() <= 2) - return CFX_ByteStringC(); - return CFX_ByteStringC(&word[1], word.GetLength() - 2); -} - -int CompareDWORD(const void* data1, const void* data2) { - return (*(uint32_t*)data1) - (*(uint32_t*)data2); -} - -int CompareCID(const void* key, const void* element) { - if ((*(uint32_t*)key) < (*(uint32_t*)element)) { - return -1; - } - if ((*(uint32_t*)key) > - (*(uint32_t*)element) + ((uint32_t*)element)[1] / 65536) { - return 1; - } - return 0; -} - -int CheckCodeRange(uint8_t* codes, - int size, - CMap_CodeRange* pRanges, - int nRanges) { - int iSeg = nRanges - 1; - while (iSeg >= 0) { - if (pRanges[iSeg].m_CharSize < size) { - --iSeg; - continue; - } - int iChar = 0; - while (iChar < size) { - if (codes[iChar] < pRanges[iSeg].m_Lower[iChar] || - codes[iChar] > pRanges[iSeg].m_Upper[iChar]) { - break; - } - ++iChar; - } - if (iChar == pRanges[iSeg].m_CharSize) - return 2; - - if (iChar) - return (size == pRanges[iSeg].m_CharSize) ? 2 : 1; - iSeg--; - } - return 0; -} - -int GetCharSizeImpl(uint32_t charcode, - CMap_CodeRange* pRanges, - int iRangesSize) { - if (!iRangesSize) - return 1; - - uint8_t codes[4]; - codes[0] = codes[1] = 0x00; - codes[2] = (uint8_t)(charcode >> 8 & 0xFF); - codes[3] = (uint8_t)charcode; - int offset = 0; - int size = 4; - for (int i = 0; i < 4; ++i) { - int iSeg = iRangesSize - 1; - while (iSeg >= 0) { - if (pRanges[iSeg].m_CharSize < size) { - --iSeg; - continue; - } - int iChar = 0; - while (iChar < size) { - if (codes[offset + iChar] < pRanges[iSeg].m_Lower[iChar] || - codes[offset + iChar] > pRanges[iSeg].m_Upper[iChar]) { - break; - } - ++iChar; - } - if (iChar == pRanges[iSeg].m_CharSize) - return size; - --iSeg; - } - --size; - ++offset; - } - return 1; -} - -} // namespace - -CPDF_CMapManager::CPDF_CMapManager() { - FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps); -} -CPDF_CMapManager::~CPDF_CMapManager() { - for (const auto& pair : m_CMaps) { - delete pair.second; - } - m_CMaps.clear(); - for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) { - delete m_CID2UnicodeMaps[i]; - } -} -CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name, - bool bPromptCJK) { - auto it = m_CMaps.find(name); - if (it != m_CMaps.end()) { - return it->second; - } - CPDF_CMap* pCMap = LoadPredefinedCMap(name, bPromptCJK); - if (!name.IsEmpty()) { - m_CMaps[name] = pCMap; - } - return pCMap; -} -CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name, - bool bPromptCJK) { - CPDF_CMap* pCMap = new CPDF_CMap; - const FX_CHAR* pname = name.c_str(); - if (*pname == '/') { - pname++; - } - pCMap->LoadPredefined(this, pname, bPromptCJK); - return pCMap; -} - -CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(CIDSet charset, - bool bPromptCJK) { - if (!m_CID2UnicodeMaps[charset]) - m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK); - return m_CID2UnicodeMaps[charset]; -} -CPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(CIDSet charset, - bool bPromptCJK) { - CPDF_CID2UnicodeMap* pMap = new CPDF_CID2UnicodeMap(); - pMap->Load(this, charset, bPromptCJK); - return pMap; -} - -CPDF_CMapParser::CPDF_CMapParser() - : m_pCMap(nullptr), m_Status(0), m_CodeSeq(0) {} - -CPDF_CMapParser::~CPDF_CMapParser() {} - -void CPDF_CMapParser::Initialize(CPDF_CMap* pCMap) { - m_pCMap = pCMap; - m_Status = 0; - m_CodeSeq = 0; - m_AddMaps.EstimateSize(0, 10240); -} - -void CPDF_CMapParser::ParseWord(const CFX_ByteStringC& word) { - if (word.IsEmpty()) { - return; - } - if (word == "begincidchar") { - m_Status = 1; - m_CodeSeq = 0; - } else if (word == "begincidrange") { - m_Status = 2; - m_CodeSeq = 0; - } else if (word == "endcidrange" || word == "endcidchar") { - m_Status = 0; - } else if (word == "/WMode") { - m_Status = 6; - } else if (word == "/Registry") { - m_Status = 3; - } else if (word == "/Ordering") { - m_Status = 4; - } else if (word == "/Supplement") { - m_Status = 5; - } else if (word == "begincodespacerange") { - m_Status = 7; - m_CodeSeq = 0; - } else if (word == "usecmap") { - } else if (m_Status == 1 || m_Status == 2) { - m_CodePoints[m_CodeSeq] = CMap_GetCode(word); - m_CodeSeq++; - uint32_t StartCode, EndCode; - uint16_t StartCID; - if (m_Status == 1) { - if (m_CodeSeq < 2) { - return; - } - EndCode = StartCode = m_CodePoints[0]; - StartCID = (uint16_t)m_CodePoints[1]; - } else { - if (m_CodeSeq < 3) { - return; - } - StartCode = m_CodePoints[0]; - EndCode = m_CodePoints[1]; - StartCID = (uint16_t)m_CodePoints[2]; - } - if (EndCode < 0x10000) { - for (uint32_t code = StartCode; code <= EndCode; code++) { - m_pCMap->m_pMapping[code] = (uint16_t)(StartCID + code - StartCode); - } - } else { - uint32_t buf[2]; - buf[0] = StartCode; - buf[1] = ((EndCode - StartCode) << 16) + StartCID; - m_AddMaps.AppendBlock(buf, sizeof buf); - } - m_CodeSeq = 0; - } else if (m_Status == 3) { - m_Status = 0; - } else if (m_Status == 4) { - m_pCMap->m_Charset = CharsetFromOrdering(CMap_GetString(word)); - m_Status = 0; - } else if (m_Status == 5) { - m_Status = 0; - } else if (m_Status == 6) { - m_pCMap->m_bVertical = CMap_GetCode(word) != 0; - m_Status = 0; - } else if (m_Status == 7) { - if (word == "endcodespacerange") { - int nSegs = m_CodeRanges.GetSize(); - if (nSegs > 1) { - m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes; - m_pCMap->m_nCodeRanges = nSegs; - FX_Free(m_pCMap->m_pLeadingBytes); - m_pCMap->m_pLeadingBytes = - FX_Alloc2D(uint8_t, nSegs, sizeof(CMap_CodeRange)); - FXSYS_memcpy(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(), - nSegs * sizeof(CMap_CodeRange)); - } else if (nSegs == 1) { - m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2) - ? CPDF_CMap::TwoBytes - : CPDF_CMap::OneByte; - } - m_Status = 0; - } else { - if (word.GetLength() == 0 || word.GetAt(0) != '<') { - return; - } - if (m_CodeSeq % 2) { - CMap_CodeRange range; - if (CMap_GetCodeRange(range, m_LastWord.AsStringC(), word)) { - m_CodeRanges.Add(range); - } - } - m_CodeSeq++; - } - } - m_LastWord = word; -} - -// Static. -uint32_t CPDF_CMapParser::CMap_GetCode(const CFX_ByteStringC& word) { - pdfium::base::CheckedNumeric num = 0; - if (word.GetAt(0) == '<') { - for (int i = 1; i < word.GetLength() && std::isxdigit(word.GetAt(i)); ++i) { - num = num * 16 + FXSYS_toHexDigit(word.GetAt(i)); - if (!num.IsValid()) - return 0; - } - return num.ValueOrDie(); - } - - for (int i = 0; i < word.GetLength() && std::isdigit(word.GetAt(i)); ++i) { - num = num * 10 + FXSYS_toDecimalDigit(static_cast(word.GetAt(i))); - if (!num.IsValid()) - return 0; - } - return num.ValueOrDie(); -} - -// Static. -bool CPDF_CMapParser::CMap_GetCodeRange(CMap_CodeRange& range, - const CFX_ByteStringC& first, - const CFX_ByteStringC& second) { - if (first.GetLength() == 0 || first.GetAt(0) != '<') - return false; - - int i; - for (i = 1; i < first.GetLength(); ++i) { - if (first.GetAt(i) == '>') { - break; - } - } - range.m_CharSize = (i - 1) / 2; - if (range.m_CharSize > 4) - return false; - - for (i = 0; i < range.m_CharSize; ++i) { - uint8_t digit1 = first.GetAt(i * 2 + 1); - uint8_t digit2 = first.GetAt(i * 2 + 2); - range.m_Lower[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2); - } - - uint32_t size = second.GetLength(); - for (i = 0; i < range.m_CharSize; ++i) { - uint8_t digit1 = ((uint32_t)i * 2 + 1 < size) - ? second.GetAt((FX_STRSIZE)i * 2 + 1) - : '0'; - uint8_t digit2 = ((uint32_t)i * 2 + 2 < size) - ? second.GetAt((FX_STRSIZE)i * 2 + 2) - : '0'; - range.m_Upper[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2); - } - return true; -} - -CPDF_CMap::CPDF_CMap() { - m_Charset = CIDSET_UNKNOWN; - m_Coding = CIDCODING_UNKNOWN; - m_CodingScheme = TwoBytes; - m_bVertical = false; - m_bLoaded = false; - m_pMapping = nullptr; - m_pLeadingBytes = nullptr; - m_pAddMapping = nullptr; - m_pEmbedMap = nullptr; - m_nCodeRanges = 0; -} -CPDF_CMap::~CPDF_CMap() { - FX_Free(m_pMapping); - FX_Free(m_pAddMapping); - FX_Free(m_pLeadingBytes); -} - -bool CPDF_CMap::IsLoaded() const { - return m_bLoaded; -} - -bool CPDF_CMap::IsVertWriting() const { - return m_bVertical; -} - -void CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr, - const CFX_ByteString& bsName, - bool bPromptCJK) { - m_PredefinedCMap = bsName; - if (m_PredefinedCMap == "Identity-H" || m_PredefinedCMap == "Identity-V") { - m_Coding = CIDCODING_CID; - m_bVertical = bsName[9] == 'V'; - m_bLoaded = true; - return; - } - CFX_ByteString cmapid = m_PredefinedCMap; - m_bVertical = cmapid.Right(1) == "V"; - if (cmapid.GetLength() > 2) { - cmapid = cmapid.Left(cmapid.GetLength() - 2); - } - const CPDF_PredefinedCMap* map = nullptr; - for (size_t i = 0; i < FX_ArraySize(g_PredefinedCMaps); ++i) { - if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[i].m_pName)) { - map = &g_PredefinedCMaps[i]; - break; - } - } - if (!map) - return; - - m_Charset = map->m_Charset; - m_Coding = map->m_Coding; - m_CodingScheme = map->m_CodingScheme; - if (m_CodingScheme == MixedTwoBytes) { - m_pLeadingBytes = FX_Alloc(uint8_t, 256); - for (uint32_t i = 0; i < map->m_LeadingSegCount; ++i) { - const uint8_t* segs = map->m_LeadingSegs; - for (int b = segs[i * 2]; b <= segs[i * 2 + 1]; ++b) { - m_pLeadingBytes[b] = 1; - } - } - } - FPDFAPI_FindEmbeddedCMap(bsName, m_Charset, m_Coding, m_pEmbedMap); - if (!m_pEmbedMap) - return; - - m_bLoaded = true; -} - -void CPDF_CMap::LoadEmbedded(const uint8_t* pData, uint32_t size) { - m_pMapping = FX_Alloc(uint16_t, 65536); - CPDF_CMapParser parser; - parser.Initialize(this); - CPDF_SimpleParser syntax(pData, size); - while (1) { - CFX_ByteStringC word = syntax.GetWord(); - if (word.IsEmpty()) { - break; - } - parser.ParseWord(word); - } - if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) { - m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4); - *(uint32_t*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8; - FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), - parser.m_AddMaps.GetSize()); - FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, - CompareDWORD); - } -} - -uint16_t CPDF_CMap::CIDFromCharCode(uint32_t charcode) const { - if (m_Coding == CIDCODING_CID) { - return (uint16_t)charcode; - } - if (m_pEmbedMap) { - return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode); - } - if (!m_pMapping) { - return (uint16_t)charcode; - } - if (charcode >> 16) { - if (m_pAddMapping) { - void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, - *(uint32_t*)m_pAddMapping, 8, CompareCID); - if (!found) - return 0; - return (uint16_t)(((uint32_t*)found)[1] % 65536 + charcode - - *(uint32_t*)found); - } - return 0; - } - return m_pMapping[charcode]; -} - -uint32_t CPDF_CMap::GetNextChar(const FX_CHAR* pString, - int nStrLen, - int& offset) const { - switch (m_CodingScheme) { - case OneByte: - return ((uint8_t*)pString)[offset++]; - case TwoBytes: - offset += 2; - return ((uint8_t*)pString)[offset - 2] * 256 + - ((uint8_t*)pString)[offset - 1]; - case MixedTwoBytes: { - uint8_t byte1 = ((uint8_t*)pString)[offset++]; - if (!m_pLeadingBytes[byte1]) { - return byte1; - } - uint8_t byte2 = ((uint8_t*)pString)[offset++]; - return byte1 * 256 + byte2; - } - case MixedFourBytes: { - uint8_t codes[4]; - int char_size = 1; - codes[0] = ((uint8_t*)pString)[offset++]; - CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes; - while (1) { - int ret = CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges); - if (ret == 0) { - return 0; - } - if (ret == 2) { - uint32_t charcode = 0; - for (int i = 0; i < char_size; i++) { - charcode = (charcode << 8) + codes[i]; - } - return charcode; - } - if (char_size == 4 || offset == nStrLen) { - return 0; - } - codes[char_size++] = ((uint8_t*)pString)[offset++]; - } - break; - } - } - return 0; -} -int CPDF_CMap::GetCharSize(uint32_t charcode) const { - switch (m_CodingScheme) { - case OneByte: - return 1; - case TwoBytes: - return 2; - case MixedTwoBytes: - case MixedFourBytes: - if (charcode < 0x100) { - return 1; - } - if (charcode < 0x10000) { - return 2; - } - if (charcode < 0x1000000) { - return 3; - } - return 4; - } - return 1; -} -int CPDF_CMap::CountChar(const FX_CHAR* pString, int size) const { - switch (m_CodingScheme) { - case OneByte: - return size; - case TwoBytes: - return (size + 1) / 2; - case MixedTwoBytes: { - int count = 0; - for (int i = 0; i < size; i++) { - count++; - if (m_pLeadingBytes[((uint8_t*)pString)[i]]) { - i++; - } - } - return count; - } - case MixedFourBytes: { - int count = 0, offset = 0; - while (offset < size) { - GetNextChar(pString, size, offset); - count++; - } - return count; - } - } - return size; -} - -int CPDF_CMap::AppendChar(FX_CHAR* str, uint32_t charcode) const { - switch (m_CodingScheme) { - case OneByte: - str[0] = (uint8_t)charcode; - return 1; - case TwoBytes: - str[0] = (uint8_t)(charcode / 256); - str[1] = (uint8_t)(charcode % 256); - return 2; - case MixedTwoBytes: - case MixedFourBytes: - if (charcode < 0x100) { - CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes; - int iSize = GetCharSizeImpl(charcode, pRanges, m_nCodeRanges); - if (iSize == 0) { - iSize = 1; - } - if (iSize > 1) { - FXSYS_memset(str, 0, sizeof(uint8_t) * iSize); - } - str[iSize - 1] = (uint8_t)charcode; - return iSize; - } - if (charcode < 0x10000) { - str[0] = (uint8_t)(charcode >> 8); - str[1] = (uint8_t)charcode; - return 2; - } - if (charcode < 0x1000000) { - str[0] = (uint8_t)(charcode >> 16); - str[1] = (uint8_t)(charcode >> 8); - str[2] = (uint8_t)charcode; - return 3; - } - str[0] = (uint8_t)(charcode >> 24); - str[1] = (uint8_t)(charcode >> 16); - str[2] = (uint8_t)(charcode >> 8); - str[3] = (uint8_t)charcode; - return 4; - } - return 0; -} - -CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() { - m_EmbeddedCount = 0; -} - -CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {} - -bool CPDF_CID2UnicodeMap::IsLoaded() { - return m_EmbeddedCount != 0; -} - -FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(uint16_t CID) { - if (m_Charset == CIDSET_UNICODE) { - return CID; - } - if (CID < m_EmbeddedCount) { - return m_pEmbeddedMap[CID]; - } - return 0; -} - -void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, - CIDSet charset, - bool bPromptCJK) { - m_Charset = charset; - - CPDF_FontGlobals* pFontGlobals = - CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); - m_pEmbeddedMap = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap; - m_EmbeddedCount = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count; -} - -CIDSet CharsetFromOrdering(const CFX_ByteStringC& ordering) { - for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) { - if (ordering == g_CharsetNames[charset]) - return CIDSetFromSizeT(charset); - } - return CIDSET_UNKNOWN; -} diff --git a/core/fpdfapi/fpdf_font/fpdf_font_cid_unittest.cpp b/core/fpdfapi/fpdf_font/fpdf_font_cid_unittest.cpp deleted file mode 100644 index ec05df5226..0000000000 --- a/core/fpdfapi/fpdf_font/fpdf_font_cid_unittest.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -bool uint_ranges_equal(uint8_t* a, uint8_t* b, size_t count) { - for (size_t i = 0; i < count; ++i) { - if (a[i] != b[i]) - return false; - } - return true; -} - -} // namespace - -TEST(fpdf_font_cid, CMap_GetCode) { - EXPECT_EQ(0u, CPDF_CMapParser::CMap_GetCode("")); - EXPECT_EQ(0u, CPDF_CMapParser::CMap_GetCode("<")); - EXPECT_EQ(194u, CPDF_CMapParser::CMap_GetCode("", "")); - EXPECT_EQ(5, range.m_CharSize); - - EXPECT_TRUE( - CPDF_CMapParser::CMap_GetCodeRange(range, "<12345678>", "<87654321>")); - EXPECT_EQ(4, range.m_CharSize); - { - uint8_t lower[4] = {18, 52, 86, 120}; - uint8_t upper[4] = {135, 101, 67, 33}; - EXPECT_TRUE(uint_ranges_equal(lower, range.m_Lower, range.m_CharSize)); - EXPECT_TRUE(uint_ranges_equal(upper, range.m_Upper, range.m_CharSize)); - } - - // Hex characters - EXPECT_TRUE(CPDF_CMapParser::CMap_GetCodeRange(range, "", "")); - EXPECT_EQ(1, range.m_CharSize); - EXPECT_EQ(161, range.m_Lower[0]); - EXPECT_EQ(243, range.m_Upper[0]); - - // The second string should return 0's if it is shorter - EXPECT_TRUE(CPDF_CMapParser::CMap_GetCodeRange(range, "", "")); - EXPECT_EQ(1, range.m_CharSize); - EXPECT_EQ(161, range.m_Lower[0]); - EXPECT_EQ(0, range.m_Upper[0]); -} diff --git a/core/fpdfapi/fpdf_font/fpdf_font_unittest.cpp b/core/fpdfapi/fpdf_font/fpdf_font_unittest.cpp deleted file mode 100644 index 0c5ad8a66a..0000000000 --- a/core/fpdfapi/fpdf_font/fpdf_font_unittest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/fpdfapi/fpdf_font/font_int.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(fpdf_font, StringToCode) { - EXPECT_EQ(0u, CPDF_ToUnicodeMap::StringToCode("")); - EXPECT_EQ(194u, CPDF_ToUnicodeMap::StringToCode(" buf[count - 1].key) { - m_Buffer.AppendBlock(&pair, sizeof(_IntPair)); - return; - } - int low = 0, high = count - 1; - while (low <= high) { - int mid = (low + high) / 2; - if (buf[mid].key < key) { - low = mid + 1; - } else if (buf[mid].key > key) { - high = mid - 1; - } else { - buf[mid].value = value; - return; - } - } - m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair)); -} - -FX_BOOL CFX_GlyphMap::Lookup(int key, int& value) { - void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), - m_Buffer.GetSize() / sizeof(_IntPair), - sizeof(_IntPair), _CompareInt); - if (!pResult) { - return FALSE; - } - value = ((uint32_t*)pResult)[1]; - return TRUE; -} - -CFX_CTTGSUBTable::CFX_CTTGSUBTable() - : m_bFeautureMapLoad(FALSE), loaded(false) {} - -CFX_CTTGSUBTable::CFX_CTTGSUBTable(FT_Bytes gsub) - : m_bFeautureMapLoad(FALSE), loaded(false) { - LoadGSUBTable(gsub); -} - -CFX_CTTGSUBTable::~CFX_CTTGSUBTable() {} - -bool CFX_CTTGSUBTable::IsOk() const { - return loaded; -} - -bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub) { - header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3]; - if (header.Version != 0x00010000) { - return false; - } - header.ScriptList = gsub[4] << 8 | gsub[5]; - header.FeatureList = gsub[6] << 8 | gsub[7]; - header.LookupList = gsub[8] << 8 | gsub[9]; - return Parse(&gsub[header.ScriptList], &gsub[header.FeatureList], - &gsub[header.LookupList]); -} - -bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, - uint32_t* vglyphnum) { - uint32_t tag[] = { - (uint8_t)'v' << 24 | (uint8_t)'r' << 16 | (uint8_t)'t' << 8 | - (uint8_t)'2', - (uint8_t)'v' << 24 | (uint8_t)'e' << 16 | (uint8_t)'r' << 8 | - (uint8_t)'t', - }; - if (!m_bFeautureMapLoad) { - for (int i = 0; i < ScriptList.ScriptCount; i++) { - for (int j = 0; j < ScriptList.ScriptRecord[i].Script.LangSysCount; ++j) { - const auto& record = ScriptList.ScriptRecord[i].Script.LangSysRecord[j]; - for (int k = 0; k < record.LangSys.FeatureCount; ++k) { - uint32_t index = record.LangSys.FeatureIndex[k]; - if (FeatureList.FeatureRecord[index].FeatureTag == tag[0] || - FeatureList.FeatureRecord[index].FeatureTag == tag[1]) { - if (!pdfium::ContainsKey(m_featureMap, index)) { - m_featureMap[index] = index; - } - } - } - } - } - if (m_featureMap.empty()) { - for (int i = 0; i < FeatureList.FeatureCount; i++) { - if (FeatureList.FeatureRecord[i].FeatureTag == tag[0] || - FeatureList.FeatureRecord[i].FeatureTag == tag[1]) { - m_featureMap[i] = i; - } - } - } - m_bFeautureMapLoad = TRUE; - } - for (const auto& pair : m_featureMap) { - if (GetVerticalGlyphSub(glyphnum, vglyphnum, - &FeatureList.FeatureRecord[pair.second].Feature)) { - return true; - } - } - return false; -} - -bool CFX_CTTGSUBTable::GetVerticalGlyphSub(uint32_t glyphnum, - uint32_t* vglyphnum, - TFeature* Feature) const { - for (int i = 0; i < Feature->LookupCount; i++) { - int index = Feature->LookupListIndex[i]; - if (index < 0 || LookupList.LookupCount < index) { - continue; - } - if (LookupList.Lookup[index].LookupType == 1) { - if (GetVerticalGlyphSub2(glyphnum, vglyphnum, - &LookupList.Lookup[index])) { - return true; - } - } - } - return false; -} - -bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, - uint32_t* vglyphnum, - TLookup* Lookup) const { - for (int i = 0; i < Lookup->SubTableCount; i++) { - switch (Lookup->SubTable[i]->SubstFormat) { - case 1: { - TSingleSubstFormat1* tbl1 = (TSingleSubstFormat1*)Lookup->SubTable[i]; - if (GetCoverageIndex(tbl1->Coverage.get(), glyphnum) >= 0) { - *vglyphnum = glyphnum + tbl1->DeltaGlyphID; - return true; - } - break; - } - case 2: { - TSingleSubstFormat2* tbl2 = (TSingleSubstFormat2*)Lookup->SubTable[i]; - int index = -1; - index = GetCoverageIndex(tbl2->Coverage.get(), glyphnum); - if (0 <= index && index < tbl2->GlyphCount) { - *vglyphnum = tbl2->Substitute[index]; - return true; - } - break; - } - } - } - return false; -} - -int CFX_CTTGSUBTable::GetCoverageIndex(TCoverageFormatBase* Coverage, - uint32_t g) const { - int i = 0; - if (!Coverage) { - return -1; - } - switch (Coverage->CoverageFormat) { - case 1: { - TCoverageFormat1* c1 = (TCoverageFormat1*)Coverage; - for (i = 0; i < c1->GlyphCount; i++) { - if ((uint32_t)c1->GlyphArray[i] == g) { - return i; - } - } - return -1; - } - case 2: { - TCoverageFormat2* c2 = (TCoverageFormat2*)Coverage; - for (i = 0; i < c2->RangeCount; i++) { - uint32_t s = c2->RangeRecord[i].Start; - uint32_t e = c2->RangeRecord[i].End; - uint32_t si = c2->RangeRecord[i].StartCoverageIndex; - if (s <= g && g <= e) { - return si + g - s; - } - } - return -1; - } - } - return -1; -} - -uint8_t CFX_CTTGSUBTable::GetUInt8(FT_Bytes& p) const { - uint8_t ret = p[0]; - p += 1; - return ret; -} - -int16_t CFX_CTTGSUBTable::GetInt16(FT_Bytes& p) const { - uint16_t ret = p[0] << 8 | p[1]; - p += 2; - return *(int16_t*)&ret; -} - -uint16_t CFX_CTTGSUBTable::GetUInt16(FT_Bytes& p) const { - uint16_t ret = p[0] << 8 | p[1]; - p += 2; - return ret; -} - -int32_t CFX_CTTGSUBTable::GetInt32(FT_Bytes& p) const { - uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; - p += 4; - return *(int32_t*)&ret; -} - -uint32_t CFX_CTTGSUBTable::GetUInt32(FT_Bytes& p) const { - uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; - p += 4; - return ret; -} - -bool CFX_CTTGSUBTable::Parse(FT_Bytes scriptlist, - FT_Bytes featurelist, - FT_Bytes lookuplist) { - ParseScriptList(scriptlist, &ScriptList); - ParseFeatureList(featurelist, &FeatureList); - ParseLookupList(lookuplist, &LookupList); - return true; -} - -void CFX_CTTGSUBTable::ParseScriptList(FT_Bytes raw, TScriptList* rec) { - int i; - FT_Bytes sp = raw; - rec->ScriptCount = GetUInt16(sp); - if (rec->ScriptCount <= 0) { - return; - } - rec->ScriptRecord.reset(new TScriptRecord[rec->ScriptCount]); - for (i = 0; i < rec->ScriptCount; i++) { - rec->ScriptRecord[i].ScriptTag = GetUInt32(sp); - uint16_t offset = GetUInt16(sp); - ParseScript(&raw[offset], &rec->ScriptRecord[i].Script); - } -} - -void CFX_CTTGSUBTable::ParseScript(FT_Bytes raw, TScript* rec) { - int i; - FT_Bytes sp = raw; - rec->DefaultLangSys = GetUInt16(sp); - rec->LangSysCount = GetUInt16(sp); - if (rec->LangSysCount <= 0) { - return; - } - rec->LangSysRecord.reset(new TLangSysRecord[rec->LangSysCount]); - for (i = 0; i < rec->LangSysCount; i++) { - rec->LangSysRecord[i].LangSysTag = GetUInt32(sp); - uint16_t offset = GetUInt16(sp); - ParseLangSys(&raw[offset], &rec->LangSysRecord[i].LangSys); - } -} - -void CFX_CTTGSUBTable::ParseLangSys(FT_Bytes raw, TLangSys* rec) { - FT_Bytes sp = raw; - rec->LookupOrder = GetUInt16(sp); - rec->ReqFeatureIndex = GetUInt16(sp); - rec->FeatureCount = GetUInt16(sp); - if (rec->FeatureCount <= 0) { - return; - } - rec->FeatureIndex.reset(new uint16_t[rec->FeatureCount]); - FXSYS_memset(rec->FeatureIndex.get(), 0, - sizeof(uint16_t) * rec->FeatureCount); - for (int i = 0; i < rec->FeatureCount; ++i) { - rec->FeatureIndex[i] = GetUInt16(sp); - } -} - -void CFX_CTTGSUBTable::ParseFeatureList(FT_Bytes raw, TFeatureList* rec) { - int i; - FT_Bytes sp = raw; - rec->FeatureCount = GetUInt16(sp); - if (rec->FeatureCount <= 0) { - return; - } - rec->FeatureRecord.reset(new TFeatureRecord[rec->FeatureCount]); - for (i = 0; i < rec->FeatureCount; i++) { - rec->FeatureRecord[i].FeatureTag = GetUInt32(sp); - uint16_t offset = GetUInt16(sp); - ParseFeature(&raw[offset], &rec->FeatureRecord[i].Feature); - } -} - -void CFX_CTTGSUBTable::ParseFeature(FT_Bytes raw, TFeature* rec) { - int i; - FT_Bytes sp = raw; - rec->FeatureParams = GetUInt16(sp); - rec->LookupCount = GetUInt16(sp); - if (rec->LookupCount <= 0) { - return; - } - rec->LookupListIndex.reset(new uint16_t[rec->LookupCount]); - for (i = 0; i < rec->LookupCount; i++) { - rec->LookupListIndex[i] = GetUInt16(sp); - } -} - -void CFX_CTTGSUBTable::ParseLookupList(FT_Bytes raw, TLookupList* rec) { - int i; - FT_Bytes sp = raw; - rec->LookupCount = GetUInt16(sp); - if (rec->LookupCount <= 0) { - return; - } - rec->Lookup.reset(new TLookup[rec->LookupCount]); - for (i = 0; i < rec->LookupCount; i++) { - uint16_t offset = GetUInt16(sp); - ParseLookup(&raw[offset], &rec->Lookup[i]); - } -} - -void CFX_CTTGSUBTable::ParseLookup(FT_Bytes raw, TLookup* rec) { - int i; - FT_Bytes sp = raw; - rec->LookupType = GetUInt16(sp); - rec->LookupFlag = GetUInt16(sp); - rec->SubTableCount = GetUInt16(sp); - if (rec->SubTableCount <= 0) { - return; - } - rec->SubTable.reset(new TSubTableBase*[rec->SubTableCount]); - for (i = 0; i < rec->SubTableCount; i++) { - rec->SubTable[i] = nullptr; - } - if (rec->LookupType != 1) { - return; - } - for (i = 0; i < rec->SubTableCount; i++) { - uint16_t offset = GetUInt16(sp); - ParseSingleSubst(&raw[offset], &rec->SubTable[i]); - } -} - -CFX_CTTGSUBTable::TCoverageFormatBase* CFX_CTTGSUBTable::ParseCoverage( - FT_Bytes raw) { - FT_Bytes sp = raw; - uint16_t format = GetUInt16(sp); - TCoverageFormatBase* rec = nullptr; - if (format == 1) { - rec = new TCoverageFormat1(); - ParseCoverageFormat1(raw, static_cast(rec)); - } else if (format == 2) { - rec = new TCoverageFormat2(); - ParseCoverageFormat2(raw, static_cast(rec)); - } - return rec; -} - -void CFX_CTTGSUBTable::ParseCoverageFormat1(FT_Bytes raw, - TCoverageFormat1* rec) { - int i; - FT_Bytes sp = raw; - GetUInt16(sp); - rec->GlyphCount = GetUInt16(sp); - if (rec->GlyphCount <= 0) { - return; - } - rec->GlyphArray.reset(new uint16_t[rec->GlyphCount]); - for (i = 0; i < rec->GlyphCount; i++) { - rec->GlyphArray[i] = GetUInt16(sp); - } -} - -void CFX_CTTGSUBTable::ParseCoverageFormat2(FT_Bytes raw, - TCoverageFormat2* rec) { - int i; - FT_Bytes sp = raw; - GetUInt16(sp); - rec->RangeCount = GetUInt16(sp); - if (rec->RangeCount <= 0) { - return; - } - rec->RangeRecord.reset(new TRangeRecord[rec->RangeCount]); - for (i = 0; i < rec->RangeCount; i++) { - rec->RangeRecord[i].Start = GetUInt16(sp); - rec->RangeRecord[i].End = GetUInt16(sp); - rec->RangeRecord[i].StartCoverageIndex = GetUInt16(sp); - } -} - -void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec) { - FT_Bytes sp = raw; - uint16_t Format = GetUInt16(sp); - switch (Format) { - case 1: - *rec = new TSingleSubstFormat1(); - ParseSingleSubstFormat1(raw, (TSingleSubstFormat1*)*rec); - break; - case 2: - *rec = new TSingleSubstFormat2(); - ParseSingleSubstFormat2(raw, (TSingleSubstFormat2*)*rec); - break; - } -} - -void CFX_CTTGSUBTable::ParseSingleSubstFormat1(FT_Bytes raw, - TSingleSubstFormat1* rec) { - FT_Bytes sp = raw; - GetUInt16(sp); - uint16_t offset = GetUInt16(sp); - rec->Coverage.reset(ParseCoverage(&raw[offset])); - rec->DeltaGlyphID = GetInt16(sp); -} - -void CFX_CTTGSUBTable::ParseSingleSubstFormat2(FT_Bytes raw, - TSingleSubstFormat2* rec) { - int i; - FT_Bytes sp = raw; - GetUInt16(sp); - uint16_t offset = GetUInt16(sp); - rec->Coverage.reset(ParseCoverage(&raw[offset])); - rec->GlyphCount = GetUInt16(sp); - if (rec->GlyphCount <= 0) { - return; - } - rec->Substitute.reset(new uint16_t[rec->GlyphCount]); - for (i = 0; i < rec->GlyphCount; i++) { - rec->Substitute[i] = GetUInt16(sp); - } -} - -CFX_CTTGSUBTable::TCoverageFormat1::TCoverageFormat1() - : TCoverageFormatBase(1), GlyphCount(0) {} - -CFX_CTTGSUBTable::TCoverageFormat1::~TCoverageFormat1() {} - -CFX_CTTGSUBTable::TRangeRecord::TRangeRecord() - : Start(0), End(0), StartCoverageIndex(0) {} - -CFX_CTTGSUBTable::TCoverageFormat2::TCoverageFormat2() - : TCoverageFormatBase(2), RangeCount(0) {} - -CFX_CTTGSUBTable::TCoverageFormat2::~TCoverageFormat2() {} - -CFX_CTTGSUBTable::TSingleSubstFormat1::TSingleSubstFormat1() - : TSubTableBase(1), DeltaGlyphID(0) {} - -CFX_CTTGSUBTable::TSingleSubstFormat1::~TSingleSubstFormat1() {} - -CFX_CTTGSUBTable::TSingleSubstFormat2::TSingleSubstFormat2() - : TSubTableBase(2), GlyphCount(0) {} - -CFX_CTTGSUBTable::TSingleSubstFormat2::~TSingleSubstFormat2() {} - -CFX_CTTGSUBTable::TLookup::TLookup() - : LookupType(0), LookupFlag(0), SubTableCount(0) {} - -CFX_CTTGSUBTable::TLookup::~TLookup() { - if (SubTable) { - for (int i = 0; i < SubTableCount; ++i) - delete SubTable[i]; - } -} - -CFX_CTTGSUBTable::TScript::TScript() : DefaultLangSys(0), LangSysCount(0) {} - -CFX_CTTGSUBTable::TScript::~TScript() {} - -CFX_CTTGSUBTable::TScriptList::TScriptList() : ScriptCount(0) {} - -CFX_CTTGSUBTable::TScriptList::~TScriptList() {} - -CFX_CTTGSUBTable::TFeature::TFeature() : FeatureParams(0), LookupCount(0) {} - -CFX_CTTGSUBTable::TFeature::~TFeature() {} - -CFX_CTTGSUBTable::TFeatureList::TFeatureList() : FeatureCount(0) {} - -CFX_CTTGSUBTable::TFeatureList::~TFeatureList() {} - -CFX_CTTGSUBTable::TLookupList::TLookupList() : LookupCount(0) {} - -CFX_CTTGSUBTable::TLookupList::~TLookupList() {} - -CFX_CTTGSUBTable::TLangSys::TLangSys() - : LookupOrder(0), ReqFeatureIndex(0), FeatureCount(0) {} - -CFX_CTTGSUBTable::TLangSys::~TLangSys() {} diff --git a/core/fpdfapi/fpdf_font/ttgsubtable.h b/core/fpdfapi/fpdf_font/ttgsubtable.h deleted file mode 100644 index 492a6a21de..0000000000 --- a/core/fpdfapi/fpdf_font/ttgsubtable.h +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_ -#define CORE_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_ - -#include - -#include -#include - -#include "core/fxcrt/fx_basic.h" -#include "core/fxge/fx_font.h" -#include "core/fxge/fx_freetype.h" - -class CFX_GlyphMap { - public: - CFX_GlyphMap(); - ~CFX_GlyphMap(); - - void SetAt(int key, int value); - FX_BOOL Lookup(int key, int& value); - - protected: - CFX_BinaryBuf m_Buffer; -}; - -class CFX_CTTGSUBTable { - public: - CFX_CTTGSUBTable(); - explicit CFX_CTTGSUBTable(FT_Bytes gsub); - virtual ~CFX_CTTGSUBTable(); - - bool IsOk() const; - bool LoadGSUBTable(FT_Bytes gsub); - bool GetVerticalGlyph(uint32_t glyphnum, uint32_t* vglyphnum); - - private: - struct tt_gsub_header { - uint32_t Version; - uint16_t ScriptList; - uint16_t FeatureList; - uint16_t LookupList; - }; - struct TLangSys { - TLangSys(); - ~TLangSys(); - - uint16_t LookupOrder; - uint16_t ReqFeatureIndex; - uint16_t FeatureCount; - std::unique_ptr FeatureIndex; - - private: - TLangSys(const TLangSys&); - TLangSys& operator=(const TLangSys&); - }; - struct TLangSysRecord { - TLangSysRecord() : LangSysTag(0) {} - - uint32_t LangSysTag; - TLangSys LangSys; - - private: - TLangSysRecord(const TLangSysRecord&); - TLangSysRecord& operator=(const TLangSysRecord&); - }; - struct TScript { - TScript(); - ~TScript(); - - uint16_t DefaultLangSys; - uint16_t LangSysCount; - std::unique_ptr LangSysRecord; - - private: - TScript(const TScript&); - TScript& operator=(const TScript&); - }; - struct TScriptRecord { - TScriptRecord() : ScriptTag(0) {} - - uint32_t ScriptTag; - TScript Script; - - private: - TScriptRecord(const TScriptRecord&); - TScriptRecord& operator=(const TScriptRecord&); - }; - struct TScriptList { - TScriptList(); - ~TScriptList(); - - uint16_t ScriptCount; - std::unique_ptr ScriptRecord; - - private: - TScriptList(const TScriptList&); - TScriptList& operator=(const TScriptList&); - }; - struct TFeature { - TFeature(); - ~TFeature(); - - uint16_t FeatureParams; - int LookupCount; - std::unique_ptr LookupListIndex; - - private: - TFeature(const TFeature&); - TFeature& operator=(const TFeature&); - }; - struct TFeatureRecord { - TFeatureRecord() : FeatureTag(0) {} - - uint32_t FeatureTag; - TFeature Feature; - - private: - TFeatureRecord(const TFeatureRecord&); - TFeatureRecord& operator=(const TFeatureRecord&); - }; - struct TFeatureList { - TFeatureList(); - ~TFeatureList(); - - int FeatureCount; - std::unique_ptr FeatureRecord; - - private: - TFeatureList(const TFeatureList&); - TFeatureList& operator=(const TFeatureList&); - }; - enum TLookupFlag { - LOOKUPFLAG_RightToLeft = 0x0001, - LOOKUPFLAG_IgnoreBaseGlyphs = 0x0002, - LOOKUPFLAG_IgnoreLigatures = 0x0004, - LOOKUPFLAG_IgnoreMarks = 0x0008, - LOOKUPFLAG_Reserved = 0x00F0, - LOOKUPFLAG_MarkAttachmentType = 0xFF00, - }; - struct TCoverageFormatBase { - TCoverageFormatBase() : CoverageFormat(0) {} - explicit TCoverageFormatBase(uint16_t format) : CoverageFormat(format) {} - virtual ~TCoverageFormatBase() {} - - uint16_t CoverageFormat; - CFX_GlyphMap m_glyphMap; - - private: - TCoverageFormatBase(const TCoverageFormatBase&); - TCoverageFormatBase& operator=(const TCoverageFormatBase&); - }; - struct TCoverageFormat1 : public TCoverageFormatBase { - TCoverageFormat1(); - ~TCoverageFormat1() override; - - uint16_t GlyphCount; - std::unique_ptr GlyphArray; - - private: - TCoverageFormat1(const TCoverageFormat1&); - TCoverageFormat1& operator=(const TCoverageFormat1&); - }; - struct TRangeRecord { - TRangeRecord(); - - friend bool operator>(const TRangeRecord& r1, const TRangeRecord& r2) { - return r1.Start > r2.Start; - } - - uint16_t Start; - uint16_t End; - uint16_t StartCoverageIndex; - - private: - TRangeRecord(const TRangeRecord&); - }; - struct TCoverageFormat2 : public TCoverageFormatBase { - TCoverageFormat2(); - ~TCoverageFormat2() override; - - uint16_t RangeCount; - std::unique_ptr RangeRecord; - - private: - TCoverageFormat2(const TCoverageFormat2&); - TCoverageFormat2& operator=(const TCoverageFormat2&); - }; - struct TDevice { - TDevice() : StartSize(0), EndSize(0), DeltaFormat(0) {} - - uint16_t StartSize; - uint16_t EndSize; - uint16_t DeltaFormat; - - private: - TDevice(const TDevice&); - TDevice& operator=(const TDevice&); - }; - struct TSubTableBase { - TSubTableBase() : SubstFormat(0) {} - explicit TSubTableBase(uint16_t format) : SubstFormat(format) {} - virtual ~TSubTableBase() {} - - uint16_t SubstFormat; - - private: - TSubTableBase(const TSubTableBase&); - TSubTableBase& operator=(const TSubTableBase&); - }; - struct TSingleSubstFormat1 : public TSubTableBase { - TSingleSubstFormat1(); - ~TSingleSubstFormat1() override; - - std::unique_ptr Coverage; - int16_t DeltaGlyphID; - - private: - TSingleSubstFormat1(const TSingleSubstFormat1&); - TSingleSubstFormat1& operator=(const TSingleSubstFormat1&); - }; - struct TSingleSubstFormat2 : public TSubTableBase { - TSingleSubstFormat2(); - ~TSingleSubstFormat2() override; - - std::unique_ptr Coverage; - uint16_t GlyphCount; - std::unique_ptr Substitute; - - private: - TSingleSubstFormat2(const TSingleSubstFormat2&); - TSingleSubstFormat2& operator=(const TSingleSubstFormat2&); - }; - struct TLookup { - TLookup(); - ~TLookup(); - - uint16_t LookupType; - uint16_t LookupFlag; - uint16_t SubTableCount; - std::unique_ptr SubTable; - - private: - TLookup(const TLookup&); - TLookup& operator=(const TLookup&); - }; - struct TLookupList { - TLookupList(); - ~TLookupList(); - - int LookupCount; - std::unique_ptr Lookup; - - private: - TLookupList(const TLookupList&); - TLookupList& operator=(const TLookupList&); - }; - - bool Parse(FT_Bytes scriptlist, FT_Bytes featurelist, FT_Bytes lookuplist); - void ParseScriptList(FT_Bytes raw, TScriptList* rec); - void ParseScript(FT_Bytes raw, TScript* rec); - void ParseLangSys(FT_Bytes raw, TLangSys* rec); - void ParseFeatureList(FT_Bytes raw, TFeatureList* rec); - void ParseFeature(FT_Bytes raw, TFeature* rec); - void ParseLookupList(FT_Bytes raw, TLookupList* rec); - void ParseLookup(FT_Bytes raw, TLookup* rec); - TCoverageFormatBase* ParseCoverage(FT_Bytes raw); - void ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1* rec); - void ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2* rec); - void ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec); - void ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1* rec); - void ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2* rec); - - bool GetVerticalGlyphSub(uint32_t glyphnum, - uint32_t* vglyphnum, - TFeature* Feature) const; - bool GetVerticalGlyphSub2(uint32_t glyphnum, - uint32_t* vglyphnum, - TLookup* Lookup) const; - int GetCoverageIndex(TCoverageFormatBase* Coverage, uint32_t g) const; - - uint8_t GetUInt8(FT_Bytes& p) const; - int16_t GetInt16(FT_Bytes& p) const; - uint16_t GetUInt16(FT_Bytes& p) const; - int32_t GetInt32(FT_Bytes& p) const; - uint32_t GetUInt32(FT_Bytes& p) const; - - std::map m_featureMap; - FX_BOOL m_bFeautureMapLoad; - bool loaded; - tt_gsub_header header; - TScriptList ScriptList; - TFeatureList FeatureList; - TLookupList LookupList; -}; - -#endif // CORE_FPDFAPI_FPDF_FONT_TTGSUBTABLE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pagemodule.h b/core/fpdfapi/fpdf_page/cpdf_pagemodule.h index c1f0ede1ba..35316cd0bf 100644 --- a/core/fpdfapi/fpdf_page/cpdf_pagemodule.h +++ b/core/fpdfapi/fpdf_page/cpdf_pagemodule.h @@ -7,7 +7,7 @@ #ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEMODULE_H_ #define CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEMODULE_H_ -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_colorspace.h" #include "core/fpdfapi/fpdf_page/pageint.h" diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp index 1119d2965f..97f6ad2bcd 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp @@ -6,8 +6,8 @@ #include "core/fpdfapi/fpdf_page/cpdf_textobject.h" -#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_cidfont.h" +#include "core/fpdfapi/font/cpdf_font.h" CPDF_TextObject::CPDF_TextObject() : m_PosX(0), diff --git a/core/fpdfapi/fpdf_page/cpdf_textstate.cpp b/core/fpdfapi/fpdf_page/cpdf_textstate.cpp index 578624de0a..800af23861 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textstate.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_textstate.cpp @@ -6,7 +6,7 @@ #include "core/fpdfapi/fpdf_page/cpdf_textstate.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" diff --git a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp index 82cb405859..4b1eaa3064 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp @@ -11,8 +11,8 @@ #include "core/fdrm/crypto/fx_crypt.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_type1font.h" -#include "core/fpdfapi/fpdf_font/font_int.h" +#include "core/fpdfapi/font/cpdf_type1font.h" +#include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/fpdf_page/cpdf_image.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fpdfapi/fpdf_page/cpdf_pattern.h" diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index ccdc897e17..c0059b8a77 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -11,8 +11,8 @@ #include #include "core/fpdfapi/edit/cpdf_creator.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_type3font.h" #include "core/fpdfapi/fpdf_page/cpdf_allstates.h" #include "core/fpdfapi/fpdf_page/cpdf_form.h" #include "core/fpdfapi/fpdf_page/cpdf_formobject.h" diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp index 3c7a301d29..3c3104b8ab 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp @@ -9,7 +9,7 @@ #include #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3char.h" +#include "core/fpdfapi/font/cpdf_type3char.h" #include "core/fpdfapi/fpdf_page/cpdf_allstates.h" #include "core/fpdfapi/fpdf_page/cpdf_form.h" #include "core/fpdfapi/fpdf_page/cpdf_page.h" diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp index 75e6a84598..811f3a9f95 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_document.cpp @@ -11,7 +11,7 @@ #include #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" +#include "core/fpdfapi/font/cpdf_fontencoding.h" #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" diff --git a/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp b/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp index 6de46a6376..1891a8d2d0 100644 --- a/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp +++ b/core/fpdfapi/fpdf_render/cpdf_type3cache.cpp @@ -9,8 +9,8 @@ #include #include -#include "core/fpdfapi/fpdf_font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" +#include "core/fpdfapi/font/cpdf_type3char.h" +#include "core/fpdfapi/font/cpdf_type3font.h" #include "core/fpdfapi/fpdf_render/cpdf_type3glyphs.h" #include "core/fxge/fx_dib.h" #include "core/fxge/fx_font.h" diff --git a/core/fpdfapi/fpdf_render/cpdf_type3cache.h b/core/fpdfapi/fpdf_render/cpdf_type3cache.h index 199bc28987..ea4b5a1408 100644 --- a/core/fpdfapi/fpdf_render/cpdf_type3cache.h +++ b/core/fpdfapi/fpdf_render/cpdf_type3cache.h @@ -9,7 +9,7 @@ #include -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" +#include "core/fpdfapi/font/cpdf_type3font.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp index a87a40afae..cb1b2042fb 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render.cpp @@ -9,8 +9,8 @@ #include #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" +#include "core/fpdfapi/font/cpdf_type3char.h" +#include "core/fpdfapi/font/cpdf_type3font.h" #include "core/fpdfapi/fpdf_page/cpdf_form.h" #include "core/fpdfapi/fpdf_page/cpdf_formobject.h" #include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp index 1ddf954d86..2554f645d4 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp @@ -8,10 +8,10 @@ #include -#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_font/cpdf_type3font.h" +#include "core/fpdfapi/font/cpdf_cidfont.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_type3char.h" +#include "core/fpdfapi/font/cpdf_type3font.h" #include "core/fpdfapi/fpdf_page/cpdf_form.h" #include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" #include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp index 624bb45de4..d68bdbc524 100644 --- a/core/fpdfdoc/cpdf_interform.cpp +++ b/core/fpdfdoc/cpdf_interform.cpp @@ -6,8 +6,8 @@ #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_fontencoding.h" #include "core/fpdfapi/fpdf_page/cpdf_page.h" #include "core/fpdfapi/fpdf_parser/cfdf_document.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp index 4ac6c6b1f9..75454f67ff 100644 --- a/core/fpdfdoc/cpdf_variabletext.cpp +++ b/core/fpdfdoc/cpdf_variabletext.cpp @@ -6,7 +6,7 @@ #include "core/fpdfdoc/cpdf_variabletext.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfdoc/cline.h" #include "core/fpdfdoc/cpvt_section.h" #include "core/fpdfdoc/cpvt_word.h" diff --git a/core/fpdfdoc/cpvt_fontmap.cpp b/core/fpdfdoc/cpvt_fontmap.cpp index 908f69f761..4a3bafd56a 100644 --- a/core/fpdfdoc/cpvt_fontmap.cpp +++ b/core/fpdfdoc/cpvt_fontmap.cpp @@ -6,7 +6,7 @@ #include "core/fpdfdoc/cpvt_fontmap.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfdoc/cpdf_interform.h" diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index c09503614f..0b75b3d33d 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -8,7 +8,7 @@ #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" diff --git a/core/fpdftext/cpdf_textpage.cpp b/core/fpdftext/cpdf_textpage.cpp index 8ee5719dbf..51556c43e7 100644 --- a/core/fpdftext/cpdf_textpage.cpp +++ b/core/fpdftext/cpdf_textpage.cpp @@ -10,7 +10,7 @@ #include #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_page/cpdf_form.h" #include "core/fpdfapi/fpdf_page/cpdf_formobject.h" #include "core/fpdfapi/fpdf_page/cpdf_page.h" diff --git a/core/fxge/ge/cfx_font.cpp b/core/fxge/ge/cfx_font.cpp index e957b219f4..f58462479f 100644 --- a/core/fxge/ge/cfx_font.cpp +++ b/core/fxge/ge/cfx_font.cpp @@ -6,7 +6,7 @@ #include "core/fxge/fx_font.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fxge/cfx_facecache.h" #include "core/fxge/cfx_fontcache.h" #include "core/fxge/cfx_fontmgr.h" diff --git a/core/fxge/ge/cfx_unicodeencodingex.cpp b/core/fxge/ge/cfx_unicodeencodingex.cpp index 5bacba42bd..c7e3303f02 100644 --- a/core/fxge/ge/cfx_unicodeencodingex.cpp +++ b/core/fxge/ge/cfx_unicodeencodingex.cpp @@ -6,7 +6,7 @@ #include "core/fxge/cfx_unicodeencodingex.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fxge/fx_font.h" #include "core/fxge/fx_freetype.h" diff --git a/fpdfsdk/formfiller/DEPS b/fpdfsdk/formfiller/DEPS index 1450b21aa6..c14952a371 100644 --- a/fpdfsdk/formfiller/DEPS +++ b/fpdfsdk/formfiller/DEPS @@ -1,3 +1,3 @@ include_rules = [ - '+core/fpdfapi/fpdf_font', + '+core/fpdfapi/font', ] diff --git a/fpdfsdk/formfiller/cba_fontmap.cpp b/fpdfsdk/formfiller/cba_fontmap.cpp index 66562ca7e5..05107ed369 100644 --- a/fpdfsdk/formfiller/cba_fontmap.cpp +++ b/fpdfsdk/formfiller/cba_fontmap.cpp @@ -6,7 +6,7 @@ #include "fpdfsdk/formfiller/cba_fontmap.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_page/cpdf_page.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" diff --git a/fpdfsdk/fxedit/DEPS b/fpdfsdk/fxedit/DEPS index a8612e1c54..810c2c6c51 100644 --- a/fpdfsdk/fxedit/DEPS +++ b/fpdfsdk/fxedit/DEPS @@ -1,4 +1,4 @@ include_rules = [ - '+core/fpdfapi/fpdf_font', + '+core/fpdfapi/font', '+core/fpdfdoc', ] diff --git a/fpdfsdk/fxedit/fxet_ap.cpp b/fpdfsdk/fxedit/fxet_ap.cpp index a259d83079..c16ccdf0c4 100644 --- a/fpdfsdk/fxedit/fxet_ap.cpp +++ b/fpdfsdk/fxedit/fxet_ap.cpp @@ -4,7 +4,7 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" #include "core/fpdfdoc/cpvt_word.h" #include "core/fpdfdoc/ipvt_fontmap.h" diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp index 9f733acd70..8ea2885b73 100644 --- a/fpdfsdk/fxedit/fxet_edit.cpp +++ b/fpdfsdk/fxedit/fxet_edit.cpp @@ -10,7 +10,7 @@ #include #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" #include "core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h" #include "core/fpdfapi/fpdf_page/cpdf_pathobject.h" diff --git a/fpdfsdk/javascript/DEPS b/fpdfsdk/javascript/DEPS index 819aa99900..72b978f547 100644 --- a/fpdfsdk/javascript/DEPS +++ b/fpdfsdk/javascript/DEPS @@ -1,5 +1,5 @@ include_rules = [ '+core/fdrm/crypto', - '+core/fpdfapi/fpdf_font', + '+core/fpdfapi/font', '+fxjs' ] diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp index 10db0e75d9..48cf7824dd 100644 --- a/fpdfsdk/javascript/Document.cpp +++ b/fpdfsdk/javascript/Document.cpp @@ -9,7 +9,7 @@ #include #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_page/cpdf_page.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp index a3f77096f5..78d00f0a1d 100644 --- a/fpdfsdk/javascript/Field.cpp +++ b/fpdfsdk/javascript/Field.cpp @@ -11,7 +11,7 @@ #include #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_page/cpdf_page.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfdoc/cpdf_interform.h" diff --git a/fpdfsdk/pdfwindow/DEPS b/fpdfsdk/pdfwindow/DEPS index a8612e1c54..810c2c6c51 100644 --- a/fpdfsdk/pdfwindow/DEPS +++ b/fpdfsdk/pdfwindow/DEPS @@ -1,4 +1,4 @@ include_rules = [ - '+core/fpdfapi/fpdf_font', + '+core/fpdfapi/font', '+core/fpdfdoc', ] diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp index 09e291d7ce..c8de0d2deb 100644 --- a/fpdfsdk/pdfwindow/PWL_Edit.cpp +++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp @@ -8,7 +8,7 @@ #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfdoc/cpvt_word.h" #include "core/fxcrt/fx_safe_types.h" #include "core/fxcrt/fx_xml.h" diff --git a/fpdfsdk/pdfwindow/PWL_FontMap.cpp b/fpdfsdk/pdfwindow/PWL_FontMap.cpp index 440efe5a06..6b0f4fe881 100644 --- a/fpdfsdk/pdfwindow/PWL_FontMap.cpp +++ b/fpdfsdk/pdfwindow/PWL_FontMap.cpp @@ -7,8 +7,8 @@ #include "fpdfsdk/pdfwindow/PWL_FontMap.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_font/cpdf_font.h" -#include "core/fpdfapi/fpdf_font/cpdf_fontencoding.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_fontencoding.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_parser/cpdf_parser.h" #include "core/fpdfdoc/ipvt_fontmap.h" diff --git a/xfa/fxfa/app/DEPS b/xfa/fxfa/app/DEPS index fed4e8526d..78bd1ed55d 100644 --- a/xfa/fxfa/app/DEPS +++ b/xfa/fxfa/app/DEPS @@ -1,6 +1,6 @@ include_rules = [ '+core/fdrm/crypto', - '+core/fpdfapi/fpdf_font', + '+core/fpdfapi/font', '+core/fpdfapi/fpdf_page', '+core/fpdfapi/fpdf_parser', '+core/fpdfdoc', diff --git a/xfa/fxfa/app/xfa_fontmgr.cpp b/xfa/fxfa/app/xfa_fontmgr.cpp index 771228175b..156bd69588 100644 --- a/xfa/fxfa/app/xfa_fontmgr.cpp +++ b/xfa/fxfa/app/xfa_fontmgr.cpp @@ -10,7 +10,7 @@ #include #include -#include "core/fpdfapi/fpdf_font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "xfa/fgas/font/fgas_gefont.h" -- cgit v1.2.3