summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
authordan sinclair <dsinclair@chromium.org>2016-03-23 19:21:44 -0400
committerdan sinclair <dsinclair@chromium.org>2016-03-23 19:21:44 -0400
commit61b2fc718910a5ab2a75ec5026b239ff33bccfdc (patch)
tree4031f4cea10dac3d77969035e66fc17235cb1d3d /core/fpdfapi
parent46a8a2041868c5df6883647226dab1482e2bf4c2 (diff)
downloadpdfium-61b2fc718910a5ab2a75ec5026b239ff33bccfdc.tar.xz
Split core/include/fpdfapi/fpdf_resource.h
This CL splits apart the core/include/fpdfapi/fpdf_resource.h file and places the classes into individual files. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1824033002 .
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/fpdf_cmaps/CNS1/cmaps_cns1.cpp3
-rw-r--r--core/fpdfapi/fpdf_cmaps/GB1/cmaps_gb1.cpp3
-rw-r--r--core/fpdfapi/fpdf_cmaps/Japan1/cmaps_japan1.cpp3
-rw-r--r--core/fpdfapi/fpdf_cmaps/Korea1/cmaps_korea1.cpp3
-rw-r--r--core/fpdfapi/fpdf_cmaps/fpdf_cmaps.cpp1
-rw-r--r--core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp3
-rw-r--r--core/fpdfapi/fpdf_edit/fpdf_edit_doc.cpp2
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_cidfont.cpp908
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_cidfont.h89
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_font.cpp492
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp (renamed from core/fpdfapi/fpdf_font/fpdf_font_charset.cpp)354
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_simplefont.cpp222
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_simplefont.h48
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp225
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_truetypefont.h30
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type1font.cpp403
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type1font.h35
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3char.cpp43
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3char.h33
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3font.cpp162
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3font.h56
-rw-r--r--core/fpdfapi/fpdf_font/font_int.h3
-rw-r--r--core/fpdfapi/fpdf_font/fpdf_font.cpp1515
-rw-r--r--core/fpdfapi/fpdf_font/fpdf_font_cid.cpp893
-rw-r--r--core/fpdfapi/fpdf_font/include/cpdf_font.h128
-rw-r--r--core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h59
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_allstates.cpp1
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_color.cpp180
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_colorspace.cpp1253
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_colorstate.cpp4
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_colorstatedata.h2
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_countedobject.h45
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_image.cpp (renamed from core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp)206
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_imageobject.cpp1
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_meshstream.cpp119
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_meshstream.h63
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_page.cpp1
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp1
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_pattern.cpp21
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_pattern.h39
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp1
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp101
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_shadingpattern.h62
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_textobject.cpp3
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_textstate.cpp1
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp2
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp51
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_tilingpattern.h34
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_colors.cpp1338
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_doc.cpp9
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_func.cpp2
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_image.cpp66
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_parser.cpp6
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp3
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_pattern.cpp239
-rw-r--r--core/fpdfapi/fpdf_page/include/cpdf_color.h47
-rw-r--r--core/fpdfapi/fpdf_page/include/cpdf_colorspace.h122
-rw-r--r--core/fpdfapi/fpdf_page/include/cpdf_formobject.h2
-rw-r--r--core/fpdfapi/fpdf_page/include/cpdf_image.h98
-rw-r--r--core/fpdfapi/fpdf_page/pageint.h16
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_document.cpp1
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render.cpp3
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_image.cpp3
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp66
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp3
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_text.cpp26
-rw-r--r--core/fpdfapi/fpdf_render/render_int.h4
67 files changed, 5597 insertions, 4364 deletions
diff --git a/core/fpdfapi/fpdf_cmaps/CNS1/cmaps_cns1.cpp b/core/fpdfapi/fpdf_cmaps/CNS1/cmaps_cns1.cpp
index 086a78637a..b6a9132b5d 100644
--- a/core/fpdfapi/fpdf_cmaps/CNS1/cmaps_cns1.cpp
+++ b/core/fpdfapi/fpdf_cmaps/CNS1/cmaps_cns1.cpp
@@ -9,8 +9,7 @@
#include "core/fpdfapi/fpdf_cmaps/cmap_int.h"
#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
-#include "core/fxcrt/include/fx_basic.h" // For FX_ArraySize().
-#include "core/include/fpdfapi/fpdf_resource.h"
+#include "core/fxcrt/include/fx_basic.h"
static const FXCMAP_CMap g_FXCMAP_CNS1_cmaps[] = {
{"B5pc-H", FXCMAP_CMap::Range, g_FXCMAP_B5pc_H_0, 247, FXCMAP_CMap::None,
diff --git a/core/fpdfapi/fpdf_cmaps/GB1/cmaps_gb1.cpp b/core/fpdfapi/fpdf_cmaps/GB1/cmaps_gb1.cpp
index 95d231563e..702bf06c75 100644
--- a/core/fpdfapi/fpdf_cmaps/GB1/cmaps_gb1.cpp
+++ b/core/fpdfapi/fpdf_cmaps/GB1/cmaps_gb1.cpp
@@ -9,8 +9,7 @@
#include "core/fpdfapi/fpdf_cmaps/cmap_int.h"
#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
-#include "core/fxcrt/include/fx_basic.h" // For FX_ArraySize().
-#include "core/include/fpdfapi/fpdf_resource.h"
+#include "core/fxcrt/include/fx_basic.h"
static const FXCMAP_CMap g_FXCMAP_GB1_cmaps[] = {
{"GB-EUC-H", FXCMAP_CMap::Range, g_FXCMAP_GB_EUC_H_0, 90, FXCMAP_CMap::None,
diff --git a/core/fpdfapi/fpdf_cmaps/Japan1/cmaps_japan1.cpp b/core/fpdfapi/fpdf_cmaps/Japan1/cmaps_japan1.cpp
index 8c43d41311..43f7e0ee2b 100644
--- a/core/fpdfapi/fpdf_cmaps/Japan1/cmaps_japan1.cpp
+++ b/core/fpdfapi/fpdf_cmaps/Japan1/cmaps_japan1.cpp
@@ -9,8 +9,7 @@
#include "core/fpdfapi/fpdf_cmaps/cmap_int.h"
#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
-#include "core/fxcrt/include/fx_basic.h" // For FX_ArraySize().
-#include "core/include/fpdfapi/fpdf_resource.h"
+#include "core/fxcrt/include/fx_basic.h"
static const FXCMAP_CMap g_FXCMAP_Japan1_cmaps[] = {
{"83pv-RKSJ-H", FXCMAP_CMap::Range, g_FXCMAP_83pv_RKSJ_H_1, 222,
diff --git a/core/fpdfapi/fpdf_cmaps/Korea1/cmaps_korea1.cpp b/core/fpdfapi/fpdf_cmaps/Korea1/cmaps_korea1.cpp
index 0001aaaf8d..77f65dfe3c 100644
--- a/core/fpdfapi/fpdf_cmaps/Korea1/cmaps_korea1.cpp
+++ b/core/fpdfapi/fpdf_cmaps/Korea1/cmaps_korea1.cpp
@@ -9,8 +9,7 @@
#include "core/fpdfapi/fpdf_cmaps/cmap_int.h"
#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
-#include "core/fxcrt/include/fx_basic.h" // For FX_ArraySize().
-#include "core/include/fpdfapi/fpdf_resource.h"
+#include "core/fxcrt/include/fx_basic.h"
static const FXCMAP_CMap g_FXCMAP_Korea1_cmaps[] = {
{"KSC-EUC-H", FXCMAP_CMap::Range, g_FXCMAP_KSC_EUC_H_0, 467,
diff --git a/core/fpdfapi/fpdf_cmaps/fpdf_cmaps.cpp b/core/fpdfapi/fpdf_cmaps/fpdf_cmaps.cpp
index 73ac8e1f6a..4e0737dbc2 100644
--- a/core/fpdfapi/fpdf_cmaps/fpdf_cmaps.cpp
+++ b/core/fpdfapi/fpdf_cmaps/fpdf_cmaps.cpp
@@ -8,7 +8,6 @@
#include "core/fpdfapi/fpdf_font/font_int.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
void FPDFAPI_FindEmbeddedCMap(const char* name,
int charset,
diff --git a/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp
index 20211f27f7..0ab34eab3c 100644
--- a/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp
@@ -7,6 +7,7 @@
#include "core/fpdfapi/fpdf_edit/include/cpdf_pagecontentgenerator.h"
#include "core/fpdfapi/fpdf_edit/include/cpdf_creator.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
@@ -14,6 +15,8 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& ar, CFX_Matrix& matrix) {
diff --git a/core/fpdfapi/fpdf_edit/fpdf_edit_doc.cpp b/core/fpdfapi/fpdf_edit/fpdf_edit_doc.cpp
index 874b205c84..7688bb08ce 100644
--- a/core/fpdfapi/fpdf_edit/fpdf_edit_doc.cpp
+++ b/core/fpdfapi/fpdf_edit/fpdf_edit_doc.cpp
@@ -6,6 +6,8 @@
#include <limits.h>
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp
new file mode 100644
index 0000000000..d528017779
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp
@@ -0,0 +1,908 @@
+// 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 "core/fpdfapi/fpdf_cmaps/cmap_int.h"
+#include "core/fpdfapi/fpdf_font/font_int.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+#include "core/fpdfapi/fpdf_font/ttgsubtable.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "core/fpdfapi/include/cpdf_modulemgr.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},
+};
+
+#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,
+ FX_DWORD charcode) {
+ if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
+ return 0;
+
+ uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
+ if (cid == 0)
+ return 0;
+
+ CPDF_FontGlobals* pFontGlobals =
+ CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
+ const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
+ if (!pCodes)
+ return 0;
+
+ if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count)
+ return pCodes[cid];
+ return 0;
+}
+
+FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
+ CIDSet charset,
+ FX_WCHAR unicode) {
+ if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
+ return 0;
+
+ CPDF_FontGlobals* pFontGlobals =
+ CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
+ const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
+ if (!pCodes)
+ return 0;
+
+ int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
+ for (int i = 0; i < nCodes; ++i) {
+ if (pCodes[i] == unicode) {
+ FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
+ if (CharCode != 0) {
+ 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));
+ }
+}
+
+int CompareCIDTransform(const void* key, const void* element) {
+ uint16_t CID = *static_cast<const uint16_t*>(key);
+ return CID - static_cast<const struct CIDTransform*>(element)->CID;
+}
+
+} // namespace
+
+CPDF_CIDFont::CPDF_CIDFont()
+ : m_pCMap(nullptr),
+ m_pAllocatedCMap(nullptr),
+ m_pCID2UnicodeMap(nullptr),
+ m_pCIDToGIDMap(nullptr),
+ m_bCIDIsGID(FALSE),
+ m_pAnsiWidths(nullptr),
+ m_bAdobeCourierStd(FALSE),
+ m_pTTGSUBTable(nullptr) {}
+
+CPDF_CIDFont::~CPDF_CIDFont() {
+ if (m_pAnsiWidths) {
+ FX_Free(m_pAnsiWidths);
+ }
+ delete m_pAllocatedCMap;
+ delete m_pCIDToGIDMap;
+ delete m_pTTGSUBTable;
+}
+
+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(FX_DWORD charcode) const {
+ if (!m_pCMap) {
+ return (uint16_t)charcode;
+ }
+ return m_pCMap->CIDFromCharCode(charcode);
+}
+
+FX_BOOL CPDF_CIDFont::IsVertWriting() const {
+ return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
+}
+
+CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(FX_DWORD charcode) const {
+ CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode);
+ if (!str.IsEmpty())
+ return str;
+ FX_WCHAR ret = GetUnicodeFromCharCode(charcode);
+ if (ret == 0)
+ return CFX_WideString();
+ return ret;
+}
+
+FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(FX_DWORD charcode) const {
+ switch (m_pCMap->m_Coding) {
+ case CIDCODING_UCS2:
+ case CIDCODING_UTF16:
+ return (FX_WCHAR)charcode;
+ case CIDCODING_CID:
+ if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
+ return 0;
+ }
+ return m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)charcode);
+ }
+ if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
+ !m_pCID2UnicodeMap->IsLoaded()) {
+#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,
+ (const FX_CHAR*)&charcode, charsize,
+ &unicode, 1);
+ if (ret != 1) {
+ return 0;
+ }
+ return unicode;
+#else
+ if (m_pCMap->m_pEmbedMap) {
+ return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap,
+ m_pCMap->m_Charset, charcode);
+ }
+ return 0;
+#endif
+ }
+ return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
+}
+
+FX_DWORD CPDF_CIDFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ FX_DWORD 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;
+ }
+ FX_DWORD CID = 0;
+ while (CID < 65536) {
+ FX_WCHAR this_unicode =
+ m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID);
+ if (this_unicode == unicode) {
+ return CID;
+ }
+ CID++;
+ }
+ break;
+ }
+ }
+
+ if (unicode < 0x80) {
+ return static_cast<FX_DWORD>(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,
+ (char*)buffer, 4, NULL, NULL);
+ 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;
+}
+
+FX_BOOL CPDF_CIDFont::Load() {
+ if (m_pFontDict->GetStringBy("Subtype") == "TrueType") {
+ return LoadGB2312();
+ }
+ CPDF_Array* pFonts = m_pFontDict->GetArrayBy("DescendantFonts");
+ if (!pFonts) {
+ return FALSE;
+ }
+ if (pFonts->GetCount() != 1) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
+ if (!pCIDFontDict) {
+ return FALSE;
+ }
+ m_BaseFont = pCIDFontDict->GetStringBy("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->GetDictBy("FontDescriptor");
+ if (pFontDesc) {
+ LoadFontDescriptor(pFontDesc);
+ }
+ CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
+ if (!pEncoding) {
+ return FALSE;
+ }
+ CFX_ByteString subtype = pCIDFontDict->GetStringBy("Subtype");
+ m_bType1 = (subtype == "CIDFontType0");
+
+ if (pEncoding->IsName()) {
+ CFX_ByteString cmap = pEncoding->GetString();
+ m_pCMap =
+ CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetPredefinedCMap(cmap, m_pFontFile && m_bType1);
+ } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
+ m_pAllocatedCMap = m_pCMap = new CPDF_CMap;
+ CPDF_StreamAcc acc;
+ acc.LoadAllData(pStream, FALSE);
+ m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
+ } else {
+ return FALSE;
+ }
+ if (!m_pCMap) {
+ return FALSE;
+ }
+ m_Charset = m_pCMap->m_Charset;
+ if (m_Charset == CIDSET_UNKNOWN) {
+ CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictBy("CIDSystemInfo");
+ if (pCIDInfo) {
+ m_Charset = CharsetFromOrdering(pCIDInfo->GetStringBy("Ordering"));
+ }
+ }
+ if (m_Charset != CIDSET_UNKNOWN)
+ m_pCID2UnicodeMap =
+ CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetCID2UnicodeMap(
+ m_Charset,
+ !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID ||
+ pCIDFontDict->KeyExist("W")));
+ 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->GetIntegerBy("DW", 1000);
+ CPDF_Array* pWidthArray = pCIDFontDict->GetArrayBy("W");
+ if (pWidthArray) {
+ LoadMetricsArray(pWidthArray, m_WidthList, 1);
+ }
+ if (!IsEmbedded()) {
+ LoadSubstFont();
+ }
+ if (1) {
+ if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
+ CPDF_Object* pmap = pCIDFontDict->GetElementValue("CIDToGIDMap");
+ if (pmap) {
+ if (CPDF_Stream* pStream = pmap->AsStream()) {
+ m_pCIDToGIDMap = new CPDF_StreamAcc;
+ m_pCIDToGIDMap->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->GetArrayBy("W2");
+ if (pWidthArray) {
+ LoadMetricsArray(pWidthArray, m_VertMetrics, 3);
+ }
+ CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayBy("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(FX_DWORD charcode, int level) {
+ if (charcode < 256 && m_CharBBox[charcode].right != FX_SMALL_RECT::kInvalid)
+ return FX_RECT(m_CharBBox[charcode]);
+
+ FX_RECT rect;
+ FX_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);
+ }
+ if (rect.top > FXFT_Get_Face_Ascender(face)) {
+ rect.top = FXFT_Get_Face_Ascender(face);
+ }
+ if (rect.bottom < FXFT_Get_Face_Descender(face)) {
+ rect.bottom = 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.GetOutterRect();
+ }
+ }
+ if (charcode < 256)
+ m_CharBBox[charcode] = rect.ToSmallRect();
+
+ return rect;
+}
+int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) {
+ if (m_pAnsiWidths && charcode < 0x80) {
+ return m_pAnsiWidths[charcode];
+ }
+ uint16_t cid = CIDFromCharCode(charcode);
+ int size = m_WidthList.GetSize();
+ FX_DWORD* list = m_WidthList.GetData();
+ for (int i = 0; i < size; i += 3) {
+ if (cid >= list[i] && cid <= list[i + 1]) {
+ return (int)list[i + 2];
+ }
+ }
+ return m_DefaultWidth;
+}
+short CPDF_CIDFont::GetVertWidth(uint16_t CID) const {
+ FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
+ if (vertsize == 0) {
+ return m_DefaultW1;
+ }
+ const FX_DWORD* pTable = m_VertMetrics.GetData();
+ for (FX_DWORD i = 0; i < vertsize; i++)
+ if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
+ return (short)(int)pTable[i * 5 + 2];
+ }
+ return m_DefaultW1;
+}
+void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const {
+ FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
+ if (vertsize) {
+ const FX_DWORD* pTable = m_VertMetrics.GetData();
+ for (FX_DWORD i = 0; i < vertsize; i++)
+ if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
+ vx = (short)(int)pTable[i * 5 + 3];
+ vy = (short)(int)pTable[i * 5 + 4];
+ return;
+ }
+ }
+ FX_DWORD dwWidth = m_DefaultWidth;
+ int size = m_WidthList.GetSize();
+ const FX_DWORD* list = m_WidthList.GetData();
+ for (int i = 0; i < size; i += 3) {
+ if (CID >= list[i] && CID <= list[i + 1]) {
+ dwWidth = (uint16_t)list[i + 2];
+ break;
+ }
+ }
+ vx = (short)dwWidth / 2;
+ vy = (short)m_DefaultVY;
+}
+int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_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()) {
+ if (m_pTTGSUBTable) {
+ uint32_t vindex = 0;
+ m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
+ if (vindex) {
+ index = vindex;
+ if (pVertGlyph) {
+ *pVertGlyph = TRUE;
+ }
+ }
+ return index;
+ }
+ if (!m_Font.GetSubData()) {
+ unsigned long length = 0;
+ int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
+ NULL, &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(), NULL);
+ if (!error && m_Font.GetSubData()) {
+ m_pTTGSUBTable = new CFX_CTTGSUBTable;
+ m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
+ uint32_t vindex = 0;
+ m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
+ if (vindex) {
+ index = vindex;
+ if (pVertGlyph) {
+ *pVertGlyph = TRUE;
+ }
+ }
+ }
+ return index;
+ }
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ return index;
+}
+int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ if (!m_pFontFile && !m_pCIDToGIDMap) {
+ 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 && !(m_Flags & PDFFONT_SYMBOLIC)) {
+ unicode = UnicodeFromCharCode(charcode).GetAt(0);
+ }
+ }
+ FXFT_Face face = m_Font.GetFace();
+ if (unicode == 0) {
+ if (!m_bAdobeCourierStd) {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ charcode += 31;
+ int index = 0, iBaseEncoding;
+ FX_BOOL bMSUnicode = FT_UseTTCharmap(face, 3, 1);
+ FX_BOOL bMacRoman = FALSE;
+ if (!bMSUnicode) {
+ bMacRoman = FT_UseTTCharmap(face, 1, 0);
+ }
+ iBaseEncoding = PDFFONT_ENCODING_STANDARD;
+ if (bMSUnicode) {
+ iBaseEncoding = PDFFONT_ENCODING_WINANSI;
+ } else if (bMacRoman) {
+ iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
+ }
+ const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode);
+ if (!name) {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ uint16_t unicode = PDF_UnicodeFromAdobeName(name);
+ if (unicode) {
+ if (bMSUnicode) {
+ index = FXFT_Get_Char_Index(face, unicode);
+ } else if (bMacRoman) {
+ FX_DWORD maccode =
+ FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode);
+ index = !maccode ? FXFT_Get_Name_Index(face, (char*)name)
+ : FXFT_Get_Char_Index(face, maccode);
+ } else {
+ return FXFT_Get_Char_Index(face, unicode);
+ }
+ } else {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ if (index == 0 || index == 0xffff) {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ 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 != 0) {
+ int i;
+ for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
+ FX_DWORD ret = FT_CharCodeFromUnicode(
+ FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
+ (FX_WCHAR)charcode);
+ if (ret == 0) {
+ continue;
+ }
+ FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
+ unicode = (FX_WCHAR)ret;
+ break;
+ }
+ if (i == FXFT_Get_Face_CharmapCount(face) && i) {
+ FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
+ unicode = (FX_WCHAR)charcode;
+ }
+ }
+ if (FXFT_Get_Face_Charmap(face)) {
+ int index = GetGlyphIndex(unicode, pVertGlyph);
+ if (index == 0)
+ return -1;
+ return index;
+ }
+ return unicode;
+ }
+ if (!m_Font.GetFace())
+ return -1;
+
+ uint16_t cid = CIDFromCharCode(charcode);
+ if (m_bType1) {
+ if (!m_pCIDToGIDMap) {
+ return cid;
+ }
+ } else {
+ if (!m_pCIDToGIDMap) {
+ 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);
+ }
+ }
+ FX_DWORD byte_pos = cid * 2;
+ if (byte_pos + 2 > m_pCIDToGIDMap->GetSize())
+ return -1;
+
+ const uint8_t* pdata = m_pCIDToGIDMap->GetData() + byte_pos;
+ return pdata[0] * 256 + pdata[1];
+}
+FX_DWORD CPDF_CIDFont::GetNextChar(const FX_CHAR* pString,
+ int nStrLen,
+ int& offset) const {
+ return m_pCMap->GetNextChar(pString, nStrLen, offset);
+}
+int CPDF_CIDFont::GetCharSize(FX_DWORD 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, FX_DWORD charcode) const {
+ return m_pCMap->AppendChar(str, charcode);
+}
+FX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const {
+ if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
+ !m_pCID2UnicodeMap->IsLoaded()) {
+ return m_pCMap->m_Coding != CIDCODING_UNKNOWN;
+ }
+ return TRUE;
+}
+FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const {
+ return TRUE;
+}
+void CPDF_CIDFont::LoadSubstFont() {
+ m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle,
+ g_CharsetCPs[m_Charset], IsVertWriting());
+}
+void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
+ CFX_DWordArray& result,
+ int nElements) {
+ int width_status = 0;
+ int iCurElement = 0;
+ int first_code = 0;
+ int last_code = 0;
+ FX_DWORD count = pArray->GetCount();
+ for (FX_DWORD i = 0; i < count; i++) {
+ CPDF_Object* pObj = pArray->GetElementValue(i);
+ if (!pObj)
+ continue;
+
+ if (CPDF_Array* pArray = pObj->AsArray()) {
+ if (width_status != 1)
+ return;
+
+ FX_DWORD count = pArray->GetCount();
+ for (FX_DWORD j = 0; j < count; j += nElements) {
+ result.Add(first_code);
+ result.Add(first_code);
+ for (int k = 0; k < nElements; k++) {
+ result.Add(pArray->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) {
+ if (ch < 128) {
+ return ch * 1.0f / 127;
+ }
+ return (-255 + ch) * 1.0f / 127;
+}
+
+FX_BOOL CPDF_CIDFont::LoadGB2312() {
+ m_BaseFont = m_pFontDict->GetStringBy("BaseFont");
+ CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc) {
+ LoadFontDescriptor(pFontDesc);
+ }
+ m_Charset = CIDSET_GB1;
+ m_bType1 = FALSE;
+ m_pCMap = CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE);
+ m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE);
+ if (!IsEmbedded()) {
+ LoadSubstFont();
+ }
+ CheckFontMetrics();
+ m_DefaultWidth = 1000;
+ m_pAnsiWidths = FX_Alloc(uint16_t, 128);
+ for (int i = 32; i < 127; i++) {
+ m_pAnsiWidths[i] = 500;
+ }
+ return TRUE;
+}
+
+const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
+ if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
+ return nullptr;
+
+ const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch(
+ &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs),
+ sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform);
+ return found ? &found->a : nullptr;
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.h b/core/fpdfapi/fpdf_font/cpdf_cidfont.h
new file mode 100644
index 0000000000..6ff7c825d2
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_cidfont.h
@@ -0,0 +1,89 @@
+// 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 "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/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(FX_DWORD charcode, FX_BOOL* pVertGlyph = NULL) override;
+ int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
+ FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) override;
+ FX_DWORD 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, FX_DWORD charcode) const override;
+ int GetCharSize(FX_DWORD charcode) const override;
+ FX_BOOL IsVertWriting() const override;
+ FX_BOOL IsUnicodeCompatible() const override;
+ FX_BOOL Load() override;
+ CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const override;
+ FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const override;
+
+ FX_BOOL LoadGB2312();
+ uint16_t CIDFromCharCode(FX_DWORD 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;
+ virtual FX_BOOL IsFontStyleFromCharCode(FX_DWORD charcode) const;
+
+ protected:
+ int GetGlyphIndex(FX_DWORD unicodeb, FX_BOOL* pVertGlyph);
+ void LoadMetricsArray(CPDF_Array* pArray,
+ CFX_DWordArray& result,
+ int nElements);
+ void LoadSubstFont();
+ FX_WCHAR GetUnicodeFromCharCode(FX_DWORD charcode) const;
+
+ CPDF_CMap* m_pCMap;
+ CPDF_CMap* m_pAllocatedCMap;
+ CPDF_CID2UnicodeMap* m_pCID2UnicodeMap;
+ CIDSet m_Charset;
+ FX_BOOL m_bType1;
+ CPDF_StreamAcc* m_pCIDToGIDMap;
+ FX_BOOL m_bCIDIsGID;
+ uint16_t m_DefaultWidth;
+ uint16_t* m_pAnsiWidths;
+ FX_SMALL_RECT m_CharBBox[256];
+ CFX_DWordArray m_WidthList;
+ short m_DefaultVY;
+ short m_DefaultW1;
+ CFX_DWordArray m_VertMetrics;
+ FX_BOOL m_bAdobeCourierStd;
+ CFX_CTTGSUBTable* 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
new file mode 100644
index 0000000000..bb63966161
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_font.cpp
@@ -0,0 +1,492 @@
+// 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/include/cpdf_font.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_font/include/cpdf_fontencoding.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "core/fpdfapi/include/cpdf_modulemgr.h"
+#include "core/include/fxge/fx_freetype.h"
+
+namespace {
+
+const uint8_t ChineseFontNames[][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}};
+
+FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
+ 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;
+ else
+ return FALSE;
+ return TRUE;
+}
+
+} // namespace
+
+CPDF_Font::CPDF_Font()
+ : m_pFontFile(nullptr),
+ m_pFontDict(nullptr),
+ m_pToUnicodeMap(nullptr),
+ m_bToUnicodeLoaded(FALSE),
+ m_Flags(0),
+ m_StemV(0),
+ m_Ascent(0),
+ m_Descent(0),
+ m_ItalicAngle(0) {}
+
+CPDF_Font::~CPDF_Font() {
+ delete m_pToUnicodeMap;
+ m_pToUnicodeMap = NULL;
+
+ if (m_pFontFile) {
+ m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
+ const_cast<CPDF_Stream*>(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;
+}
+
+FX_BOOL CPDF_Font::IsUnicodeCompatible() const {
+ return FALSE;
+}
+
+int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
+ return size;
+}
+
+int CPDF_Font::GetCharSize(FX_DWORD charcode) const {
+ return 1;
+}
+
+int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
+ ASSERT(false);
+ return 0;
+}
+
+int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
+ return GlyphFromCharCode(charcode);
+}
+
+FX_BOOL CPDF_Font::IsVertWriting() const {
+ FX_BOOL bVertWriting = FALSE;
+ const CPDF_CIDFont* pCIDFont = AsCIDFont();
+ if (pCIDFont) {
+ bVertWriting = pCIDFont->IsVertWriting();
+ } else {
+ bVertWriting = m_Font.IsVertical();
+ }
+ return bVertWriting;
+}
+
+int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
+ *buf = (FX_CHAR)charcode;
+ return 1;
+}
+
+void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD 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(FX_DWORD charcode) const {
+ if (!m_bToUnicodeLoaded)
+ ((CPDF_Font*)this)->LoadUnicodeMap();
+
+ if (m_pToUnicodeMap)
+ return m_pToUnicodeMap->Lookup(charcode);
+ return CFX_WideString();
+}
+
+FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ if (!m_bToUnicodeLoaded)
+ ((CPDF_Font*)this)->LoadUnicodeMap();
+
+ if (m_pToUnicodeMap)
+ return m_pToUnicodeMap->ReverseLookup(unicode);
+ return 0;
+}
+
+void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
+ m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
+ int ItalicAngle = 0;
+ FX_BOOL bExistItalicAngle = FALSE;
+ if (pFontDesc->KeyExist("ItalicAngle")) {
+ ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
+ bExistItalicAngle = TRUE;
+ }
+ if (ItalicAngle < 0) {
+ m_Flags |= PDFFONT_ITALIC;
+ m_ItalicAngle = ItalicAngle;
+ }
+ FX_BOOL bExistStemV = FALSE;
+ if (pFontDesc->KeyExist("StemV")) {
+ m_StemV = pFontDesc->GetIntegerBy("StemV");
+ bExistStemV = TRUE;
+ }
+ FX_BOOL bExistAscent = FALSE;
+ if (pFontDesc->KeyExist("Ascent")) {
+ m_Ascent = pFontDesc->GetIntegerBy("Ascent");
+ bExistAscent = TRUE;
+ }
+ FX_BOOL bExistDescent = FALSE;
+ if (pFontDesc->KeyExist("Descent")) {
+ m_Descent = pFontDesc->GetIntegerBy("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->GetArrayBy("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->GetStreamBy("FontFile");
+ if (!pFontFile)
+ pFontFile = pFontDesc->GetStreamBy("FontFile2");
+ if (!pFontFile)
+ pFontFile = pFontDesc->GetStreamBy("FontFile3");
+ if (!pFontFile)
+ return;
+
+ m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
+ if (!m_pFontFile)
+ return;
+
+ const uint8_t* pFontData = m_pFontFile->GetData();
+ FX_DWORD dwFontSize = m_pFontFile->GetSize();
+ if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
+ m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
+ const_cast<CPDF_Stream*>(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() {
+ m_bToUnicodeLoaded = TRUE;
+ CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
+ if (!pStream) {
+ return;
+ }
+ m_pToUnicodeMap = 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) {
+ FX_DWORD 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;
+ pDict->SetAtName("Type", "Font");
+ pDict->SetAtName("Subtype", "Type1");
+ pDict->SetAtName("BaseFont", fontname);
+ pDict->SetAtName("Encoding", "WinAnsiEncoding");
+ pFont = CPDF_Font::CreateFontF(NULL, pDict);
+ pFontGlobals->Set(pDoc, font_id, pFont);
+ return pFont;
+}
+
+CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
+ CPDF_Dictionary* pFontDict) {
+ CFX_ByteString type = pFontDict->GetStringBy("Subtype");
+ CPDF_Font* pFont;
+ if (type == "TrueType") {
+ {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
+ _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
+ _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
+ _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont");
+ CFX_ByteString tag = basefont.Left(4);
+ int i;
+ int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
+ for (i = 0; i < count; ++i) {
+ if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
+ break;
+ }
+ }
+ if (i < count) {
+ CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
+ if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
+ pFont = new CPDF_CIDFont;
+ pFont->m_pFontDict = pFontDict;
+ pFont->m_pDocument = pDoc;
+ pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
+ if (!pFont->Load()) {
+ delete pFont;
+ return NULL;
+ }
+ return pFont;
+ }
+ }
+#endif
+ }
+ pFont = new CPDF_TrueTypeFont;
+ } else if (type == "Type3") {
+ pFont = new CPDF_Type3Font;
+ } else if (type == "Type0") {
+ pFont = new CPDF_CIDFont;
+ } else {
+ pFont = new CPDF_Type1Font;
+ }
+ pFont->m_pFontDict = pFontDict;
+ pFont->m_pDocument = pDoc;
+ pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
+ if (!pFont->Load()) {
+ delete pFont;
+ return NULL;
+ }
+ return pFont;
+}
+
+FX_DWORD 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<FX_DWORD>(ch);
+}
+
+void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
+ int& iBaseEncoding,
+ CFX_ByteString*& pCharNames,
+ FX_BOOL bEmbedded,
+ FX_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(iBaseEncoding, bsEncoding);
+ return;
+ }
+
+ CPDF_Dictionary* pDict = pEncoding->AsDictionary();
+ if (!pDict)
+ return;
+
+ if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
+ iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
+ CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
+ if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
+ bsEncoding = "WinAnsiEncoding";
+ }
+ GetPredefinedEncoding(iBaseEncoding, bsEncoding);
+ }
+ if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
+ iBaseEncoding = PDFFONT_ENCODING_STANDARD;
+ }
+ CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
+ if (!pDiffs) {
+ return;
+ }
+ pCharNames = new CFX_ByteString[256];
+ FX_DWORD cur_code = 0;
+ for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
+ CPDF_Object* pElement = pDiffs->GetElementValue(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();
+ }
+ }
+}
+
+FX_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 CFX_ByteString* pCharNames,
+ int charcode) {
+ ASSERT(charcode >= 0 && charcode < 256);
+ if (charcode < 0 || charcode >= 256)
+ return nullptr;
+
+ const FX_CHAR* name = nullptr;
+ if (pCharNames)
+ name = pCharNames[charcode];
+ if ((!name || name[0] == 0) && iBaseEncoding)
+ name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
+ return name && name[0] ? name : nullptr;
+}
diff --git a/core/fpdfapi/fpdf_font/fpdf_font_charset.cpp b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp
index 1b503c69a6..64e11e09de 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font_charset.cpp
+++ b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp
@@ -1,77 +1,52 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// 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_parser/include/fpdf_parser_decode.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/include/fxge/fx_freetype.h"
+#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
-static const struct _UnicodeAlt {
- uint16_t m_Unicode;
- const FX_CHAR* m_Alter;
-} UnicodeAlts[] = {
- {0x00a0, " "}, {0x00a1, "!"}, {0x00a2, "c"}, {0x00a3, "P"},
- {0x00a4, "o"}, {0x00a5, "Y"}, {0x00a6, "|"}, {0x00a7, "S"},
- {0x00a9, "(C)"}, {0x00aa, "a"}, {0x00ab, "<<"}, {0x00ac, "-|"},
- {0x00ae, "(R)"}, {0x00af, "-"}, {0x00b0, "o"}, {0x00b1, "+/-"},
- {0x00b2, "^2"}, {0x00b3, "^3"}, {0x00b4, "'"}, {0x00b5, "u"},
- {0x00b6, "P"}, {0x00b7, "."}, {0x00b9, "^1"}, {0x00ba, "o"},
- {0x00bb, ">>"}, {0x00bc, "1/4"}, {0x00bd, "1/2"}, {0x00be, "3/4"},
- {0x00bf, "?"}, {0x00c0, "A"}, {0x00c1, "A"}, {0x00c2, "A"},
- {0x00c3, "A"}, {0x00c4, "A"}, {0x00c5, "A"}, {0x00c6, "AE"},
- {0x00c7, "C"}, {0x00c8, "E"}, {0x00c9, "E"}, {0x00ca, "E"},
- {0x00cb, "E"}, {0x00cc, "I"}, {0x00cd, "I"}, {0x00ce, "I"},
- {0x00cf, "I"}, {0x00d1, "N"}, {0x00d2, "O"}, {0x00d3, "O"},
- {0x00d4, "O"}, {0x00d5, "O"}, {0x00d6, "O"}, {0x00d7, "x"},
- {0x00d8, "O"}, {0x00d9, "U"}, {0x00da, "U"}, {0x00db, "U"},
- {0x00dc, "U"}, {0x00dd, "Y"}, {0x00df, "S"}, {0x00e0, "a"},
- {0x00e1, "a"}, {0x00e2, "a"}, {0x00e3, "a"}, {0x00e4, "a"},
- {0x00e5, "a"}, {0x00e6, "ae"}, {0x00e7, "c"}, {0x00e8, "e"},
- {0x00e9, "e"}, {0x00ea, "e"}, {0x00eb, "e"}, {0x00ec, "i"},
- {0x00ed, "i"}, {0x00ee, "i"}, {0x00ef, "i"}, {0x00f1, "n"},
- {0x00f2, "o"}, {0x00f3, "o"}, {0x00f4, "o"}, {0x00f5, "o"},
- {0x00f6, "o"}, {0x00f7, "/"}, {0x00f8, "o"}, {0x00f9, "u"},
- {0x00fa, "u"}, {0x00fb, "u"}, {0x00fc, "u"}, {0x00fd, "y"},
- {0x00ff, "y"}, {0x02b0, "h"}, {0x02b2, "j"}, {0x02b3, "r"},
- {0x02b7, "w"}, {0x02b8, "y"}, {0x02b9, "'"}, {0x02ba, "\""},
- {0x02bb, "'"}, {0x02bc, "'"}, {0x02bd, "'"}, {0x02be, "'"},
- {0x02bf, "'"}, {0x02c2, "<"}, {0x02c3, ">"}, {0x02c4, "^"},
- {0x02c5, "v"}, {0x02c6, "^"}, {0x02c7, "v"}, {0x02c8, "'"},
- {0x02c9, "-"}, {0x02ca, "'"}, {0x02cb, "'"}, {0x02cc, "."},
- {0x02cd, "_"}, {0x2010, "-"}, {0x2012, "-"}, {0x2013, "-"},
- {0x2014, "--"}, {0x2015, "--"}, {0x2016, "|"}, {0x2017, "_"},
- {0x2018, "'"}, {0x2019, "'"}, {0x201a, ","}, {0x201b, "'"},
- {0x201c, "\""}, {0x201d, "\""}, {0x201e, ","}, {0x201f, "'"},
- {0x2020, "+"}, {0x2021, "+"}, {0x2022, "*"}, {0x2023, ">"},
- {0x2024, "."}, {0x2025, ".."}, {0x2027, "."}, {0x2032, "'"},
- {0x2033, "\""}, {0x2035, "'"}, {0x2036, "\""}, {0x2038, "^"},
- {0x2039, "<"}, {0x203a, ">"}, {0x203b, "*"}, {0x203c, "!!"},
- {0x203d, "?!"}, {0x203e, "-"}, {0x2044, "/"}, {0x2047, "??"},
- {0x2048, "?!"}, {0x2049, "!?"}, {0x204e, "*"}, {0x2052, "%"},
- {0x2122, "(TM)"}, {0x2212, "-"}, {0x2215, "/"}, {0x2216, "\\"},
- {0x2217, "*"}, {0x2218, "*"}, {0x2219, "*"}, {0x2223, "|"},
- {0x22c5, "."}, {0x266f, "#"}, {0XF6D9, "(C)"}, {0XF6DA, "(C)"},
- {0XF6DB, "(TM)"}, {0XF8E8, "(C)"}, {0xf8e9, "(C)"}, {0XF8EA, "(TM)"},
- {0xfb01, "fi"}, {0xfb02, "fl"}};
-const FX_CHAR* FCS_GetAltStr(FX_WCHAR unicode) {
- int begin = 0;
- int end = sizeof UnicodeAlts / sizeof(struct _UnicodeAlt) - 1;
- while (begin <= end) {
- int middle = (begin + end) / 2;
- uint16_t middlecode = UnicodeAlts[middle].m_Unicode;
- if (middlecode > unicode) {
- end = middle - 1;
- } else if (middlecode < unicode) {
- begin = middle + 1;
- } else {
- return UnicodeAlts[middle].m_Alter;
- }
- }
- return NULL;
-}
-static const uint16_t StandardEncoding[256] = {
+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,
@@ -101,7 +76,8 @@ static const uint16_t StandardEncoding[256] = {
0x0152, 0x00ba, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00e6, 0x0000,
0x0000, 0x0000, 0x0131, 0x0000, 0x0000, 0x0142, 0x00f8, 0x0153, 0x00df,
0x0000, 0x0000, 0x0000, 0x0000};
-static const uint16_t MacRomanEncoding[256] = {
+
+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,
@@ -131,7 +107,8 @@ static const uint16_t MacRomanEncoding[256] = {
0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, 0x0000, 0x00d2, 0x00da,
0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da,
0x00b8, 0x02dd, 0x02db, 0x02c7};
-static const uint16_t AdobeWinAnsiEncoding[256] = {
+
+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,
@@ -161,7 +138,8 @@ static const uint16_t AdobeWinAnsiEncoding[256] = {
0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
0x00fc, 0x00fd, 0x00fe, 0x00ff};
-static const uint16_t MacExpertEncoding[256] = {
+
+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,
@@ -191,7 +169,8 @@ static const uint16_t MacExpertEncoding[256] = {
0xf6f2, 0xf6eb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf6ee, 0xf6fb,
0xf6f4, 0xf7af, 0xf6ea, 0x207f, 0xf6ef, 0xf6e2, 0xf6e8, 0xf6f7, 0xf6fc,
0x0000, 0x0000, 0x0000, 0x0000};
-static const uint16_t AdobeSymbolEncoding[256] = {
+
+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,
@@ -222,7 +201,8 @@ static const uint16_t AdobeSymbolEncoding[256] = {
0x2320, 0xF8F5, 0x2321, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, 0xF8FA, 0xF8FB,
0xF8FC, 0xF8FD, 0xF8FE, 0x0000,
};
-static const uint16_t ZapfEncoding[256] = {
+
+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,
@@ -253,7 +233,8 @@ static const uint16_t ZapfEncoding[256] = {
0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, 0x27B8, 0x27B9, 0x27BA, 0x27BB,
0x27BC, 0x27BD, 0x27BE, 0x0000,
};
-static const FX_CHAR* const StandardEncodingNames[224] = {
+
+const FX_CHAR* const StandardEncodingNames[224] = {
"space",
"exclam",
"quotedbl",
@@ -479,7 +460,8 @@ static const FX_CHAR* const StandardEncodingNames[224] = {
NULL,
NULL,
};
-static const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = {
+
+const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = {
"space",
"exclam",
"quotedbl",
@@ -705,7 +687,8 @@ static const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = {
"thorn",
"ydieresis",
};
-static const FX_CHAR* const MacRomanEncodingNames[224] = {
+
+const FX_CHAR* const MacRomanEncodingNames[224] = {
"space",
"exclam",
"quotedbl",
@@ -931,7 +914,8 @@ static const FX_CHAR* const MacRomanEncodingNames[224] = {
"ogonek",
"caron",
};
-static const FX_CHAR* const MacExpertEncodingNames[224] = {
+
+const FX_CHAR* const MacExpertEncodingNames[224] = {
"space",
"exclamsmall",
"Hungarumlautsmall",
@@ -1157,7 +1141,8 @@ static const FX_CHAR* const MacExpertEncodingNames[224] = {
NULL,
NULL,
};
-static const FX_CHAR* const PDFDocEncodingNames[232] = {
+
+const FX_CHAR* const PDFDocEncodingNames[232] = {
"breve",
"caron",
"circumflex",
@@ -1391,7 +1376,8 @@ static const FX_CHAR* const PDFDocEncodingNames[232] = {
"thorn",
"ydieresis",
};
-static const FX_CHAR* const AdobeSymbolEncodingNames[224] = {
+
+const FX_CHAR* const AdobeSymbolEncodingNames[224] = {
"space",
"exclam",
"universal",
@@ -1617,7 +1603,8 @@ static const FX_CHAR* const AdobeSymbolEncodingNames[224] = {
"bracerightbt",
NULL,
};
-static const FX_CHAR* const ZapfEncodingNames[224] = {
+
+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",
@@ -1643,91 +1630,89 @@ static const FX_CHAR* const ZapfEncodingNames[224] = {
"a176", "a177", "a178", "a179", "a193", "a180", "a199", "a181", "a200",
"a182", NULL, "a201", "a183", "a184", "a197", "a185", "a194", "a198",
"a186", "a195", "a187", "a188", "a189", "a190", "a191", NULL};
-const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding,
- uint8_t charcode) {
- if (encoding == PDFFONT_ENCODING_PDFDOC) {
- if (charcode < 24) {
- return NULL;
+
+FX_DWORD PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) {
+ for (FX_DWORD 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;
}
- charcode -= 24;
+ 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 {
- if (charcode < 32) {
- return NULL;
- }
- charcode -= 32;
+ for (int i = 0; i < 256; i++)
+ m_Unicodes[i] = pSrc[i];
}
- 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 NULL;
}
-FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD 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;
+
+FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const {
+ return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) ==
+ 0;
}
-static FX_DWORD PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) {
- for (FX_DWORD i = 0; i < 256; i++)
- if (pCodes[i] == unicode) {
- return i;
+
+CPDF_Object* CPDF_FontEncoding::Realize() {
+ 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;
+ }
}
- return 0;
+ if (match) {
+ predefined = cs;
+ break;
+ }
+ }
+ if (predefined) {
+ if (predefined == PDFFONT_ENCODING_WINANSI) {
+ return new CPDF_Name("WinAnsiEncoding");
+ }
+ if (predefined == PDFFONT_ENCODING_MACROMAN) {
+ return new CPDF_Name("MacRomanEncoding");
+ }
+ if (predefined == PDFFONT_ENCODING_MACEXPERT) {
+ return new CPDF_Name("MacExpertEncoding");
+ }
+ return NULL;
+ }
+ 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;
+ pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
+ pDict->SetAt("Differences", pDiff);
+ return pDict;
}
-static 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};
+
FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode) {
switch (encoding) {
case FXFT_ENCODING_UNICODE:
@@ -1768,14 +1753,63 @@ const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding) {
}
return NULL;
}
-FX_DWORD PDF_PredefinedCharCodeFromUnicode(int encoding, FX_WCHAR unicode) {
- return PDF_FindCode(PDF_UnicodesForPredefinedCharSet(encoding), unicode);
-}
+
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 NULL;
+
+ charcode -= 24;
+ } else {
+ if (charcode < 32)
+ return NULL;
+
+ 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, FX_DWORD 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_simplefont.cpp b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp
new file mode 100644
index 0000000000..d7057e1894
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp
@@ -0,0 +1,222 @@
+// 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/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/include/fxge/fx_freetype.h"
+
+CPDF_SimpleFont::CPDF_SimpleFont()
+ : m_pCharNames(nullptr), 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);
+}
+
+CPDF_SimpleFont::~CPDF_SimpleFont() {
+ delete[] m_pCharNames;
+}
+
+int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ if (charcode > 0xff) {
+ return -1;
+ }
+ int index = m_GlyphIndex[(uint8_t)charcode];
+ if (index == 0xffff) {
+ return -1;
+ }
+ return index;
+}
+
+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;
+ }
+ m_CharBBox[charcode] = FX_SMALL_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));
+
+ 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(FX_DWORD charcode, int level) {
+ if (charcode > 0xff) {
+ charcode = 0;
+ }
+ if (m_CharWidth[charcode] == 0xffff) {
+ LoadCharMetrics(charcode);
+ if (m_CharWidth[charcode] == 0xffff) {
+ m_CharWidth[charcode] = 0;
+ }
+ }
+ return (int16_t)m_CharWidth[charcode];
+}
+
+FX_RECT CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, int level) {
+ if (charcode > 0xff)
+ charcode = 0;
+
+ if (m_CharBBox[charcode].left == FX_SMALL_RECT::kInvalid)
+ LoadCharMetrics(charcode);
+
+ return FX_RECT(m_CharBBox[charcode]);
+}
+
+FX_BOOL CPDF_SimpleFont::LoadCommon() {
+ CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc) {
+ LoadFontDescriptor(pFontDesc);
+ }
+ CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
+ int width_start = 0, width_end = -1;
+ m_bUseFontWidth = TRUE;
+ if (pWidthArray) {
+ m_bUseFontWidth = FALSE;
+ if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
+ int MissingWidth = pFontDesc->GetIntegerBy("MissingWidth");
+ for (int i = 0; i < 256; i++) {
+ m_CharWidth[i] = MissingWidth;
+ }
+ }
+ width_start = m_pFontDict->GetIntegerBy("FirstChar", 0);
+ width_end = m_pFontDict->GetIntegerBy("LastChar", 0);
+ if (width_start >= 0 && width_start <= 255) {
+ if (width_end <= 0 ||
+ width_end >= width_start + (int)pWidthArray->GetCount()) {
+ width_end = width_start + pWidthArray->GetCount() - 1;
+ }
+ if (width_end > 255) {
+ width_end = 255;
+ }
+ for (int 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->GetElementValue("Encoding");
+ LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
+ m_Font.IsTTFont());
+ LoadGlyphMap();
+ delete[] m_pCharNames;
+ m_pCharNames = NULL;
+ if (!m_Font.GetFace())
+ return TRUE;
+
+ if (m_Flags & PDFFONT_ALLCAP) {
+ unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
+ for (size_t range = 0; range < sizeof lowercases / 2; range++) {
+ for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
+ if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
+ continue;
+ }
+ m_GlyphIndex[i] = m_GlyphIndex[i - 32];
+ if (m_CharWidth[i - 32]) {
+ m_CharWidth[i] = m_CharWidth[i - 32];
+ m_CharBBox[i] = m_CharBBox[i - 32];
+ }
+ }
+ }
+ }
+ 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;
+ }
+ }
+ int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
+ m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, weight, m_ItalicAngle,
+ 0);
+ if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
+ }
+}
+
+FX_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(FX_DWORD 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;
+}
+
+FX_DWORD CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ FX_DWORD 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
new file mode 100644
index 0000000000..19d6816c9f
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_simplefont.h
@@ -0,0 +1,48 @@
+// 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 "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_SimpleFont : public CPDF_Font {
+ public:
+ CPDF_SimpleFont();
+ virtual ~CPDF_SimpleFont();
+
+ // CPDF_Font:
+ int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
+ FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) override;
+ int GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph = NULL) override;
+ FX_BOOL IsUnicodeCompatible() const override;
+ CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const override;
+ FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const override;
+
+ CPDF_FontEncoding* GetEncoding() { return &m_Encoding; }
+
+ protected:
+ virtual void LoadGlyphMap() = 0;
+
+ FX_BOOL LoadCommon();
+ void LoadSubstFont();
+ void LoadFaceMetrics();
+ void LoadCharMetrics(int charcode);
+
+ CPDF_FontEncoding m_Encoding;
+ uint16_t m_GlyphIndex[256];
+ uint16_t m_ExtGID[256];
+ CFX_ByteString* m_pCharNames;
+ int m_BaseEncoding;
+ uint16_t m_CharWidth[256];
+ FX_SMALL_RECT m_CharBBox[256];
+ FX_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
new file mode 100644
index 0000000000..13e031808e
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp
@@ -0,0 +1,225 @@
+// 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/include/cpdf_dictionary.h"
+#include "core/include/fxge/fx_font.h"
+
+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;
+}
+
+FX_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_pCharNames) ||
+ (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->GetIntegerBy("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;
+ }
+ FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
+ FX_BOOL bMacRoman = FALSE, 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_pCharNames, 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) {
+ 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 (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) {
+ FX_DWORD 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)) {
+ const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
+ FX_BOOL bGotOne = FALSE;
+ for (int charcode = 0; charcode < 256; charcode++) {
+ 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 (m_GlyphIndex[charcode]) {
+ bGotOne = TRUE;
+ break;
+ }
+ }
+ }
+ if (bGotOne) {
+ if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
+ if (!name) {
+ continue;
+ }
+ 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)) {
+ FX_BOOL bGotOne = 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]) {
+ bGotOne = TRUE;
+ }
+ }
+ if (m_pFontFile || bGotOne) {
+ return;
+ }
+ }
+ if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
+ FX_BOOL bGotOne = 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_pCharNames, 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]) {
+ bGotOne = TRUE;
+ }
+ }
+ if (bGotOne) {
+ 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
new file mode 100644
index 0000000000..46b19e513d
--- /dev/null
+++ b/core/fpdfapi/fpdf_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_FPDF_FONT_CPDF_TRUETYPEFONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_
+
+#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h"
+#include "core/fxcrt/include/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:
+ FX_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
new file mode 100644
index 0000000000..5a6ee34362
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp
@@ -0,0 +1,403 @@
+// 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/include/cpdf_dictionary.h"
+#include "core/include/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"},
+ {"fi", "uniFB01"},
+ {"fl", "uniFB02"},
+ {"ffi", "uniFB03"},
+ {"ffl", "uniFB04"}};
+
+int compareString(const void* key, const void* element) {
+ return FXSYS_stricmp((const FX_CHAR*)key,
+ ((GlyphNameMap*)element)->m_pStrAdobe);
+}
+
+const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) {
+ GlyphNameMap* found = (GlyphNameMap*)FXSYS_bsearch(
+ pStrAdobe, g_GlyphNameSubsts,
+ sizeof(g_GlyphNameSubsts) / sizeof(GlyphNameMap), sizeof(GlyphNameMap),
+ compareString);
+ if (found)
+ return found->m_pStrUnicode;
+ return NULL;
+}
+
+#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;
+}
+
+FX_BOOL CPDF_Type1Font::Load() {
+ m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
+ if (m_Base14Font >= 0) {
+ CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc && pFontDesc->KeyExist("Flags"))
+ m_Flags = pFontDesc->GetIntegerBy("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(FX_DWORD 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_
+ FX_BOOL bCoreText = TRUE;
+ CQuartz2D& quartz2d =
+ ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ if (!m_Font.GetPlatformFont()) {
+ if (m_Font.GetPsName() == CFX_WideString::FromLocal("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_pCharNames, 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_pCharNames, 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_pCharNames, 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
+ if (m_Flags & PDFFONT_SYMBOLIC) {
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, 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_pCharNames, 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
new file mode 100644
index 0000000000..da82cd4417
--- /dev/null
+++ b/core/fpdfapi/fpdf_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_FPDF_FONT_CPDF_TYPE1FONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_
+
+#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h"
+#include "core/fxcrt/include/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(FX_DWORD charcode) override;
+
+ int GetBase14Font() const { return m_Base14Font; }
+
+ protected:
+ // CPDF_Font:
+ FX_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
new file mode 100644
index 0000000000..c9d44435a3
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3char.cpp
@@ -0,0 +1,43 @@
+// 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/include/cpdf_form.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
+#include "core/include/fxge/fx_dib.h"
+
+CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
+ : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
+
+CPDF_Type3Char::~CPDF_Type3Char() {
+ delete m_pForm;
+ delete m_pBitmap;
+}
+
+FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) {
+ if (m_pBitmap || !m_pForm) {
+ return TRUE;
+ }
+ if (m_pForm->GetPageObjectList()->size() == 1 && !m_bColored) {
+ auto& pPageObj = m_pForm->GetPageObjectList()->front();
+ if (pPageObj->IsImage()) {
+ m_ImageMatrix = pPageObj->AsImage()->m_Matrix;
+ const CFX_DIBSource* pSource =
+ pPageObj->AsImage()->m_pImage->LoadDIBSource();
+ if (pSource) {
+ m_pBitmap = pSource->Clone();
+ delete pSource;
+ }
+ delete m_pForm;
+ m_pForm = NULL;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_type3char.h b/core/fpdfapi/fpdf_font/cpdf_type3char.h
new file mode 100644
index 0000000000..c67620b5f6
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3char.h
@@ -0,0 +1,33 @@
+// 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 "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/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);
+
+ CPDF_Form* m_pForm;
+ CFX_DIBitmap* 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
new file mode 100644
index 0000000000..91a03a9830
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp
@@ -0,0 +1,162 @@
+// 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 "core/fpdfapi/fpdf_font/cpdf_type3char.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fxcrt/include/fx_system.h"
+#include "third_party/base/stl_util.h"
+
+CPDF_Type3Font::CPDF_Type3Font()
+ : m_pCharProcs(nullptr),
+ m_pPageResources(nullptr),
+ m_pFontResources(nullptr) {
+ FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
+}
+
+CPDF_Type3Font::~CPDF_Type3Font() {
+ for (auto it : m_CacheMap)
+ delete it.second;
+}
+
+bool CPDF_Type3Font::IsType3Font() const {
+ return true;
+}
+
+const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
+ return this;
+}
+
+CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
+ return this;
+}
+
+FX_BOOL CPDF_Type3Font::Load() {
+ m_pFontResources = m_pFontDict->GetDictBy("Resources");
+ CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("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->GetArrayBy("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->GetIntegerBy("FirstChar");
+ CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
+ if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
+ FX_DWORD count = pWidthArray->GetCount();
+ if (count > 256) {
+ count = 256;
+ }
+ if (StartChar + count > 256) {
+ count = 256 - StartChar;
+ }
+ for (FX_DWORD i = 0; i < count; i++) {
+ m_CharWidthL[StartChar + i] =
+ FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
+ }
+ }
+ m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
+ CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
+ if (pEncoding) {
+ LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
+ if (m_pCharNames) {
+ for (int i = 0; i < 256; i++) {
+ m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
+ 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(FX_DWORD charcode, int level) {
+ if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
+ return nullptr;
+
+ auto it = m_CacheMap.find(charcode);
+ if (it != m_CacheMap.end())
+ return it->second;
+
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (!name)
+ return nullptr;
+
+ CPDF_Stream* pStream =
+ ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
+ if (!pStream)
+ return nullptr;
+
+ std::unique_ptr<CPDF_Type3Char> 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.
+ pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
+ level + 1);
+ it = m_CacheMap.find(charcode);
+ if (it != m_CacheMap.end())
+ return it->second;
+
+ 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));
+ CPDF_Type3Char* pCachedChar = pNewChar.release();
+ m_CacheMap[charcode] = pCachedChar;
+ if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
+ delete pCachedChar->m_pForm;
+ pCachedChar->m_pForm = nullptr;
+ }
+ return pCachedChar;
+}
+
+int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
+ if (charcode >= FX_ArraySize(m_CharWidthL))
+ charcode = 0;
+
+ if (m_CharWidthL[charcode])
+ return m_CharWidthL[charcode];
+
+ const CPDF_Type3Char* pChar = LoadChar(charcode, level);
+ return pChar ? pChar->m_Width : 0;
+}
+
+FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) {
+ const CPDF_Type3Char* pChar = LoadChar(charcode, level);
+ 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
new file mode 100644
index 0000000000..554556934e
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3font.h
@@ -0,0 +1,56 @@
+// 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 <map>
+
+#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/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(FX_DWORD charcode, int level = 0) override;
+ FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) override;
+
+ void SetPageResources(CPDF_Dictionary* pResources) {
+ m_pPageResources = pResources;
+ }
+ CPDF_Type3Char* LoadChar(FX_DWORD charcode, int level = 0);
+ void CheckType3FontMetrics();
+
+ CFX_Matrix& GetFontMatrix() { return m_FontMatrix; }
+
+ protected:
+ CFX_Matrix m_FontMatrix;
+
+ private:
+ // CPDF_Font:
+ FX_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<FX_DWORD, CPDF_Type3Char*> m_CacheMap;
+};
+
+#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
index 74380f1147..b9b5b5327d 100644
--- a/core/fpdfapi/fpdf_font/font_int.h
+++ b/core/fpdfapi/fpdf_font/font_int.h
@@ -10,8 +10,8 @@
#include <map>
#include <memory>
+#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h"
#include "core/fxcrt/include/fx_basic.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
class CPDF_CID2UnicodeMap;
class CPDF_CMap;
@@ -22,6 +22,7 @@ typedef void* FXFT_Library;
short TT2PDF(int m, FXFT_Face face);
FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id);
+CIDSet CharsetFromOrdering(const CFX_ByteString& ordering);
class CPDF_CMapManager {
public:
diff --git a/core/fpdfapi/fpdf_font/fpdf_font.cpp b/core/fpdfapi/fpdf_font/fpdf_font.cpp
index 8dc91616f9..c0c6f520f4 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font.cpp
+++ b/core/fpdfapi/fpdf_font/fpdf_font.cpp
@@ -14,87 +14,12 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fxcrt/include/fx_ext.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_freetype.h"
#include "third_party/base/stl_util.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"},
- {"fi", "uniFB01"},
- {"fl", "uniFB02"},
- {"ffi", "uniFB03"},
- {"ffl", "uniFB04"}};
-
-int compareString(const void* key, const void* element) {
- return FXSYS_stricmp((const FX_CHAR*)key,
- ((GlyphNameMap*)element)->m_pStrAdobe);
-}
-
-const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) {
- GlyphNameMap* found = (GlyphNameMap*)FXSYS_bsearch(
- pStrAdobe, g_GlyphNameSubsts,
- sizeof(g_GlyphNameSubsts) / sizeof(GlyphNameMap), sizeof(GlyphNameMap),
- compareString);
- if (found)
- return found->m_pStrUnicode;
- return NULL;
-}
-#endif
-
-const uint8_t ChineseFontNames[][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}};
-
-FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
- 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;
- } else {
- return FALSE;
- }
- return TRUE;
-}
-
-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
-
FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) {
for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) ==
@@ -156,356 +81,15 @@ void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) {
m_StockMap.erase(pDoc);
}
-CPDF_Font::CPDF_Font()
- : m_pFontFile(nullptr),
- m_pFontDict(nullptr),
- m_pToUnicodeMap(nullptr),
- m_bToUnicodeLoaded(FALSE),
- m_Flags(0),
- m_StemV(0),
- m_Ascent(0),
- m_Descent(0),
- m_ItalicAngle(0) {}
-
-CPDF_Font::~CPDF_Font() {
- delete m_pToUnicodeMap;
- m_pToUnicodeMap = NULL;
-
- if (m_pFontFile) {
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
- const_cast<CPDF_Stream*>(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;
-}
-
-FX_BOOL CPDF_Font::IsUnicodeCompatible() const {
- return FALSE;
-}
-
-int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
- return size;
-}
-
-int CPDF_Font::GetCharSize(FX_DWORD charcode) const {
- return 1;
-}
-
-int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
- ASSERT(false);
- return 0;
-}
-
-int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
- return GlyphFromCharCode(charcode);
-}
-
-FX_BOOL CPDF_Font::IsVertWriting() const {
- FX_BOOL bVertWriting = FALSE;
- const CPDF_CIDFont* pCIDFont = AsCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- } else {
- bVertWriting = m_Font.IsVertical();
- }
- return bVertWriting;
-}
-
-int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
- *buf = (FX_CHAR)charcode;
- return 1;
-}
-
-void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD 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(FX_DWORD charcode) const {
- if (!m_bToUnicodeLoaded)
- ((CPDF_Font*)this)->LoadUnicodeMap();
-
- if (m_pToUnicodeMap)
- return m_pToUnicodeMap->Lookup(charcode);
- return CFX_WideString();
-}
-
-FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
- if (!m_bToUnicodeLoaded)
- ((CPDF_Font*)this)->LoadUnicodeMap();
-
- if (m_pToUnicodeMap)
- return m_pToUnicodeMap->ReverseLookup(unicode);
- return 0;
-}
-
-void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
- m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
- int ItalicAngle = 0;
- FX_BOOL bExistItalicAngle = FALSE;
- if (pFontDesc->KeyExist("ItalicAngle")) {
- ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
- bExistItalicAngle = TRUE;
- }
- if (ItalicAngle < 0) {
- m_Flags |= PDFFONT_ITALIC;
- m_ItalicAngle = ItalicAngle;
- }
- FX_BOOL bExistStemV = FALSE;
- if (pFontDesc->KeyExist("StemV")) {
- m_StemV = pFontDesc->GetIntegerBy("StemV");
- bExistStemV = TRUE;
- }
- FX_BOOL bExistAscent = FALSE;
- if (pFontDesc->KeyExist("Ascent")) {
- m_Ascent = pFontDesc->GetIntegerBy("Ascent");
- bExistAscent = TRUE;
- }
- FX_BOOL bExistDescent = FALSE;
- if (pFontDesc->KeyExist("Descent")) {
- m_Descent = pFontDesc->GetIntegerBy("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->GetArrayBy("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->GetStreamBy("FontFile");
- if (!pFontFile)
- pFontFile = pFontDesc->GetStreamBy("FontFile2");
- if (!pFontFile)
- pFontFile = pFontDesc->GetStreamBy("FontFile3");
- if (!pFontFile)
- return;
-
- m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
- if (!m_pFontFile)
- return;
- const uint8_t* pFontData = m_pFontFile->GetData();
- FX_DWORD dwFontSize = m_pFontFile->GetSize();
- if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
- const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
- m_pFontFile = nullptr;
- }
-}
short TT2PDF(int m, FXFT_Face face) {
int upm = FXFT_Get_Face_UnitsPerEM(face);
- if (upm == 0) {
+ if (upm == 0)
return (short)m;
- }
return (m * 1000 + upm / 2) / upm;
}
-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() {
- m_bToUnicodeLoaded = TRUE;
- CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
- if (!pStream) {
- return;
- }
- m_pToUnicodeMap = 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) {
- FX_DWORD 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;
- pDict->SetAtName("Type", "Font");
- pDict->SetAtName("Subtype", "Type1");
- pDict->SetAtName("BaseFont", fontname);
- pDict->SetAtName("Encoding", "WinAnsiEncoding");
- pFont = CPDF_Font::CreateFontF(NULL, pDict);
- pFontGlobals->Set(pDoc, font_id, pFont);
- return pFont;
-}
-
-CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
- CPDF_Dictionary* pFontDict) {
- CFX_ByteString type = pFontDict->GetStringBy("Subtype");
- CPDF_Font* pFont;
- if (type == "TrueType") {
- {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
- _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
- _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
- _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont");
- CFX_ByteString tag = basefont.Left(4);
- int i;
- int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
- for (i = 0; i < count; ++i) {
- if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
- break;
- }
- }
- if (i < count) {
- CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
- if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
- pFont = new CPDF_CIDFont;
- pFont->m_pFontDict = pFontDict;
- pFont->m_pDocument = pDoc;
- pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
- if (!pFont->Load()) {
- delete pFont;
- return NULL;
- }
- return pFont;
- }
- }
-#endif
- }
- pFont = new CPDF_TrueTypeFont;
- } else if (type == "Type3") {
- pFont = new CPDF_Type3Font;
- } else if (type == "Type0") {
- pFont = new CPDF_CIDFont;
- } else {
- pFont = new CPDF_Type1Font;
- }
- pFont->m_pFontDict = pFontDict;
- pFont->m_pDocument = pDoc;
- pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
- if (!pFont->Load()) {
- delete pFont;
- return NULL;
- }
- return pFont;
-}
CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) {
auto it = m_Map.find(charcode);
@@ -716,1098 +300,3 @@ void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) {
m_pBaseMap = NULL;
}
}
-
-FX_DWORD 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<FX_DWORD>(ch);
-}
-
-void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
- int& iBaseEncoding,
- CFX_ByteString*& pCharNames,
- FX_BOOL bEmbedded,
- FX_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(iBaseEncoding, bsEncoding);
- return;
- }
-
- CPDF_Dictionary* pDict = pEncoding->AsDictionary();
- if (!pDict)
- return;
-
- if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
- iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
- CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
- if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
- bsEncoding = "WinAnsiEncoding";
- }
- GetPredefinedEncoding(iBaseEncoding, bsEncoding);
- }
- if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
- iBaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
- if (!pDiffs) {
- return;
- }
- pCharNames = new CFX_ByteString[256];
- FX_DWORD cur_code = 0;
- for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
- CPDF_Object* pElement = pDiffs->GetElementValue(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();
- }
- }
-}
-
-FX_BOOL CPDF_Font::IsStandardFont() const {
- if (!IsType1Font())
- return FALSE;
- if (m_pFontFile)
- return FALSE;
- if (AsType1Font()->GetBase14Font() < 0)
- return FALSE;
- return TRUE;
-}
-
-CPDF_SimpleFont::CPDF_SimpleFont()
- : m_pCharNames(nullptr), 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);
-}
-
-CPDF_SimpleFont::~CPDF_SimpleFont() {
- delete[] m_pCharNames;
-}
-
-int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- if (charcode > 0xff) {
- return -1;
- }
- int index = m_GlyphIndex[(uint8_t)charcode];
- if (index == 0xffff) {
- return -1;
- }
- return index;
-}
-
-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;
- }
- m_CharBBox[charcode] = FX_SMALL_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));
-
- 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(FX_DWORD charcode, int level) {
- if (charcode > 0xff) {
- charcode = 0;
- }
- if (m_CharWidth[charcode] == 0xffff) {
- LoadCharMetrics(charcode);
- if (m_CharWidth[charcode] == 0xffff) {
- m_CharWidth[charcode] = 0;
- }
- }
- return (int16_t)m_CharWidth[charcode];
-}
-
-FX_RECT CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, int level) {
- if (charcode > 0xff)
- charcode = 0;
-
- if (m_CharBBox[charcode].left == FX_SMALL_RECT::kInvalid)
- LoadCharMetrics(charcode);
-
- return FX_RECT(m_CharBBox[charcode]);
-}
-
-const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
- const CFX_ByteString* pCharNames,
- int charcode) {
- ASSERT(charcode >= 0 && charcode < 256);
- if (charcode < 0 || charcode >= 256) {
- return NULL;
- }
- const FX_CHAR* name = NULL;
- if (pCharNames) {
- name = pCharNames[charcode];
- }
- if ((!name || name[0] == 0) && iBaseEncoding) {
- name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
- }
- return name && name[0] ? name : nullptr;
-}
-
-FX_BOOL CPDF_SimpleFont::LoadCommon() {
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
- int width_start = 0, width_end = -1;
- m_bUseFontWidth = TRUE;
- if (pWidthArray) {
- m_bUseFontWidth = FALSE;
- if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
- int MissingWidth = pFontDesc->GetIntegerBy("MissingWidth");
- for (int i = 0; i < 256; i++) {
- m_CharWidth[i] = MissingWidth;
- }
- }
- width_start = m_pFontDict->GetIntegerBy("FirstChar", 0);
- width_end = m_pFontDict->GetIntegerBy("LastChar", 0);
- if (width_start >= 0 && width_start <= 255) {
- if (width_end <= 0 ||
- width_end >= width_start + (int)pWidthArray->GetCount()) {
- width_end = width_start + pWidthArray->GetCount() - 1;
- }
- if (width_end > 255) {
- width_end = 255;
- }
- for (int 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->GetElementValue("Encoding");
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
- m_Font.IsTTFont());
- LoadGlyphMap();
- delete[] m_pCharNames;
- m_pCharNames = NULL;
- if (!m_Font.GetFace())
- return TRUE;
-
- if (m_Flags & PDFFONT_ALLCAP) {
- unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
- for (size_t range = 0; range < sizeof lowercases / 2; range++) {
- for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
- if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
- continue;
- }
- m_GlyphIndex[i] = m_GlyphIndex[i - 32];
- if (m_CharWidth[i - 32]) {
- m_CharWidth[i] = m_CharWidth[i - 32];
- m_CharBBox[i] = m_CharBBox[i - 32];
- }
- }
- }
- }
- 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;
- }
- }
- int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
- m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, weight, m_ItalicAngle,
- 0);
- if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
- }
-}
-
-FX_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(FX_DWORD 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;
-}
-
-FX_DWORD CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
- FX_DWORD ret = CPDF_Font::CharCodeFromUnicode(unicode);
- if (ret)
- return ret;
- return m_Encoding.CharCodeFromUnicode(unicode);
-}
-
-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;
-}
-
-FX_BOOL CPDF_Type1Font::Load() {
- m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
- if (m_Base14Font >= 0) {
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc && pFontDesc->KeyExist("Flags"))
- m_Flags = pFontDesc->GetIntegerBy("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(FX_DWORD 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_
- FX_BOOL bCoreText = TRUE;
- CQuartz2D& quartz2d =
- ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- if (!m_Font.GetPlatformFont()) {
- if (m_Font.GetPsName() == CFX_WideString::FromLocal("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_pCharNames, 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_pCharNames, 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_pCharNames, 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
- if (m_Flags & PDFFONT_SYMBOLIC) {
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, 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_pCharNames, 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
-}
-
-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() {
- 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("WinAnsiEncoding");
- }
- if (predefined == PDFFONT_ENCODING_MACROMAN) {
- return new CPDF_Name("MacRomanEncoding");
- }
- if (predefined == PDFFONT_ENCODING_MACEXPERT) {
- return new CPDF_Name("MacExpertEncoding");
- }
- return NULL;
- }
- 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;
- pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
- pDict->SetAt("Differences", pDiff);
- return pDict;
-}
-
-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;
-}
-
-FX_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_pCharNames) ||
- (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->GetIntegerBy("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;
- }
- FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
- FX_BOOL bMacRoman = FALSE, 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_pCharNames, 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) {
- 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 (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) {
- FX_DWORD 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)) {
- const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
- FX_BOOL bGotOne = FALSE;
- for (int charcode = 0; charcode < 256; charcode++) {
- 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 (m_GlyphIndex[charcode]) {
- bGotOne = TRUE;
- break;
- }
- }
- }
- if (bGotOne) {
- if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
- if (!name) {
- continue;
- }
- 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)) {
- FX_BOOL bGotOne = 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]) {
- bGotOne = TRUE;
- }
- }
- if (m_pFontFile || bGotOne) {
- return;
- }
- }
- if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
- FX_BOOL bGotOne = 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_pCharNames, 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]) {
- bGotOne = TRUE;
- }
- }
- if (bGotOne) {
- return;
- }
- }
- for (int charcode = 0; charcode < 256; charcode++) {
- m_GlyphIndex[charcode] = charcode;
- }
-}
-
-CPDF_Type3Font::CPDF_Type3Font()
- : m_pCharProcs(nullptr),
- m_pPageResources(nullptr),
- m_pFontResources(nullptr) {
- FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
-}
-
-CPDF_Type3Font::~CPDF_Type3Font() {
- for (auto it : m_CacheMap)
- delete it.second;
-}
-
-bool CPDF_Type3Font::IsType3Font() const {
- return true;
-}
-
-const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
- return this;
-}
-
-CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
- return this;
-}
-
-FX_BOOL CPDF_Type3Font::Load() {
- m_pFontResources = m_pFontDict->GetDictBy("Resources");
- CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("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->GetArrayBy("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->GetIntegerBy("FirstChar");
- CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
- if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
- FX_DWORD count = pWidthArray->GetCount();
- if (count > 256) {
- count = 256;
- }
- if (StartChar + count > 256) {
- count = 256 - StartChar;
- }
- for (FX_DWORD i = 0; i < count; i++) {
- m_CharWidthL[StartChar + i] =
- FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
- }
- }
- m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
- if (pEncoding) {
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
- if (m_pCharNames) {
- for (int i = 0; i < 256; i++) {
- m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
- 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(FX_DWORD charcode, int level) {
- if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
- return nullptr;
-
- auto it = m_CacheMap.find(charcode);
- if (it != m_CacheMap.end())
- return it->second;
-
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (!name)
- return nullptr;
-
- CPDF_Stream* pStream =
- ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
- if (!pStream)
- return nullptr;
-
- std::unique_ptr<CPDF_Type3Char> 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.
- pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
- level + 1);
- it = m_CacheMap.find(charcode);
- if (it != m_CacheMap.end())
- return it->second;
-
- 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));
- CPDF_Type3Char* pCachedChar = pNewChar.release();
- m_CacheMap[charcode] = pCachedChar;
- if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
- delete pCachedChar->m_pForm;
- pCachedChar->m_pForm = nullptr;
- }
- return pCachedChar;
-}
-
-int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
- if (charcode >= FX_ArraySize(m_CharWidthL))
- charcode = 0;
-
- if (m_CharWidthL[charcode])
- return m_CharWidthL[charcode];
-
- const CPDF_Type3Char* pChar = LoadChar(charcode, level);
- return pChar ? pChar->m_Width : 0;
-}
-
-FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) {
- const CPDF_Type3Char* pChar = LoadChar(charcode, level);
- return pChar ? pChar->m_BBox : FX_RECT();
-}
-
-CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
- : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
-
-CPDF_Type3Char::~CPDF_Type3Char() {
- delete m_pForm;
- delete m_pBitmap;
-}
diff --git a/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp b/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp
index c73043abfa..95452a7227 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp
+++ b/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp
@@ -13,7 +13,6 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fxcrt/include/fx_ext.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_freetype.h"
#include "core/include/fxge/fx_ge.h"
@@ -22,7 +21,6 @@ namespace {
const FX_CHAR* const g_CharsetNames[CIDSET_NUM_SETS] = {
nullptr, "GB1", "CNS1", "Japan1", "Korea1", "UCS"};
-const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
class CPDF_PredefinedCMap {
public:
@@ -192,14 +190,6 @@ CIDSet CIDSetFromSizeT(size_t index) {
return static_cast<CIDSet>(index);
}
-CIDSet CharsetFromOrdering(const CFX_ByteString& ordering) {
- for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) {
- if (ordering == CFX_ByteStringC(g_CharsetNames[charset]))
- return CIDSetFromSizeT(charset);
- }
- return CIDSET_UNKNOWN;
-}
-
CFX_ByteString CMap_GetString(const CFX_ByteStringC& word) {
return word.Mid(1, word.GetLength() - 2);
}
@@ -284,183 +274,6 @@ int GetCharSizeImpl(FX_DWORD charcode,
return 1;
}
-#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_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
- CIDSet charset,
- FX_WCHAR unicode) {
- if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
- return 0;
-
- CPDF_FontGlobals* pFontGlobals =
- CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
- const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
- if (!pCodes)
- return 0;
-
- int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
- for (int i = 0; i < nCodes; ++i) {
- if (pCodes[i] == unicode) {
- FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
- if (CharCode != 0) {
- return CharCode;
- }
- }
- }
- return 0;
-}
-
-FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
- CIDSet charset,
- FX_DWORD charcode) {
- if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
- return 0;
-
- uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
- if (cid == 0)
- return 0;
-
- CPDF_FontGlobals* pFontGlobals =
- CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
- const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
- if (!pCodes)
- return 0;
-
- if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count)
- return pCodes[cid];
- 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));
- }
-}
-
-const struct CIDTransform {
- uint16_t CID;
- uint8_t a, b, c, d, e, 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},
-};
-
-int CompareCIDTransform(const void* key, const void* element) {
- uint16_t CID = *static_cast<const uint16_t*>(key);
- return CID - static_cast<const struct CIDTransform*>(element)->CID;
-}
-
} // namespace
CPDF_CMapManager::CPDF_CMapManager() {
@@ -975,706 +788,10 @@ void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr,
FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount);
}
-CPDF_CIDFont::CPDF_CIDFont()
- : m_pCMap(nullptr),
- m_pAllocatedCMap(nullptr),
- m_pCID2UnicodeMap(nullptr),
- m_pCIDToGIDMap(nullptr),
- m_bCIDIsGID(FALSE),
- m_pAnsiWidths(nullptr),
- m_bAdobeCourierStd(FALSE),
- m_pTTGSUBTable(nullptr) {}
-
-CPDF_CIDFont::~CPDF_CIDFont() {
- if (m_pAnsiWidths) {
- FX_Free(m_pAnsiWidths);
- }
- delete m_pAllocatedCMap;
- delete m_pCIDToGIDMap;
- delete m_pTTGSUBTable;
-}
-
-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(FX_DWORD charcode) const {
- if (!m_pCMap) {
- return (uint16_t)charcode;
- }
- return m_pCMap->CIDFromCharCode(charcode);
-}
-
-FX_BOOL CPDF_CIDFont::IsVertWriting() const {
- return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
-}
-
-CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(FX_DWORD charcode) const {
- CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode);
- if (!str.IsEmpty())
- return str;
- FX_WCHAR ret = GetUnicodeFromCharCode(charcode);
- if (ret == 0)
- return CFX_WideString();
- return ret;
-}
-
-FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(FX_DWORD charcode) const {
- switch (m_pCMap->m_Coding) {
- case CIDCODING_UCS2:
- case CIDCODING_UTF16:
- return (FX_WCHAR)charcode;
- case CIDCODING_CID:
- if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
- return 0;
- }
- return m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)charcode);
- }
- if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
- !m_pCID2UnicodeMap->IsLoaded()) {
-#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,
- (const FX_CHAR*)&charcode, charsize,
- &unicode, 1);
- if (ret != 1) {
- return 0;
- }
- return unicode;
-#else
- if (m_pCMap->m_pEmbedMap) {
- return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap,
- m_pCMap->m_Charset, charcode);
- }
- return 0;
-#endif
- }
- return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
-}
-
-FX_DWORD CPDF_CIDFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
- FX_DWORD 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;
- }
- FX_DWORD CID = 0;
- while (CID < 65536) {
- FX_WCHAR this_unicode =
- m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID);
- if (this_unicode == unicode) {
- return CID;
- }
- CID++;
- }
- break;
- }
- }
-
- if (unicode < 0x80) {
- return static_cast<FX_DWORD>(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,
- (char*)buffer, 4, NULL, NULL);
- 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;
-}
-
-FX_BOOL CPDF_CIDFont::Load() {
- if (m_pFontDict->GetStringBy("Subtype") == "TrueType") {
- return LoadGB2312();
- }
- CPDF_Array* pFonts = m_pFontDict->GetArrayBy("DescendantFonts");
- if (!pFonts) {
- return FALSE;
- }
- if (pFonts->GetCount() != 1) {
- return FALSE;
- }
- CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
- if (!pCIDFontDict) {
- return FALSE;
- }
- m_BaseFont = pCIDFontDict->GetStringBy("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->GetDictBy("FontDescriptor");
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
- if (!pEncoding) {
- return FALSE;
- }
- CFX_ByteString subtype = pCIDFontDict->GetStringBy("Subtype");
- m_bType1 = (subtype == "CIDFontType0");
-
- if (pEncoding->IsName()) {
- CFX_ByteString cmap = pEncoding->GetString();
- m_pCMap =
- CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetPredefinedCMap(cmap, m_pFontFile && m_bType1);
- } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
- m_pAllocatedCMap = m_pCMap = new CPDF_CMap;
- CPDF_StreamAcc acc;
- acc.LoadAllData(pStream, FALSE);
- m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
- } else {
- return FALSE;
- }
- if (!m_pCMap) {
- return FALSE;
- }
- m_Charset = m_pCMap->m_Charset;
- if (m_Charset == CIDSET_UNKNOWN) {
- CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictBy("CIDSystemInfo");
- if (pCIDInfo) {
- m_Charset = CharsetFromOrdering(pCIDInfo->GetStringBy("Ordering"));
- }
- }
- if (m_Charset != CIDSET_UNKNOWN)
- m_pCID2UnicodeMap =
- CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetCID2UnicodeMap(
- m_Charset,
- !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID ||
- pCIDFontDict->KeyExist("W")));
- 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->GetIntegerBy("DW", 1000);
- CPDF_Array* pWidthArray = pCIDFontDict->GetArrayBy("W");
- if (pWidthArray) {
- LoadMetricsArray(pWidthArray, m_WidthList, 1);
- }
- if (!IsEmbedded()) {
- LoadSubstFont();
- }
- if (1) {
- if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
- CPDF_Object* pmap = pCIDFontDict->GetElementValue("CIDToGIDMap");
- if (pmap) {
- if (CPDF_Stream* pStream = pmap->AsStream()) {
- m_pCIDToGIDMap = new CPDF_StreamAcc;
- m_pCIDToGIDMap->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->GetArrayBy("W2");
- if (pWidthArray) {
- LoadMetricsArray(pWidthArray, m_VertMetrics, 3);
- }
- CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayBy("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(FX_DWORD charcode, int level) {
- if (charcode < 256 && m_CharBBox[charcode].right != FX_SMALL_RECT::kInvalid)
- return FX_RECT(m_CharBBox[charcode]);
-
- FX_RECT rect;
- FX_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);
- }
- if (rect.top > FXFT_Get_Face_Ascender(face)) {
- rect.top = FXFT_Get_Face_Ascender(face);
- }
- if (rect.bottom < FXFT_Get_Face_Descender(face)) {
- rect.bottom = 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.GetOutterRect();
- }
- }
- if (charcode < 256)
- m_CharBBox[charcode] = rect.ToSmallRect();
-
- return rect;
-}
-int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) {
- if (m_pAnsiWidths && charcode < 0x80) {
- return m_pAnsiWidths[charcode];
- }
- uint16_t cid = CIDFromCharCode(charcode);
- int size = m_WidthList.GetSize();
- FX_DWORD* list = m_WidthList.GetData();
- for (int i = 0; i < size; i += 3) {
- if (cid >= list[i] && cid <= list[i + 1]) {
- return (int)list[i + 2];
- }
- }
- return m_DefaultWidth;
-}
-short CPDF_CIDFont::GetVertWidth(uint16_t CID) const {
- FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
- if (vertsize == 0) {
- return m_DefaultW1;
- }
- const FX_DWORD* pTable = m_VertMetrics.GetData();
- for (FX_DWORD i = 0; i < vertsize; i++)
- if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
- return (short)(int)pTable[i * 5 + 2];
- }
- return m_DefaultW1;
-}
-void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const {
- FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
- if (vertsize) {
- const FX_DWORD* pTable = m_VertMetrics.GetData();
- for (FX_DWORD i = 0; i < vertsize; i++)
- if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
- vx = (short)(int)pTable[i * 5 + 3];
- vy = (short)(int)pTable[i * 5 + 4];
- return;
- }
- }
- FX_DWORD dwWidth = m_DefaultWidth;
- int size = m_WidthList.GetSize();
- const FX_DWORD* list = m_WidthList.GetData();
- for (int i = 0; i < size; i += 3) {
- if (CID >= list[i] && CID <= list[i + 1]) {
- dwWidth = (uint16_t)list[i + 2];
- break;
- }
- }
- vx = (short)dwWidth / 2;
- vy = (short)m_DefaultVY;
-}
-int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_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()) {
- if (m_pTTGSUBTable) {
- uint32_t vindex = 0;
- m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
- if (vindex) {
- index = vindex;
- if (pVertGlyph) {
- *pVertGlyph = TRUE;
- }
- }
- return index;
- }
- if (!m_Font.GetSubData()) {
- unsigned long length = 0;
- int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
- NULL, &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(), NULL);
- if (!error && m_Font.GetSubData()) {
- m_pTTGSUBTable = new CFX_CTTGSUBTable;
- m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
- uint32_t vindex = 0;
- m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
- if (vindex) {
- index = vindex;
- if (pVertGlyph) {
- *pVertGlyph = TRUE;
- }
- }
- }
- return index;
- }
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- return index;
-}
-int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- if (!m_pFontFile && !m_pCIDToGIDMap) {
- 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 && !(m_Flags & PDFFONT_SYMBOLIC)) {
- unicode = UnicodeFromCharCode(charcode).GetAt(0);
- }
- }
- FXFT_Face face = m_Font.GetFace();
- if (unicode == 0) {
- if (!m_bAdobeCourierStd) {
- return charcode == 0 ? -1 : (int)charcode;
- }
- charcode += 31;
- int index = 0, iBaseEncoding;
- FX_BOOL bMSUnicode = FT_UseTTCharmap(face, 3, 1);
- FX_BOOL bMacRoman = FALSE;
- if (!bMSUnicode) {
- bMacRoman = FT_UseTTCharmap(face, 1, 0);
- }
- iBaseEncoding = PDFFONT_ENCODING_STANDARD;
- if (bMSUnicode) {
- iBaseEncoding = PDFFONT_ENCODING_WINANSI;
- } else if (bMacRoman) {
- iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
- }
- const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode);
- if (!name) {
- return charcode == 0 ? -1 : (int)charcode;
- }
- uint16_t unicode = PDF_UnicodeFromAdobeName(name);
- if (unicode) {
- if (bMSUnicode) {
- index = FXFT_Get_Char_Index(face, unicode);
- } else if (bMacRoman) {
- FX_DWORD maccode =
- FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode);
- index = !maccode ? FXFT_Get_Name_Index(face, (char*)name)
- : FXFT_Get_Char_Index(face, maccode);
- } else {
- return FXFT_Get_Char_Index(face, unicode);
- }
- } else {
- return charcode == 0 ? -1 : (int)charcode;
- }
- if (index == 0 || index == 0xffff) {
- return charcode == 0 ? -1 : (int)charcode;
- }
- 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 != 0) {
- int i;
- for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
- FX_DWORD ret = FT_CharCodeFromUnicode(
- FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
- (FX_WCHAR)charcode);
- if (ret == 0) {
- continue;
- }
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
- unicode = (FX_WCHAR)ret;
- break;
- }
- if (i == FXFT_Get_Face_CharmapCount(face) && i) {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
- unicode = (FX_WCHAR)charcode;
- }
- }
- if (FXFT_Get_Face_Charmap(face)) {
- int index = GetGlyphIndex(unicode, pVertGlyph);
- if (index == 0)
- return -1;
- return index;
- }
- return unicode;
- }
- if (!m_Font.GetFace())
- return -1;
-
- uint16_t cid = CIDFromCharCode(charcode);
- if (m_bType1) {
- if (!m_pCIDToGIDMap) {
- return cid;
- }
- } else {
- if (!m_pCIDToGIDMap) {
- 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);
- }
- }
- FX_DWORD byte_pos = cid * 2;
- if (byte_pos + 2 > m_pCIDToGIDMap->GetSize())
- return -1;
-
- const uint8_t* pdata = m_pCIDToGIDMap->GetData() + byte_pos;
- return pdata[0] * 256 + pdata[1];
-}
-FX_DWORD CPDF_CIDFont::GetNextChar(const FX_CHAR* pString,
- int nStrLen,
- int& offset) const {
- return m_pCMap->GetNextChar(pString, nStrLen, offset);
-}
-int CPDF_CIDFont::GetCharSize(FX_DWORD 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, FX_DWORD charcode) const {
- return m_pCMap->AppendChar(str, charcode);
-}
-FX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const {
- if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
- !m_pCID2UnicodeMap->IsLoaded()) {
- return m_pCMap->m_Coding != CIDCODING_UNKNOWN;
- }
- return TRUE;
-}
-FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const {
- return TRUE;
-}
-void CPDF_CIDFont::LoadSubstFont() {
- m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle,
- g_CharsetCPs[m_Charset], IsVertWriting());
-}
-void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
- CFX_DWordArray& result,
- int nElements) {
- int width_status = 0;
- int iCurElement = 0;
- int first_code = 0;
- int last_code = 0;
- FX_DWORD count = pArray->GetCount();
- for (FX_DWORD i = 0; i < count; i++) {
- CPDF_Object* pObj = pArray->GetElementValue(i);
- if (!pObj)
- continue;
-
- if (CPDF_Array* pArray = pObj->AsArray()) {
- if (width_status != 1)
- return;
-
- FX_DWORD count = pArray->GetCount();
- for (FX_DWORD j = 0; j < count; j += nElements) {
- result.Add(first_code);
- result.Add(first_code);
- for (int k = 0; k < nElements; k++) {
- result.Add(pArray->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) {
- if (ch < 128) {
- return ch * 1.0f / 127;
- }
- return (-255 + ch) * 1.0f / 127;
-}
-
-FX_BOOL CPDF_CIDFont::LoadGB2312() {
- m_BaseFont = m_pFontDict->GetStringBy("BaseFont");
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- m_Charset = CIDSET_GB1;
- m_bType1 = FALSE;
- m_pCMap = CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE);
- m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE);
- if (!IsEmbedded()) {
- LoadSubstFont();
- }
- CheckFontMetrics();
- m_DefaultWidth = 1000;
- m_pAnsiWidths = FX_Alloc(uint16_t, 128);
- for (int i = 32; i < 127; i++) {
- m_pAnsiWidths[i] = 500;
+CIDSet CharsetFromOrdering(const CFX_ByteString& ordering) {
+ for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) {
+ if (ordering == CFX_ByteStringC(g_CharsetNames[charset]))
+ return CIDSetFromSizeT(charset);
}
- return TRUE;
-}
-
-const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
- if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
- return nullptr;
-
- const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch(
- &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs),
- sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform);
- return found ? &found->a : nullptr;
+ return CIDSET_UNKNOWN;
}
diff --git a/core/fpdfapi/fpdf_font/include/cpdf_font.h b/core/fpdfapi/fpdf_font/include/cpdf_font.h
new file mode 100644
index 0000000000..1931c245de
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/include/cpdf_font.h
@@ -0,0 +1,128 @@
+// 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_INCLUDE_CPDF_FONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONT_H_
+
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+#include "core/include/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 CPDF_Font* CreateFontF(CPDF_Document* pDoc,
+ CPDF_Dictionary* pFontDict);
+ static CPDF_Font* GetStockFont(CPDF_Document* pDoc,
+ const CFX_ByteStringC& fontname);
+ static const FX_DWORD kInvalidCharCode = static_cast<FX_DWORD>(-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 FX_BOOL IsVertWriting() const;
+ virtual FX_BOOL IsUnicodeCompatible() const;
+ virtual FX_DWORD 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, FX_DWORD charcode) const;
+ virtual int GetCharSize(FX_DWORD charcode) const;
+ virtual int GlyphFromCharCode(FX_DWORD charcode,
+ FX_BOOL* pVertGlyph = nullptr);
+ virtual int GlyphFromCharCodeExt(FX_DWORD charcode);
+ virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const;
+ virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const;
+
+ const CFX_ByteString& GetBaseFont() const { return m_BaseFont; }
+ const CFX_SubstFont* GetSubstFont() const { return m_Font.GetSubstFont(); }
+ FX_DWORD GetFlags() const { return m_Flags; }
+ FX_BOOL IsEmbedded() const { return IsType3Font() || m_pFontFile != nullptr; }
+ CPDF_StreamAcc* GetFontFile() const { return m_pFontFile; }
+ CPDF_Dictionary* GetFontDict() const { return m_pFontDict; }
+ FX_BOOL IsStandardFont() const;
+ FXFT_Face GetFace() const { return m_Font.GetFace(); }
+ void AppendChar(CFX_ByteString& str, FX_DWORD 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);
+
+ virtual int GetCharWidthF(FX_DWORD charcode, int level = 0) = 0;
+ virtual FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) = 0;
+
+ CPDF_Document* m_pDocument;
+ CFX_Font m_Font;
+
+ protected:
+ CPDF_Font();
+
+ virtual FX_BOOL Load() = 0;
+
+ FX_BOOL Initialize();
+ void LoadUnicodeMap();
+ void LoadPDFEncoding(CPDF_Object* pEncoding,
+ int& iBaseEncoding,
+ CFX_ByteString*& pCharNames,
+ FX_BOOL bEmbedded,
+ FX_BOOL bTrueType);
+ void LoadFontDescriptor(CPDF_Dictionary* pDict);
+ void CheckFontMetrics();
+
+ const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
+ const CFX_ByteString* pCharNames,
+ int charcode);
+
+ CFX_ByteString m_BaseFont;
+ CPDF_StreamAcc* m_pFontFile;
+ CPDF_Dictionary* m_pFontDict;
+ CPDF_ToUnicodeMap* m_pToUnicodeMap;
+ FX_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_INCLUDE_CPDF_FONT_H_
diff --git a/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h b/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h
new file mode 100644
index 0000000000..a64687cd0e
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.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_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_
+#define CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_
+
+#include "core/fxcrt/include/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
+
+FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
+FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD 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();
+
+ public:
+ FX_WCHAR m_Unicodes[256];
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_
diff --git a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp
index 96ccc77f81..5d02381d2e 100644
--- a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp
@@ -8,6 +8,7 @@
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
namespace {
diff --git a/core/fpdfapi/fpdf_page/cpdf_color.cpp b/core/fpdfapi/fpdf_page/cpdf_color.cpp
new file mode 100644
index 0000000000..d174660d4a
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_color.cpp
@@ -0,0 +1,180 @@
+// 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_page/include/cpdf_color.h"
+
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fxcrt/include/fx_system.h"
+
+CPDF_Color::CPDF_Color(int family) {
+ m_pCS = CPDF_ColorSpace::GetStockCS(family);
+ int nComps = 3;
+ if (family == PDFCS_DEVICEGRAY)
+ nComps = 1;
+ else if (family == PDFCS_DEVICECMYK)
+ nComps = 4;
+
+ m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
+ for (int i = 0; i < nComps; i++)
+ m_pBuffer[i] = 0;
+}
+
+CPDF_Color::~CPDF_Color() {
+ ReleaseBuffer();
+ ReleaseColorSpace();
+}
+
+void CPDF_Color::ReleaseBuffer() {
+ if (!m_pBuffer)
+ return;
+
+ if (m_pCS->GetFamily() == PDFCS_PATTERN) {
+ PatternValue* pvalue = (PatternValue*)m_pBuffer;
+ CPDF_Pattern* pPattern =
+ pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : nullptr;
+ if (pPattern && pPattern->m_pDocument) {
+ CPDF_DocPageData* pPageData = pPattern->m_pDocument->GetPageData();
+ if (pPageData)
+ pPageData->ReleasePattern(pPattern->m_pPatternObj);
+ }
+ }
+ FX_Free(m_pBuffer);
+ m_pBuffer = nullptr;
+}
+
+void CPDF_Color::ReleaseColorSpace() {
+ if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
+ m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
+ m_pCS = nullptr;
+ }
+}
+
+void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) {
+ if (m_pCS == pCS) {
+ if (!m_pBuffer)
+ m_pBuffer = pCS->CreateBuf();
+
+ ReleaseColorSpace();
+ m_pCS = pCS;
+ return;
+ }
+ ReleaseBuffer();
+ ReleaseColorSpace();
+
+ m_pCS = pCS;
+ if (m_pCS) {
+ m_pBuffer = pCS->CreateBuf();
+ pCS->GetDefaultColor(m_pBuffer);
+ }
+}
+
+void CPDF_Color::SetValue(FX_FLOAT* comps) {
+ if (!m_pBuffer)
+ return;
+ if (m_pCS->GetFamily() != PDFCS_PATTERN)
+ FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
+}
+
+void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) {
+ if (ncomps > MAX_PATTERN_COLORCOMPS)
+ return;
+
+ if (!m_pCS || m_pCS->GetFamily() != PDFCS_PATTERN) {
+ FX_Free(m_pBuffer);
+ m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
+ m_pBuffer = m_pCS->CreateBuf();
+ }
+
+ CPDF_DocPageData* pDocPageData = nullptr;
+ PatternValue* pvalue = (PatternValue*)m_pBuffer;
+ if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
+ pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
+ if (pDocPageData)
+ pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
+ }
+ pvalue->m_nComps = ncomps;
+ pvalue->m_pPattern = pPattern;
+ if (ncomps)
+ FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
+
+ pvalue->m_pCountedPattern = nullptr;
+ if (pPattern && pPattern->m_pDocument) {
+ if (!pDocPageData)
+ pDocPageData = pPattern->m_pDocument->GetPageData();
+
+ pvalue->m_pCountedPattern =
+ pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);
+ }
+}
+
+void CPDF_Color::Copy(const CPDF_Color* pSrc) {
+ ReleaseBuffer();
+ ReleaseColorSpace();
+
+ m_pCS = pSrc->m_pCS;
+ if (m_pCS && m_pCS->m_pDocument) {
+ CPDF_Array* pArray = m_pCS->GetArray();
+ if (pArray)
+ m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
+ }
+ if (!m_pCS)
+ return;
+
+ m_pBuffer = m_pCS->CreateBuf();
+ FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
+ if (m_pCS->GetFamily() == PDFCS_PATTERN) {
+ PatternValue* pvalue = (PatternValue*)m_pBuffer;
+ if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
+ pvalue->m_pPattern =
+ pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(
+ pvalue->m_pPattern->m_pPatternObj, FALSE,
+ &pvalue->m_pPattern->m_ParentMatrix);
+ }
+ }
+}
+
+FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const {
+ if (!m_pCS || !m_pBuffer)
+ return FALSE;
+
+ FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
+ if (!m_pCS->GetRGB(m_pBuffer, r, g, b))
+ return FALSE;
+
+ R = (int32_t)(r * 255 + 0.5f);
+ G = (int32_t)(g * 255 + 0.5f);
+ B = (int32_t)(b * 255 + 0.5f);
+ return TRUE;
+}
+
+CPDF_Pattern* CPDF_Color::GetPattern() const {
+ if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN)
+ return nullptr;
+
+ PatternValue* pvalue = (PatternValue*)m_pBuffer;
+ return pvalue->m_pPattern;
+}
+
+CPDF_ColorSpace* CPDF_Color::GetPatternCS() const {
+ if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN)
+ return nullptr;
+ return m_pCS->GetBaseCS();
+}
+
+FX_FLOAT* CPDF_Color::GetPatternColor() const {
+ if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN)
+ return nullptr;
+
+ PatternValue* pvalue = (PatternValue*)m_pBuffer;
+ return pvalue->m_nComps ? pvalue->m_Comps : nullptr;
+}
+
+FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const {
+ return m_pCS && m_pCS == other.m_pCS &&
+ FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp b/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp
new file mode 100644
index 0000000000..b1b464471d
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp
@@ -0,0 +1,1253 @@
+// 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_page/include/cpdf_colorspace.h"
+
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
+#include "core/fpdfapi/include/cpdf_modulemgr.h"
+#include "core/include/fxcodec/fx_codec.h"
+
+namespace {
+
+const uint8_t g_sRGBSamples1[] = {
+ 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31,
+ 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58,
+ 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68,
+ 68, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76,
+ 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83,
+ 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90,
+ 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96,
+ 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 101, 101, 101,
+ 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 106, 106, 106, 107,
+ 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 110, 111, 111, 111,
+ 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116,
+ 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120,
+};
+
+const uint8_t g_sRGBSamples2[] = {
+ 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149,
+ 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162,
+ 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173,
+ 174, 175, 175, 176, 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184,
+ 185, 185, 186, 187, 187, 188, 189, 189, 190, 190, 191, 192, 192, 193, 194,
+ 194, 195, 196, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, 203,
+ 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 209, 210, 210, 211, 212,
+ 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 218, 218, 219, 219, 220,
+ 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228,
+ 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235,
+ 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242,
+ 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 249, 249,
+ 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
+};
+
+class CPDF_CalGray : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_CalGray(CPDF_Document* pDoc);
+
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ FX_BOOL SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const override;
+
+ void TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask = FALSE) const override;
+
+ private:
+ FX_FLOAT m_WhitePoint[3];
+ FX_FLOAT m_BlackPoint[3];
+ FX_FLOAT m_Gamma;
+};
+
+class CPDF_CalRGB : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_CalRGB(CPDF_Document* pDoc);
+
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ FX_BOOL SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const override;
+
+ void TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask = FALSE) const override;
+
+ FX_FLOAT m_WhitePoint[3];
+ FX_FLOAT m_BlackPoint[3];
+ FX_FLOAT m_Gamma[3];
+ FX_FLOAT m_Matrix[9];
+ FX_BOOL m_bGamma;
+ FX_BOOL m_bMatrix;
+};
+
+class CPDF_LabCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_LabCS(CPDF_Document* pDoc);
+
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+
+ void GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const override;
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ FX_BOOL SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const override;
+
+ void TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask = FALSE) const override;
+
+ FX_FLOAT m_WhitePoint[3];
+ FX_FLOAT m_BlackPoint[3];
+ FX_FLOAT m_Ranges[4];
+};
+
+class CPDF_ICCBasedCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
+ ~CPDF_ICCBasedCS() override;
+
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ FX_BOOL SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const override;
+
+ FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT& c,
+ FX_FLOAT& m,
+ FX_FLOAT& y,
+ FX_FLOAT& k) const override;
+
+ void EnableStdConversion(FX_BOOL bEnabled) override;
+ void TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask = FALSE) const override;
+
+ CPDF_ColorSpace* m_pAlterCS;
+ CPDF_IccProfile* m_pProfile;
+ uint8_t* m_pCache;
+ FX_FLOAT* m_pRanges;
+ FX_BOOL m_bOwn;
+};
+
+class CPDF_IndexedCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_IndexedCS(CPDF_Document* pDoc);
+ ~CPDF_IndexedCS() override;
+
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ CPDF_ColorSpace* GetBaseCS() const override;
+
+ void EnableStdConversion(FX_BOOL bEnabled) override;
+
+ CPDF_ColorSpace* m_pBaseCS;
+ CPDF_CountedColorSpace* m_pCountedBaseCS;
+ int m_nBaseComponents;
+ int m_MaxIndex;
+ CFX_ByteString m_Table;
+ FX_FLOAT* m_pCompMinMax;
+};
+
+class CPDF_SeparationCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_SeparationCS(CPDF_Document* pDoc);
+ ~CPDF_SeparationCS() override;
+
+ // CPDF_ColorSpace:
+ void GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const override;
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ void EnableStdConversion(FX_BOOL bEnabled) override;
+
+ CPDF_ColorSpace* m_pAltCS;
+ CPDF_Function* m_pFunc;
+ enum { None, All, Colorant } m_Type;
+};
+
+class CPDF_DeviceNCS : public CPDF_ColorSpace {
+ public:
+ explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
+ ~CPDF_DeviceNCS() override;
+
+ // CPDF_ColorSpace:
+ void GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const override;
+ FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
+ FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const override;
+ void EnableStdConversion(FX_BOOL bEnabled) override;
+
+ CPDF_ColorSpace* m_pAltCS;
+ CPDF_Function* m_pFunc;
+};
+
+FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) {
+ if (colorComponent > 1)
+ colorComponent = 1;
+ if (colorComponent < 0)
+ colorComponent = 0;
+
+ int scale = (int)(colorComponent * 1023);
+ if (scale < 0)
+ scale = 0;
+ if (scale < 192)
+ colorComponent = (g_sRGBSamples1[scale] / 255.0f);
+ else
+ colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
+ return colorComponent;
+}
+
+void XYZ_to_sRGB(FX_FLOAT X,
+ FX_FLOAT Y,
+ FX_FLOAT Z,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) {
+ FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
+ FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
+ FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
+
+ R = RGB_Conversion(R1);
+ G = RGB_Conversion(G1);
+ B = RGB_Conversion(B1);
+}
+
+void XYZ_to_sRGB_WhitePoint(FX_FLOAT X,
+ FX_FLOAT Y,
+ FX_FLOAT Z,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B,
+ FX_FLOAT Xw,
+ FX_FLOAT Yw,
+ FX_FLOAT Zw) {
+ // The following RGB_xyz is based on
+ // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06}
+
+ FX_FLOAT Rx = 0.64f, Ry = 0.33f;
+ FX_FLOAT Gx = 0.30f, Gy = 0.60f;
+ FX_FLOAT Bx = 0.15f, By = 0.06f;
+ CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy,
+ 1 - Bx - By);
+ CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
+ CFX_Vector_3by1 XYZ(X, Y, Z);
+
+ CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
+ CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0,
+ 0, RGB_Sum_XYZ.c);
+ CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG);
+ CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ);
+
+ R = RGB_Conversion(RGB.a);
+ G = RGB_Conversion(RGB.b);
+ B = RGB_Conversion(RGB.c);
+}
+
+} // namespace
+
+CPDF_ColorSpace* CPDF_ColorSpace::ColorspaceFromName(
+ const CFX_ByteString& name) {
+ if (name == "DeviceRGB" || name == "RGB") {
+ return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
+ }
+ if (name == "DeviceGray" || name == "G") {
+ return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
+ }
+ if (name == "DeviceCMYK" || name == "CMYK") {
+ return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
+ }
+ if (name == "Pattern") {
+ return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
+ }
+ return NULL;
+}
+
+CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
+ return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
+}
+
+CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
+ if (!pObj)
+ return nullptr;
+ if (pObj->IsName())
+ return ColorspaceFromName(pObj->GetString());
+
+ if (CPDF_Stream* pStream = pObj->AsStream()) {
+ CPDF_Dictionary* pDict = pStream->GetDict();
+ if (!pDict)
+ return nullptr;
+
+ for (const auto& it : *pDict) {
+ CPDF_ColorSpace* pRet = nullptr;
+ CPDF_Object* pValue = it.second;
+ if (ToName(pValue))
+ pRet = ColorspaceFromName(pValue->GetString());
+ if (pRet)
+ return pRet;
+ }
+ return nullptr;
+ }
+
+ CPDF_Array* pArray = pObj->AsArray();
+ if (!pArray || pArray->GetCount() == 0)
+ return nullptr;
+
+ CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
+ if (!pFamilyObj)
+ return nullptr;
+
+ CFX_ByteString familyname = pFamilyObj->GetString();
+ if (pArray->GetCount() == 1)
+ return ColorspaceFromName(familyname);
+
+ CPDF_ColorSpace* pCS = NULL;
+ FX_DWORD id = familyname.GetID();
+ if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
+ pCS = new CPDF_CalGray(pDoc);
+ } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
+ pCS = new CPDF_CalRGB(pDoc);
+ } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
+ pCS = new CPDF_LabCS(pDoc);
+ } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
+ pCS = new CPDF_ICCBasedCS(pDoc);
+ } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
+ id == FXBSTR_ID('I', 0, 0, 0)) {
+ pCS = new CPDF_IndexedCS(pDoc);
+ } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
+ pCS = new CPDF_SeparationCS(pDoc);
+ } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
+ pCS = new CPDF_DeviceNCS(pDoc);
+ } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
+ pCS = new CPDF_PatternCS(pDoc);
+ } else {
+ return NULL;
+ }
+ pCS->m_pArray = pArray;
+ if (!pCS->v_Load(pDoc, pArray)) {
+ pCS->ReleaseCS();
+ return NULL;
+ }
+ return pCS;
+}
+
+void CPDF_ColorSpace::ReleaseCS() {
+ if (this == GetStockCS(PDFCS_DEVICERGB)) {
+ return;
+ }
+ if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
+ return;
+ }
+ if (this == GetStockCS(PDFCS_DEVICECMYK)) {
+ return;
+ }
+ if (this == GetStockCS(PDFCS_PATTERN)) {
+ return;
+ }
+ delete this;
+}
+
+int CPDF_ColorSpace::GetBufSize() const {
+ if (m_Family == PDFCS_PATTERN) {
+ return sizeof(PatternValue);
+ }
+ return m_nComponents * sizeof(FX_FLOAT);
+}
+
+FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
+ int size = GetBufSize();
+ uint8_t* pBuf = FX_Alloc(uint8_t, size);
+ return (FX_FLOAT*)pBuf;
+}
+
+FX_BOOL CPDF_ColorSpace::sRGB() const {
+ if (m_Family == PDFCS_DEVICERGB) {
+ return TRUE;
+ }
+ if (m_Family != PDFCS_ICCBASED) {
+ return FALSE;
+ }
+ CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
+ return pCS->m_pProfile->m_bsRGB;
+}
+
+FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT& c,
+ FX_FLOAT& m,
+ FX_FLOAT& y,
+ FX_FLOAT& k) const {
+ if (v_GetCMYK(pBuf, c, m, y, k)) {
+ return TRUE;
+ }
+ FX_FLOAT R, G, B;
+ if (!GetRGB(pBuf, R, G, B)) {
+ return FALSE;
+ }
+ sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
+ return TRUE;
+}
+
+FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT c,
+ FX_FLOAT m,
+ FX_FLOAT y,
+ FX_FLOAT k) const {
+ if (v_SetCMYK(pBuf, c, m, y, k)) {
+ return TRUE;
+ }
+ FX_FLOAT R, G, B;
+ AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
+ return SetRGB(pBuf, R, G, B);
+}
+
+void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
+ if (!buf || m_Family == PDFCS_PATTERN) {
+ return;
+ }
+ FX_FLOAT min, max;
+ for (int i = 0; i < m_nComponents; i++) {
+ GetDefaultValue(i, buf[i], min, max);
+ }
+}
+
+int CPDF_ColorSpace::GetMaxIndex() const {
+ if (m_Family != PDFCS_INDEXED) {
+ return 0;
+ }
+ CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
+ return pCS->m_MaxIndex;
+}
+
+void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf,
+ const uint8_t* src_buf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask) const {
+ CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
+ FX_FLOAT* src = srcbuf;
+ FX_FLOAT R, G, B;
+ for (int i = 0; i < pixels; i++) {
+ for (int j = 0; j < m_nComponents; j++)
+ if (m_Family == PDFCS_INDEXED) {
+ src[j] = (FX_FLOAT)(*src_buf++);
+ } else {
+ src[j] = (FX_FLOAT)(*src_buf++) / 255;
+ }
+ GetRGB(src, R, G, B);
+ *dest_buf++ = (int32_t)(B * 255);
+ *dest_buf++ = (int32_t)(G * 255);
+ *dest_buf++ = (int32_t)(R * 255);
+ }
+}
+
+void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
+ if (bEnabled)
+ m_dwStdConversion++;
+ else if (m_dwStdConversion)
+ m_dwStdConversion--;
+}
+
+CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {}
+
+FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Dictionary* pDict = pArray->GetDictAt(1);
+ if (!pDict)
+ return FALSE;
+
+ CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
+ int i;
+ for (i = 0; i < 3; i++)
+ m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
+
+ pParam = pDict->GetArrayBy("BlackPoint");
+ for (i = 0; i < 3; i++)
+ m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
+
+ m_Gamma = pDict->GetNumberBy("Gamma");
+ if (m_Gamma == 0)
+ m_Gamma = 1.0f;
+ return TRUE;
+}
+
+FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ R = G = B = *pBuf;
+ return TRUE;
+}
+
+FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const {
+ if (R == G && R == B) {
+ *pBuf = R;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask) const {
+ for (int i = 0; i < pixels; i++) {
+ *pDestBuf++ = pSrcBuf[i];
+ *pDestBuf++ = pSrcBuf[i];
+ *pDestBuf++ = pSrcBuf[i];
+ }
+}
+
+CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {}
+
+FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Dictionary* pDict = pArray->GetDictAt(1);
+ if (!pDict)
+ return FALSE;
+
+ CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
+ int i;
+ for (i = 0; i < 3; i++)
+ m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
+
+ pParam = pDict->GetArrayBy("BlackPoint");
+ for (i = 0; i < 3; i++)
+ m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
+
+ pParam = pDict->GetArrayBy("Gamma");
+ if (pParam) {
+ m_bGamma = TRUE;
+ for (i = 0; i < 3; i++)
+ m_Gamma[i] = pParam->GetNumberAt(i);
+ } else {
+ m_bGamma = FALSE;
+ }
+
+ pParam = pDict->GetArrayBy("Matrix");
+ if (pParam) {
+ m_bMatrix = TRUE;
+ for (i = 0; i < 9; i++)
+ m_Matrix[i] = pParam->GetNumberAt(i);
+ } else {
+ m_bMatrix = FALSE;
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ FX_FLOAT A_ = pBuf[0];
+ FX_FLOAT B_ = pBuf[1];
+ FX_FLOAT C_ = pBuf[2];
+ if (m_bGamma) {
+ A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
+ B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
+ C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
+ }
+
+ FX_FLOAT X;
+ FX_FLOAT Y;
+ FX_FLOAT Z;
+ if (m_bMatrix) {
+ X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
+ Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
+ Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
+ } else {
+ X = A_;
+ Y = B_;
+ Z = C_;
+ }
+ XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1],
+ m_WhitePoint[2]);
+ return TRUE;
+}
+
+FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const {
+ pBuf[0] = R;
+ pBuf[1] = G;
+ pBuf[2] = B;
+ return TRUE;
+}
+
+void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask) const {
+ if (bTransMask) {
+ FX_FLOAT Cal[3];
+ FX_FLOAT R;
+ FX_FLOAT G;
+ FX_FLOAT B;
+ for (int i = 0; i < pixels; i++) {
+ Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
+ Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
+ Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255;
+ GetRGB(Cal, R, G, B);
+ pDestBuf[0] = FXSYS_round(B * 255);
+ pDestBuf[1] = FXSYS_round(G * 255);
+ pDestBuf[2] = FXSYS_round(R * 255);
+ pSrcBuf += 3;
+ pDestBuf += 3;
+ }
+ }
+ ReverseRGB(pDestBuf, pSrcBuf, pixels);
+}
+
+CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {}
+
+void CPDF_LabCS::GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const {
+ assert(iComponent < 3);
+ value = 0;
+ if (iComponent == 0) {
+ min = 0;
+ max = 100 * 1.0f;
+ } else {
+ min = m_Ranges[iComponent * 2 - 2];
+ max = m_Ranges[iComponent * 2 - 1];
+ if (value < min)
+ value = min;
+ else if (value > max)
+ value = max;
+ }
+}
+
+FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Dictionary* pDict = pArray->GetDictAt(1);
+ if (!pDict)
+ return FALSE;
+
+ CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
+ int i;
+ for (i = 0; i < 3; i++)
+ m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
+
+ pParam = pDict->GetArrayBy("BlackPoint");
+ for (i = 0; i < 3; i++)
+ m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
+
+ pParam = pDict->GetArrayBy("Range");
+ const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f,
+ 100 * 1.0f};
+ for (i = 0; i < 4; i++)
+ m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i];
+ return TRUE;
+}
+
+FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ FX_FLOAT Lstar = pBuf[0];
+ FX_FLOAT astar = pBuf[1];
+ FX_FLOAT bstar = pBuf[2];
+ FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
+ FX_FLOAT L = M + astar / 500.0f;
+ FX_FLOAT N = M - bstar / 200.0f;
+ FX_FLOAT X, Y, Z;
+ if (L < 0.2069f)
+ X = 0.957f * 0.12842f * (L - 0.1379f);
+ else
+ X = 0.957f * L * L * L;
+
+ if (M < 0.2069f)
+ Y = 0.12842f * (M - 0.1379f);
+ else
+ Y = M * M * M;
+
+ if (N < 0.2069f)
+ Z = 1.0889f * 0.12842f * (N - 0.1379f);
+ else
+ Z = 1.0889f * N * N * N;
+
+ XYZ_to_sRGB(X, Y, Z, R, G, B);
+ return TRUE;
+}
+
+FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const {
+ return FALSE;
+}
+
+void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask) const {
+ for (int i = 0; i < pixels; i++) {
+ FX_FLOAT lab[3];
+ FX_FLOAT R, G, B;
+ lab[0] = (pSrcBuf[0] * 100 / 255.0f);
+ lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
+ lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128);
+ GetRGB(lab, R, G, B);
+ pDestBuf[0] = (int32_t)(B * 255);
+ pDestBuf[1] = (int32_t)(G * 255);
+ pDestBuf[2] = (int32_t)(R * 255);
+ pDestBuf += 3;
+ pSrcBuf += 3;
+ }
+}
+
+CPDF_ICCBasedCS::CPDF_ICCBasedCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0),
+ m_pAlterCS(nullptr),
+ m_pProfile(nullptr),
+ m_pCache(nullptr),
+ m_pRanges(nullptr),
+ m_bOwn(FALSE) {}
+
+CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
+ FX_Free(m_pCache);
+ FX_Free(m_pRanges);
+ if (m_pAlterCS && m_bOwn)
+ m_pAlterCS->ReleaseCS();
+ if (m_pProfile && m_pDocument)
+ m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
+}
+
+FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Stream* pStream = pArray->GetStreamAt(1);
+ if (!pStream)
+ return FALSE;
+
+ m_pProfile = pDoc->LoadIccProfile(pStream);
+ if (!m_pProfile)
+ return FALSE;
+
+ m_nComponents =
+ m_pProfile
+ ->GetComponents(); // Try using the nComponents from ICC profile
+ CPDF_Dictionary* pDict = pStream->GetDict();
+ if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB
+ CPDF_Object* pAlterCSObj =
+ pDict ? pDict->GetElementValue("Alternate") : nullptr;
+ if (pAlterCSObj) {
+ CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
+ if (pAlterCS) {
+ if (m_nComponents == 0) { // NO valid ICC profile
+ if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace
+ m_nComponents = pAlterCS->CountComponents();
+ m_pAlterCS = pAlterCS;
+ m_bOwn = TRUE;
+ } else { // No valid alternative colorspace
+ pAlterCS->ReleaseCS();
+ int32_t nDictComponents = pDict ? pDict->GetIntegerBy("N") : 0;
+ if (nDictComponents != 1 && nDictComponents != 3 &&
+ nDictComponents != 4) {
+ return FALSE;
+ }
+ m_nComponents = nDictComponents;
+ }
+
+ } else { // Using sRGB
+ if (pAlterCS->CountComponents() != m_nComponents) {
+ pAlterCS->ReleaseCS();
+ } else {
+ m_pAlterCS = pAlterCS;
+ m_bOwn = TRUE;
+ }
+ }
+ }
+ }
+ if (!m_pAlterCS) {
+ if (m_nComponents == 1)
+ m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
+ else if (m_nComponents == 3)
+ m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
+ else if (m_nComponents == 4)
+ m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
+ }
+ }
+ CPDF_Array* pRanges = pDict->GetArrayBy("Range");
+ m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
+ for (int i = 0; i < m_nComponents * 2; i++) {
+ if (pRanges)
+ m_pRanges[i] = pRanges->GetNumberAt(i);
+ else if (i % 2)
+ m_pRanges[i] = 1.0f;
+ else
+ m_pRanges[i] = 0;
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ if (m_pProfile && m_pProfile->m_bsRGB) {
+ R = pBuf[0];
+ G = pBuf[1];
+ B = pBuf[2];
+ return TRUE;
+ }
+ ICodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
+ if (!m_pProfile->m_pTransform || !pIccModule) {
+ if (m_pAlterCS) {
+ return m_pAlterCS->GetRGB(pBuf, R, G, B);
+ }
+ R = G = B = 0.0f;
+ return TRUE;
+ }
+ FX_FLOAT rgb[3];
+ pIccModule->SetComponents(m_nComponents);
+ pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
+ R = rgb[0];
+ G = rgb[1];
+ B = rgb[2];
+ return TRUE;
+}
+
+FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const {
+ return FALSE;
+}
+
+FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT& c,
+ FX_FLOAT& m,
+ FX_FLOAT& y,
+ FX_FLOAT& k) const {
+ if (m_nComponents != 4)
+ return FALSE;
+
+ c = pBuf[0];
+ m = pBuf[1];
+ y = pBuf[2];
+ k = pBuf[3];
+ return TRUE;
+}
+
+void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) {
+ CPDF_ColorSpace::EnableStdConversion(bEnabled);
+ if (m_pAlterCS)
+ m_pAlterCS->EnableStdConversion(bEnabled);
+}
+
+void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
+ const uint8_t* pSrcBuf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask) const {
+ if (m_pProfile->m_bsRGB) {
+ ReverseRGB(pDestBuf, pSrcBuf, pixels);
+ } else if (m_pProfile->m_pTransform) {
+ int nMaxColors = 1;
+ for (int i = 0; i < m_nComponents; i++) {
+ nMaxColors *= 52;
+ }
+ if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
+ CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
+ m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
+ } else {
+ if (!m_pCache) {
+ ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3);
+ uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents);
+ uint8_t* pSrc = temp_src;
+ for (int i = 0; i < nMaxColors; i++) {
+ FX_DWORD color = i;
+ FX_DWORD order = nMaxColors / 52;
+ for (int c = 0; c < m_nComponents; c++) {
+ *pSrc++ = (uint8_t)(color / order * 5);
+ color %= order;
+ order /= 52;
+ }
+ }
+ CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
+ m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
+ FX_Free(temp_src);
+ }
+ for (int i = 0; i < pixels; i++) {
+ int index = 0;
+ for (int c = 0; c < m_nComponents; c++) {
+ index = index * 52 + (*pSrcBuf) / 5;
+ pSrcBuf++;
+ }
+ index *= 3;
+ *pDestBuf++ = m_pCache[index];
+ *pDestBuf++ = m_pCache[index + 1];
+ *pDestBuf++ = m_pCache[index + 2];
+ }
+ }
+ } else if (m_pAlterCS) {
+ m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width,
+ image_height);
+ }
+}
+
+CPDF_IndexedCS::CPDF_IndexedCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
+ m_pBaseCS(nullptr),
+ m_pCountedBaseCS(nullptr),
+ m_pCompMinMax(nullptr) {}
+
+CPDF_IndexedCS::~CPDF_IndexedCS() {
+ FX_Free(m_pCompMinMax);
+ CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
+ if (pCS && m_pDocument) {
+ m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
+ }
+}
+
+FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ if (pArray->GetCount() < 4) {
+ return FALSE;
+ }
+ CPDF_Object* pBaseObj = pArray->GetElementValue(1);
+ if (pBaseObj == m_pArray) {
+ return FALSE;
+ }
+ CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
+ m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
+ if (!m_pBaseCS) {
+ return FALSE;
+ }
+ m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
+ m_nBaseComponents = m_pBaseCS->CountComponents();
+ m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
+ FX_FLOAT defvalue;
+ for (int i = 0; i < m_nBaseComponents; i++) {
+ m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2],
+ m_pCompMinMax[i * 2 + 1]);
+ m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
+ }
+ m_MaxIndex = pArray->GetIntegerAt(2);
+
+ CPDF_Object* pTableObj = pArray->GetElementValue(3);
+ if (!pTableObj)
+ return FALSE;
+
+ if (CPDF_String* pString = pTableObj->AsString()) {
+ m_Table = pString->GetString();
+ } else if (CPDF_Stream* pStream = pTableObj->AsStream()) {
+ CPDF_StreamAcc acc;
+ acc.LoadAllData(pStream, FALSE);
+ m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ int index = (int32_t)(*pBuf);
+ if (index < 0 || index > m_MaxIndex) {
+ return FALSE;
+ }
+ if (m_nBaseComponents) {
+ if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
+ (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) {
+ R = G = B = 0;
+ return FALSE;
+ }
+ }
+ CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
+ FX_FLOAT* comps = Comps;
+ const uint8_t* pTable = m_Table;
+ for (int i = 0; i < m_nBaseComponents; i++) {
+ comps[i] =
+ m_pCompMinMax[i * 2] +
+ m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
+ }
+ return m_pBaseCS->GetRGB(comps, R, G, B);
+}
+
+CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const {
+ return m_pBaseCS;
+}
+
+void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
+ CPDF_ColorSpace::EnableStdConversion(bEnabled);
+ if (m_pBaseCS) {
+ m_pBaseCS->EnableStdConversion(bEnabled);
+ }
+}
+
+CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
+ m_pBaseCS(nullptr),
+ m_pCountedBaseCS(nullptr) {}
+
+CPDF_PatternCS::~CPDF_PatternCS() {
+ CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
+ if (pCS && m_pDocument) {
+ m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
+ }
+}
+
+FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Object* pBaseCS = pArray->GetElementValue(1);
+ if (pBaseCS == m_pArray) {
+ return FALSE;
+ }
+ CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
+ m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
+ if (m_pBaseCS) {
+ if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
+ return FALSE;
+ }
+ m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
+ m_nComponents = m_pBaseCS->CountComponents() + 1;
+ if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
+ return FALSE;
+ }
+ } else {
+ m_nComponents = 1;
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ if (m_pBaseCS) {
+ ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
+ PatternValue* pvalue = (PatternValue*)pBuf;
+ if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) {
+ return TRUE;
+ }
+ }
+ R = G = B = 0.75f;
+ return FALSE;
+}
+
+CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
+ return m_pBaseCS;
+}
+
+CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
+ m_pAltCS(nullptr),
+ m_pFunc(nullptr) {}
+
+CPDF_SeparationCS::~CPDF_SeparationCS() {
+ if (m_pAltCS) {
+ m_pAltCS->ReleaseCS();
+ }
+ delete m_pFunc;
+}
+
+void CPDF_SeparationCS::GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const {
+ value = 1.0f;
+ min = 0;
+ max = 1.0f;
+}
+
+FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CFX_ByteString name = pArray->GetStringAt(1);
+ if (name == "None") {
+ m_Type = None;
+ } else {
+ m_Type = Colorant;
+ CPDF_Object* pAltCS = pArray->GetElementValue(2);
+ if (pAltCS == m_pArray) {
+ return FALSE;
+ }
+ m_pAltCS = Load(pDoc, pAltCS);
+ if (!m_pAltCS) {
+ return FALSE;
+ }
+ CPDF_Object* pFuncObj = pArray->GetElementValue(3);
+ if (pFuncObj && !pFuncObj->IsName())
+ m_pFunc = CPDF_Function::Load(pFuncObj);
+
+ if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
+ delete m_pFunc;
+ m_pFunc = NULL;
+ }
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ if (m_Type == None) {
+ return FALSE;
+ }
+ if (!m_pFunc) {
+ if (!m_pAltCS) {
+ return FALSE;
+ }
+ int nComps = m_pAltCS->CountComponents();
+ CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
+ for (int i = 0; i < nComps; i++) {
+ results[i] = *pBuf;
+ }
+ return m_pAltCS->GetRGB(results, R, G, B);
+ }
+ CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
+ int nresults = 0;
+ m_pFunc->Call(pBuf, 1, results, nresults);
+ if (nresults == 0) {
+ return FALSE;
+ }
+ if (m_pAltCS) {
+ return m_pAltCS->GetRGB(results, R, G, B);
+ }
+ R = G = B = 0;
+ return FALSE;
+}
+
+void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) {
+ CPDF_ColorSpace::EnableStdConversion(bEnabled);
+ if (m_pAltCS) {
+ m_pAltCS->EnableStdConversion(bEnabled);
+ }
+}
+
+CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc)
+ : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
+ m_pAltCS(nullptr),
+ m_pFunc(nullptr) {}
+
+CPDF_DeviceNCS::~CPDF_DeviceNCS() {
+ delete m_pFunc;
+ if (m_pAltCS) {
+ m_pAltCS->ReleaseCS();
+ }
+}
+
+void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const {
+ value = 1.0f;
+ min = 0;
+ max = 1.0f;
+}
+
+FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ CPDF_Array* pObj = ToArray(pArray->GetElementValue(1));
+ if (!pObj)
+ return FALSE;
+
+ m_nComponents = pObj->GetCount();
+ CPDF_Object* pAltCS = pArray->GetElementValue(2);
+ if (!pAltCS || pAltCS == m_pArray) {
+ return FALSE;
+ }
+ m_pAltCS = Load(pDoc, pAltCS);
+ m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
+ if (!m_pAltCS || !m_pFunc) {
+ return FALSE;
+ }
+ if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const {
+ if (!m_pFunc) {
+ return FALSE;
+ }
+ CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
+ int nresults = 0;
+ m_pFunc->Call(pBuf, m_nComponents, results, nresults);
+ if (nresults == 0) {
+ return FALSE;
+ }
+ return m_pAltCS->GetRGB(results, R, G, B);
+}
+
+void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
+ CPDF_ColorSpace::EnableStdConversion(bEnabled);
+ if (m_pAltCS) {
+ m_pAltCS->EnableStdConversion(bEnabled);
+ }
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp b/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp
index 02999c9d13..81e5e41d60 100644
--- a/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp
@@ -6,6 +6,10 @@
#include "core/fpdfapi/fpdf_page/cpdf_colorstate.h"
+#include "core/fpdfapi/fpdf_page/cpdf_pattern.h"
+#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h"
+#include "core/include/fxge/fx_dib.h"
+
void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS,
FX_FLOAT* pValue,
int nValues) {
diff --git a/core/fpdfapi/fpdf_page/cpdf_colorstatedata.h b/core/fpdfapi/fpdf_page/cpdf_colorstatedata.h
index 319fea51ae..96e43bd9f3 100644
--- a/core/fpdfapi/fpdf_page/cpdf_colorstatedata.h
+++ b/core/fpdfapi/fpdf_page/cpdf_colorstatedata.h
@@ -7,8 +7,8 @@
#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSTATEDATA_H_
#define CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSTATEDATA_H_
+#include "core/fpdfapi/fpdf_page/include/cpdf_color.h"
#include "core/fxcrt/include/fx_system.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
class CPDF_ColorStateData {
public:
diff --git a/core/fpdfapi/fpdf_page/cpdf_countedobject.h b/core/fpdfapi/fpdf_page/cpdf_countedobject.h
new file mode 100644
index 0000000000..da840bec60
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_countedobject.h
@@ -0,0 +1,45 @@
+// 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_PAGE_CPDF_COUNTEDOBJECT_H_
+#define CORE_FPDFAPI_FPDF_PAGE_CPDF_COUNTEDOBJECT_H_
+
+#include "core/fpdfapi/fpdf_page/cpdf_pattern.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h"
+#include "core/fxcrt/include/fx_system.h"
+
+template <class T>
+class CPDF_CountedObject {
+ public:
+ explicit CPDF_CountedObject(T* ptr) : m_nCount(1), m_pObj(ptr) {}
+ void reset(T* ptr) { // CAUTION: tosses prior ref counts.
+ m_nCount = 1;
+ m_pObj = ptr;
+ }
+ void clear() { // Now you're all weak ptrs ...
+ delete m_pObj;
+ m_pObj = nullptr;
+ }
+ T* get() const { return m_pObj; }
+ T* AddRef() {
+ FXSYS_assert(m_pObj);
+ ++m_nCount;
+ return m_pObj;
+ }
+ void RemoveRef() {
+ if (m_nCount)
+ --m_nCount;
+ }
+ size_t use_count() const { return m_nCount; }
+
+ protected:
+ size_t m_nCount;
+ T* m_pObj;
+};
+using CPDF_CountedColorSpace = CPDF_CountedObject<CPDF_ColorSpace>;
+using CPDF_CountedPattern = CPDF_CountedObject<CPDF_Pattern>;
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_COUNTEDOBJECT_H_
diff --git a/core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp b/core/fpdfapi/fpdf_page/cpdf_image.cpp
index 50e4f79881..d9e7d774be 100644
--- a/core/fpdfapi/fpdf_edit/fpdf_edit_image.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_image.cpp
@@ -1,20 +1,78 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// 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_page/include/cpdf_page.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/include/cpdf_modulemgr.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/include/fxge/fx_dib.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/include/fxcodec/fx_codec.h"
#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h"
#include "core/fpdfapi/fpdf_render/render_int.h"
-#include "core/fpdfapi/include/cpdf_modulemgr.h"
-#include "core/include/fxcodec/fx_codec.h"
+
+CPDF_Image::CPDF_Image(CPDF_Document* pDoc)
+ : m_pDIBSource(nullptr),
+ m_pMask(nullptr),
+ m_MatteColor(0),
+ m_pStream(nullptr),
+ m_bInline(FALSE),
+ m_pInlineDict(nullptr),
+ m_pDocument(pDoc),
+ m_pOC(nullptr) {}
+
+CPDF_Image::~CPDF_Image() {
+ if (m_bInline) {
+ if (m_pStream)
+ m_pStream->Release();
+ if (m_pInlineDict)
+ m_pInlineDict->Release();
+ }
+}
+
+void CPDF_Image::Release() {
+ if (m_bInline || (m_pStream && m_pStream->GetObjNum() == 0))
+ delete this;
+}
+
+CPDF_Image* CPDF_Image::Clone() {
+ if (m_pStream->GetObjNum())
+ return m_pDocument->GetPageData()->GetImage(m_pStream);
+
+ CPDF_Image* pImage = new CPDF_Image(m_pDocument);
+ pImage->LoadImageF(ToStream(m_pStream->Clone()), m_bInline);
+ if (m_bInline)
+ pImage->SetInlineDict(ToDictionary(m_pInlineDict->Clone(TRUE)));
+
+ return pImage;
+}
+
+FX_BOOL CPDF_Image::LoadImageF(CPDF_Stream* pStream, FX_BOOL bInline) {
+ m_pStream = pStream;
+ if (m_bInline && m_pInlineDict) {
+ m_pInlineDict->Release();
+ m_pInlineDict = NULL;
+ }
+ m_bInline = bInline;
+ CPDF_Dictionary* pDict = pStream->GetDict();
+ if (m_bInline) {
+ m_pInlineDict = ToDictionary(pDict->Clone());
+ }
+ m_pOC = pDict->GetDictBy("OC");
+ m_bIsMask =
+ !pDict->KeyExist("ColorSpace") || pDict->GetIntegerBy("ImageMask");
+ m_bInterpolate = pDict->GetIntegerBy("Interpolate");
+ m_Height = pDict->GetIntegerBy("Height");
+ m_Width = pDict->GetIntegerBy("Width");
+ return TRUE;
+}
CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, FX_DWORD size) {
int32_t width;
@@ -61,6 +119,7 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, FX_DWORD size) {
}
return pDict;
}
+
void CPDF_Image::SetJpegImage(uint8_t* pData, FX_DWORD size) {
CPDF_Dictionary* pDict = InitJPEG(pData, size);
if (!pDict) {
@@ -68,6 +127,7 @@ void CPDF_Image::SetJpegImage(uint8_t* pData, FX_DWORD size) {
}
m_pStream->InitStream(pData, size, pDict);
}
+
void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) {
FX_DWORD size = (FX_DWORD)pFile->GetSize();
if (!size) {
@@ -92,23 +152,12 @@ void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) {
}
m_pStream->InitStreamFromFile(pFile, pDict);
}
-void _DCTEncodeBitmap(CPDF_Dictionary* pBitmapDict,
- const CFX_DIBitmap* pBitmap,
- int quality,
- uint8_t*& buf,
- FX_STRSIZE& size) {}
-void _JBIG2EncodeBitmap(CPDF_Dictionary* pBitmapDict,
- const CFX_DIBitmap* pBitmap,
- CPDF_Document* pDoc,
- uint8_t*& buf,
- FX_STRSIZE& size,
- FX_BOOL bLossLess) {}
+
void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
int32_t iCompress,
IFX_FileWrite* pFileWrite,
IFX_FileRead* pFileRead,
- const CFX_DIBitmap* pMask,
- const CPDF_ImageSetParam* pParam) {
+ const CFX_DIBitmap* pMask) {
int32_t BitmapWidth = pBitmap->GetWidth();
int32_t BitmapHeight = pBitmap->GetHeight();
if (BitmapWidth < 1 || BitmapHeight < 1) {
@@ -117,8 +166,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
uint8_t* src_buf = pBitmap->GetBuffer();
int32_t src_pitch = pBitmap->GetPitch();
int32_t bpp = pBitmap->GetBPP();
- FX_BOOL bUseMatte =
- pParam && pParam->pMatteColor && (pBitmap->GetFormat() == FXDIB_Argb);
+
CPDF_Dictionary* pDict = new CPDF_Dictionary;
pDict->SetAtName("Type", "XObject");
pDict->SetAtName("Subtype", "Image");
@@ -234,11 +282,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
pMaskDict->SetAtInteger("BitsPerComponent", 8);
if (pMaskBitmap->GetBPP() == 8 &&
(iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) {
- _DCTEncodeBitmap(pMaskDict, pMaskBitmap, pParam ? pParam->nQuality : 75,
- mask_buf, mask_size);
} else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) {
- _JBIG2EncodeBitmap(pMaskDict, pMaskBitmap, m_pDocument, mask_buf,
- mask_size, TRUE);
} else {
mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth);
mask_size = maskHeight * maskWidth; // Safe since checked alloc returned.
@@ -248,15 +292,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
}
}
pMaskDict->SetAtInteger("Length", mask_size);
- if (bUseMatte) {
- int a, r, g, b;
- ArgbDecode(*(pParam->pMatteColor), a, r, g, b);
- CPDF_Array* pMatte = new CPDF_Array;
- pMatte->AddInteger(r);
- pMatte->AddInteger(g);
- pMatte->AddInteger(b);
- pMaskDict->SetAt("Matte", pMatte);
- }
+
CPDF_Stream* pMaskStream = new CPDF_Stream(mask_buf, mask_size, pMaskDict);
m_pDocument->AddIndirectObject(pMaskStream);
pDict->SetAtReference("SMask", m_pDocument, pMaskStream);
@@ -267,14 +303,8 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
FX_BOOL bStream = pFileWrite && pFileRead;
if (opType == 0) {
if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) {
- if (pBitmap->GetBPP() == 1) {
- _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size,
- TRUE);
- }
} else {
if (pBitmap->GetBPP() == 1) {
- _JBIG2EncodeBitmap(pDict, pBitmap, m_pDocument, dest_buf, dest_size,
- FALSE);
} else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) {
CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap();
pNewBitmap->Copy(pBitmap);
@@ -289,32 +319,6 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
dest_size = 0;
delete pNewBitmap;
return;
- } else {
- if (bUseMatte) {
- CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap();
- pNewBitmap->Create(BitmapWidth, BitmapHeight, FXDIB_Argb);
- uint8_t* dst_buf = pNewBitmap->GetBuffer();
- int32_t src_offset = 0;
- for (int32_t row = 0; row < BitmapHeight; row++) {
- src_offset = row * src_pitch;
- for (int32_t column = 0; column < BitmapWidth; column++) {
- FX_FLOAT alpha = src_buf[src_offset + 3] / 255.0f;
- dst_buf[src_offset] = (uint8_t)(src_buf[src_offset] * alpha);
- dst_buf[src_offset + 1] =
- (uint8_t)(src_buf[src_offset + 1] * alpha);
- dst_buf[src_offset + 2] =
- (uint8_t)(src_buf[src_offset + 2] * alpha);
- dst_buf[src_offset + 3] = (uint8_t)(src_buf[src_offset + 3]);
- src_offset += 4;
- }
- }
- _DCTEncodeBitmap(pDict, pNewBitmap, pParam ? pParam->nQuality : 75,
- dest_buf, dest_size);
- delete pNewBitmap;
- } else {
- _DCTEncodeBitmap(pDict, pBitmap, pParam ? pParam->nQuality : 75,
- dest_buf, dest_size);
- }
}
}
if (bStream) {
@@ -352,7 +356,7 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
for (int32_t row = 0; row < BitmapHeight; row++) {
src_offset = row * src_pitch;
for (int32_t column = 0; column < BitmapWidth; column++) {
- FX_FLOAT alpha = bUseMatte ? src_buf[src_offset + 3] / 255.0f : 1;
+ FX_FLOAT alpha = 1;
pDest[dest_offset] = (uint8_t)(src_buf[src_offset + 2] * alpha);
pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha);
pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha);
@@ -386,6 +390,72 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap,
m_Height = BitmapHeight;
FX_Free(dest_buf);
}
+
void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) {
pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap);
}
+
+CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask,
+ FX_DWORD* pMatteColor,
+ FX_BOOL bStdCS,
+ FX_DWORD GroupFamily,
+ FX_BOOL bLoadMask) const {
+ std::unique_ptr<CPDF_DIBSource> source(new CPDF_DIBSource);
+ if (source->Load(m_pDocument, m_pStream,
+ reinterpret_cast<CPDF_DIBSource**>(ppMask), pMatteColor,
+ nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) {
+ return source.release();
+ }
+ return nullptr;
+}
+
+CFX_DIBSource* CPDF_Image::DetachBitmap() {
+ CFX_DIBSource* pBitmap = m_pDIBSource;
+ m_pDIBSource = nullptr;
+ return pBitmap;
+}
+
+CFX_DIBSource* CPDF_Image::DetachMask() {
+ CFX_DIBSource* pBitmap = m_pMask;
+ m_pMask = nullptr;
+ return pBitmap;
+}
+
+FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource,
+ CPDF_Dictionary* pPageResource,
+ FX_BOOL bStdCS,
+ FX_DWORD GroupFamily,
+ FX_BOOL bLoadMask) {
+ std::unique_ptr<CPDF_DIBSource> source(new CPDF_DIBSource);
+ int ret =
+ source->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource,
+ pPageResource, bStdCS, GroupFamily, bLoadMask);
+ if (ret == 2) {
+ m_pDIBSource = source.release();
+ return TRUE;
+ }
+ if (!ret) {
+ m_pDIBSource = nullptr;
+ return FALSE;
+ }
+ m_pMask = source->DetachMask();
+ m_MatteColor = source->GetMatteColor();
+ m_pDIBSource = source.release();
+ return FALSE;
+}
+
+FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) {
+ CPDF_DIBSource* pSource = static_cast<CPDF_DIBSource*>(m_pDIBSource);
+ int ret = pSource->ContinueLoadDIBSource(pPause);
+ if (ret == 2) {
+ return TRUE;
+ }
+ if (!ret) {
+ delete m_pDIBSource;
+ m_pDIBSource = nullptr;
+ return FALSE;
+ }
+ m_pMask = pSource->DetachMask();
+ m_MatteColor = pSource->GetMatteColor();
+ return FALSE;
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp b/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp
index f339935ecb..6203d56273 100644
--- a/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp
@@ -6,6 +6,7 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp
new file mode 100644
index 0000000000..1d983d2b25
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp
@@ -0,0 +1,119 @@
+// 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_page/cpdf_meshstream.h"
+
+#include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+
+FX_BOOL CPDF_MeshStream::Load(CPDF_Stream* pShadingStream,
+ CPDF_Function** pFuncs,
+ int nFuncs,
+ CPDF_ColorSpace* pCS) {
+ m_Stream.LoadAllData(pShadingStream);
+ m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize());
+ m_pFuncs = pFuncs;
+ m_nFuncs = nFuncs;
+ m_pCS = pCS;
+ CPDF_Dictionary* pDict = pShadingStream->GetDict();
+ m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate");
+ m_nCompBits = pDict->GetIntegerBy("BitsPerComponent");
+ m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag");
+ if (!m_nCoordBits || !m_nCompBits)
+ return FALSE;
+
+ FX_DWORD nComps = pCS->CountComponents();
+ if (nComps > 8)
+ return FALSE;
+
+ m_nComps = nFuncs ? 1 : nComps;
+ if (((int)m_nComps < 0) || m_nComps > 8)
+ return FALSE;
+
+ m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1;
+ m_CompMax = (1 << m_nCompBits) - 1;
+ CPDF_Array* pDecode = pDict->GetArrayBy("Decode");
+ if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2)
+ return FALSE;
+
+ m_xmin = pDecode->GetNumberAt(0);
+ m_xmax = pDecode->GetNumberAt(1);
+ m_ymin = pDecode->GetNumberAt(2);
+ m_ymax = pDecode->GetNumberAt(3);
+ for (FX_DWORD i = 0; i < m_nComps; i++) {
+ m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4);
+ m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5);
+ }
+ return TRUE;
+}
+
+FX_DWORD CPDF_MeshStream::GetFlag() {
+ return m_BitStream.GetBits(m_nFlagBits) & 0x03;
+}
+
+void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) {
+ if (m_nCoordBits == 32) {
+ x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) *
+ (m_xmax - m_xmin) / (double)m_CoordMax);
+ y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) *
+ (m_ymax - m_ymin) / (double)m_CoordMax);
+ } else {
+ x = m_xmin +
+ m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax;
+ y = m_ymin +
+ m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax;
+ }
+}
+
+void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) {
+ FX_DWORD i;
+ FX_FLOAT color_value[8];
+ for (i = 0; i < m_nComps; i++) {
+ color_value[i] = m_ColorMin[i] +
+ m_BitStream.GetBits(m_nCompBits) *
+ (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax;
+ }
+ if (m_nFuncs) {
+ static const int kMaxResults = 8;
+ FX_FLOAT result[kMaxResults];
+ int nResults;
+ FXSYS_memset(result, 0, sizeof(result));
+ for (FX_DWORD i = 0; i < m_nFuncs; i++) {
+ if (m_pFuncs[i] && m_pFuncs[i]->CountOutputs() <= kMaxResults) {
+ m_pFuncs[i]->Call(color_value, 1, result, nResults);
+ }
+ }
+ m_pCS->GetRGB(result, r, g, b);
+ } else {
+ m_pCS->GetRGB(color_value, r, g, b);
+ }
+}
+
+FX_DWORD CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex,
+ CFX_Matrix* pObject2Bitmap) {
+ FX_DWORD flag = GetFlag();
+ GetCoords(vertex.x, vertex.y);
+ pObject2Bitmap->Transform(vertex.x, vertex.y);
+ GetColor(vertex.r, vertex.g, vertex.b);
+ m_BitStream.ByteAlign();
+ return flag;
+}
+
+FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex,
+ int count,
+ CFX_Matrix* pObject2Bitmap) {
+ for (int i = 0; i < count; i++) {
+ if (m_BitStream.IsEOF())
+ return FALSE;
+
+ GetCoords(vertex[i].x, vertex[i].y);
+ pObject2Bitmap->Transform(vertex[i].x, vertex[i].y);
+ GetColor(vertex[i].r, vertex[i].g, vertex[i].b);
+ m_BitStream.ByteAlign();
+ }
+ return TRUE;
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.h b/core/fpdfapi/fpdf_page/cpdf_meshstream.h
new file mode 100644
index 0000000000..4934c0b133
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_meshstream.h
@@ -0,0 +1,63 @@
+// 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_PAGE_CPDF_MESHSTREAM_H_
+#define CORE_FPDFAPI_FPDF_PAGE_CPDF_MESHSTREAM_H_
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "core/fxcrt/include/fx_basic.h"
+#include "core/fxcrt/include/fx_system.h"
+
+struct CPDF_MeshVertex {
+ FX_FLOAT x;
+ FX_FLOAT y;
+ FX_FLOAT r;
+ FX_FLOAT g;
+ FX_FLOAT b;
+};
+
+class CFX_Matrix;
+class CPDF_ColorSpace;
+class CPDF_Function;
+class CPDF_Stream;
+
+class CPDF_MeshStream {
+ public:
+ FX_BOOL Load(CPDF_Stream* pShadingStream,
+ CPDF_Function** pFuncs,
+ int nFuncs,
+ CPDF_ColorSpace* pCS);
+
+ FX_DWORD GetFlag();
+
+ void GetCoords(FX_FLOAT& x, FX_FLOAT& y);
+ void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b);
+
+ FX_DWORD GetVertex(CPDF_MeshVertex& vertex, CFX_Matrix* pObject2Bitmap);
+ FX_BOOL GetVertexRow(CPDF_MeshVertex* vertex,
+ int count,
+ CFX_Matrix* pObject2Bitmap);
+
+ CPDF_Function** m_pFuncs;
+ CPDF_ColorSpace* m_pCS;
+ FX_DWORD m_nFuncs;
+ FX_DWORD m_nCoordBits;
+ FX_DWORD m_nCompBits;
+ FX_DWORD m_nFlagBits;
+ FX_DWORD m_nComps;
+ FX_DWORD m_CoordMax;
+ FX_DWORD m_CompMax;
+ FX_FLOAT m_xmin;
+ FX_FLOAT m_xmax;
+ FX_FLOAT m_ymin;
+ FX_FLOAT m_ymax;
+ FX_FLOAT m_ColorMin[8];
+ FX_FLOAT m_ColorMax[8];
+ CPDF_StreamAcc m_Stream;
+ CFX_BitStream m_BitStream;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_MESHSTREAM_H_
diff --git a/core/fpdfapi/fpdf_page/cpdf_page.cpp b/core/fpdfapi/fpdf_page/cpdf_page.cpp
index 2c01cd5573..6fd9b0a9b3 100644
--- a/core/fpdfapi/fpdf_page/cpdf_page.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_page.cpp
@@ -9,6 +9,7 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fpdfapi/ipdf_rendermodule.h"
diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp b/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp
index fa6347e5bc..cd6eca5adc 100644
--- a/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp
@@ -8,6 +8,7 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
CPDF_PageObjectHolder::CPDF_PageObjectHolder()
: m_pFormDict(nullptr),
diff --git a/core/fpdfapi/fpdf_page/cpdf_pattern.cpp b/core/fpdfapi/fpdf_page/cpdf_pattern.cpp
new file mode 100644
index 0000000000..fc9d10e7ab
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_pattern.cpp
@@ -0,0 +1,21 @@
+// 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_page/cpdf_pattern.h"
+
+CPDF_Pattern::CPDF_Pattern(PatternType type,
+ CPDF_Document* pDoc,
+ CPDF_Object* pObj,
+ const CFX_Matrix* pParentMatrix)
+ : m_PatternType(type),
+ m_pDocument(pDoc),
+ m_pPatternObj(pObj),
+ m_bForceClear(FALSE) {
+ if (pParentMatrix)
+ m_ParentMatrix = *pParentMatrix;
+}
+
+CPDF_Pattern::~CPDF_Pattern() {}
diff --git a/core/fpdfapi/fpdf_page/cpdf_pattern.h b/core/fpdfapi/fpdf_page/cpdf_pattern.h
new file mode 100644
index 0000000000..7f9a33bac9
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_pattern.h
@@ -0,0 +1,39 @@
+// 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_PAGE_CPDF_PATTERN_H_
+#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PATTERN_H_
+
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_Document;
+class CPDF_Object;
+
+class CPDF_Pattern {
+ public:
+ enum PatternType { TILING = 1, SHADING };
+
+ virtual ~CPDF_Pattern();
+
+ void SetForceClear(FX_BOOL bForceClear) { m_bForceClear = bForceClear; }
+
+ const PatternType m_PatternType;
+ CPDF_Document* const m_pDocument;
+ CPDF_Object* const m_pPatternObj;
+ CFX_Matrix m_Pattern2Form;
+ CFX_Matrix m_ParentMatrix;
+
+ protected:
+ CPDF_Pattern(PatternType type,
+ CPDF_Document* pDoc,
+ CPDF_Object* pObj,
+ const CFX_Matrix* pParentMatrix);
+
+ FX_BOOL m_bForceClear;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PATTERN_H_
diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp b/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp
index 16287fe692..56dd6d4af4 100644
--- a/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp
@@ -6,6 +6,7 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_shadingobject.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp b/core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp
new file mode 100644
index 0000000000..6ccf1403f9
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp
@@ -0,0 +1,101 @@
+// 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_page/cpdf_shadingpattern.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
+
+namespace {
+
+ShadingType ToShadingType(int type) {
+ return (type > static_cast<int>(kInvalidShading) &&
+ type < static_cast<int>(kMaxShading))
+ ? static_cast<ShadingType>(type)
+ : kInvalidShading;
+}
+
+} // namespace
+
+CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc,
+ CPDF_Object* pPatternObj,
+ FX_BOOL bShading,
+ const CFX_Matrix* parentMatrix)
+ : CPDF_Pattern(SHADING,
+ pDoc,
+ bShading ? nullptr : pPatternObj,
+ parentMatrix),
+ m_ShadingType(kInvalidShading),
+ m_bShadingObj(bShading),
+ m_pShadingObj(pPatternObj),
+ m_pCS(nullptr),
+ m_pCountedCS(nullptr),
+ m_nFuncs(0) {
+ if (!bShading) {
+ CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
+ m_Pattern2Form = pDict->GetMatrixBy("Matrix");
+ m_pShadingObj = pDict->GetElementValue("Shading");
+ if (parentMatrix)
+ m_Pattern2Form.Concat(*parentMatrix);
+ }
+ for (int i = 0; i < FX_ArraySize(m_pFunctions); ++i)
+ m_pFunctions[i] = nullptr;
+}
+
+CPDF_ShadingPattern::~CPDF_ShadingPattern() {
+ for (int i = 0; i < m_nFuncs; ++i)
+ delete m_pFunctions[i];
+
+ CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->get() : nullptr;
+ if (pCS && m_pDocument)
+ m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
+}
+
+FX_BOOL CPDF_ShadingPattern::Load() {
+ if (m_ShadingType != kInvalidShading)
+ return TRUE;
+
+ CPDF_Dictionary* pShadingDict =
+ m_pShadingObj ? m_pShadingObj->GetDict() : nullptr;
+ if (!pShadingDict)
+ return FALSE;
+
+ if (m_nFuncs) {
+ for (int i = 0; i < m_nFuncs; i++)
+ delete m_pFunctions[i];
+ m_nFuncs = 0;
+ }
+ CPDF_Object* pFunc = pShadingDict->GetElementValue("Function");
+ if (pFunc) {
+ if (CPDF_Array* pArray = pFunc->AsArray()) {
+ m_nFuncs = std::min<int>(pArray->GetCount(), 4);
+
+ for (int i = 0; i < m_nFuncs; i++)
+ m_pFunctions[i] = CPDF_Function::Load(pArray->GetElementValue(i));
+ } else {
+ m_pFunctions[0] = CPDF_Function::Load(pFunc);
+ m_nFuncs = 1;
+ }
+ }
+ CPDF_Object* pCSObj = pShadingDict->GetElementValue("ColorSpace");
+ if (!pCSObj)
+ return FALSE;
+
+ CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
+ m_pCS = pDocPageData->GetColorSpace(pCSObj, nullptr);
+ if (m_pCS)
+ m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray());
+
+ m_ShadingType = ToShadingType(pShadingDict->GetIntegerBy("ShadingType"));
+
+ // We expect to have a stream if our shading type is a mesh.
+ if (IsMeshShading() && !ToStream(m_pShadingObj))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingpattern.h b/core/fpdfapi/fpdf_page/cpdf_shadingpattern.h
new file mode 100644
index 0000000000..55a249a1bc
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_shadingpattern.h
@@ -0,0 +1,62 @@
+// 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_PAGE_CPDF_SHADINGPATTERN_H_
+#define CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGPATTERN_H_
+
+#include "core/fpdfapi/fpdf_page/cpdf_countedobject.h"
+#include "core/fpdfapi/fpdf_page/cpdf_pattern.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fxcrt/include/fx_system.h"
+
+typedef enum {
+ kInvalidShading = 0,
+ kFunctionBasedShading = 1,
+ kAxialShading = 2,
+ kRadialShading = 3,
+ kFreeFormGouraudTriangleMeshShading = 4,
+ kLatticeFormGouraudTriangleMeshShading = 5,
+ kCoonsPatchMeshShading = 6,
+ kTensorProductPatchMeshShading = 7,
+ kMaxShading = 8
+} ShadingType;
+
+class CFX_Matrix;
+class CPDF_ColorSpace;
+class CPDF_Document;
+class CPDF_Object;
+
+class CPDF_ShadingPattern : public CPDF_Pattern {
+ public:
+ CPDF_ShadingPattern(CPDF_Document* pDoc,
+ CPDF_Object* pPatternObj,
+ FX_BOOL bShading,
+ const CFX_Matrix* parentMatrix);
+
+ ~CPDF_ShadingPattern() override;
+
+ bool IsMeshShading() const {
+ return m_ShadingType == kFreeFormGouraudTriangleMeshShading ||
+ m_ShadingType == kLatticeFormGouraudTriangleMeshShading ||
+ m_ShadingType == kCoonsPatchMeshShading ||
+ m_ShadingType == kTensorProductPatchMeshShading;
+ }
+ FX_BOOL Load();
+
+ ShadingType m_ShadingType;
+ FX_BOOL m_bShadingObj;
+ CPDF_Object* m_pShadingObj;
+
+ // Still keep |m_pCS| as some CPDF_ColorSpace (name object) are not managed
+ // as counted objects. Refer to CPDF_DocPageData::GetColorSpace.
+ CPDF_ColorSpace* m_pCS;
+
+ CPDF_CountedColorSpace* m_pCountedCS;
+ CPDF_Function* m_pFunctions[4];
+ int m_nFuncs;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGPATTERN_H_
diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp
index ef37b30631..cf588dcf3d 100644
--- a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp
@@ -6,6 +6,9 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
+#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+
CPDF_TextObject::CPDF_TextObject()
: m_PosX(0),
m_PosY(0),
diff --git a/core/fpdfapi/fpdf_page/cpdf_textstate.cpp b/core/fpdfapi/fpdf_page/cpdf_textstate.cpp
index f56d58ed0a..5269cae44b 100644
--- a/core/fpdfapi/fpdf_page/cpdf_textstate.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_textstate.cpp
@@ -4,6 +4,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
#include "core/fpdfapi/fpdf_page/cpdf_textstate.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
diff --git a/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp b/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp
index af65fb530a..5cd6061542 100644
--- a/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp
@@ -6,9 +6,9 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_textstatedata.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
CPDF_TextStateData::CPDF_TextStateData()
: m_pFont(nullptr),
diff --git a/core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp b/core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp
new file mode 100644
index 0000000000..f49ad2b8fb
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp
@@ -0,0 +1,51 @@
+// 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_page/cpdf_tilingpattern.h"
+
+#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_object.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+
+CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc,
+ CPDF_Object* pPatternObj,
+ const CFX_Matrix* parentMatrix)
+ : CPDF_Pattern(TILING, pDoc, pPatternObj, parentMatrix) {
+ CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
+ m_Pattern2Form = pDict->GetMatrixBy("Matrix");
+ m_bColored = pDict->GetIntegerBy("PaintType") == 1;
+ if (parentMatrix)
+ m_Pattern2Form.Concat(*parentMatrix);
+
+ m_pForm = nullptr;
+}
+
+CPDF_TilingPattern::~CPDF_TilingPattern() {
+ delete m_pForm;
+}
+
+FX_BOOL CPDF_TilingPattern::Load() {
+ if (m_pForm)
+ return TRUE;
+
+ CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
+ if (!pDict)
+ return FALSE;
+
+ m_bColored = pDict->GetIntegerBy("PaintType") == 1;
+ m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberBy("XStep"));
+ m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberBy("YStep"));
+
+ CPDF_Stream* pStream = m_pPatternObj->AsStream();
+ if (!pStream)
+ return FALSE;
+
+ m_pForm = new CPDF_Form(m_pDocument, NULL, pStream);
+ m_pForm->ParseContent(NULL, &m_ParentMatrix, NULL, NULL);
+ m_BBox = pDict->GetRectBy("BBox");
+ return TRUE;
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_tilingpattern.h b/core/fpdfapi/fpdf_page/cpdf_tilingpattern.h
new file mode 100644
index 0000000000..44446eac91
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_tilingpattern.h
@@ -0,0 +1,34 @@
+// 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_PAGE_CPDF_TILINGPATTERN_H_
+#define CORE_FPDFAPI_FPDF_PAGE_CPDF_TILINGPATTERN_H_
+
+#include "core/fpdfapi/fpdf_page/cpdf_pattern.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_Document;
+class CPDF_Form;
+class CPDF_Object;
+
+class CPDF_TilingPattern : public CPDF_Pattern {
+ public:
+ CPDF_TilingPattern(CPDF_Document* pDoc,
+ CPDF_Object* pPatternObj,
+ const CFX_Matrix* parentMatrix);
+ ~CPDF_TilingPattern() override;
+
+ FX_BOOL Load();
+
+ FX_BOOL m_bColored;
+ CFX_FloatRect m_BBox;
+ FX_FLOAT m_XStep;
+ FX_FLOAT m_YStep;
+ CPDF_Form* m_pForm;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_TILINGPATTERN_H_
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp
index d4b69f2d3f..cc40976f29 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp
@@ -13,12 +13,24 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/include/fxcodec/fx_codec.h"
namespace {
+FX_DWORD ComponentsForFamily(int family) {
+ if (family == PDFCS_DEVICERGB)
+ return 3;
+ if (family == PDFCS_DEVICEGRAY)
+ return 1;
+ return 4;
+}
+
+} // namespace
+
void sRGB_to_AdobeCMYK(FX_FLOAT R,
FX_FLOAT G,
FX_FLOAT B,
@@ -38,14 +50,6 @@ void sRGB_to_AdobeCMYK(FX_FLOAT R,
}
}
-FX_DWORD ComponentsForFamily(int family) {
- if (family == PDFCS_DEVICERGB)
- return 3;
- if (family == PDFCS_DEVICEGRAY)
- return 1;
- return 4;
-}
-
void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) {
if (pDestBuf == pSrcBuf) {
for (int i = 0; i < pixels; i++) {
@@ -64,8 +68,6 @@ void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) {
}
}
-} // namespace
-
CPDF_DeviceCS::CPDF_DeviceCS(CPDF_Document* pDoc, int family)
: CPDF_ColorSpace(pDoc, family, ComponentsForFamily(family)) {}
@@ -213,420 +215,7 @@ void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf,
}
}
}
-const uint8_t g_sRGBSamples1[] = {
- 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31,
- 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58,
- 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68,
- 68, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76,
- 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83,
- 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90,
- 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96,
- 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 101, 101, 101,
- 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 106, 106, 106, 107,
- 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 110, 111, 111, 111,
- 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116,
- 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120,
-};
-const uint8_t g_sRGBSamples2[] = {
- 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
- 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149,
- 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162,
- 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173,
- 174, 175, 175, 176, 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184,
- 185, 185, 186, 187, 187, 188, 189, 189, 190, 190, 191, 192, 192, 193, 194,
- 194, 195, 196, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, 203,
- 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 209, 210, 210, 211, 212,
- 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 218, 218, 219, 219, 220,
- 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228,
- 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235,
- 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242,
- 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 249, 249,
- 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
-};
-
-static FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) {
- if (colorComponent > 1) {
- colorComponent = 1;
- }
- if (colorComponent < 0) {
- colorComponent = 0;
- }
- int scale = (int)(colorComponent * 1023);
- if (scale < 0) {
- scale = 0;
- }
- if (scale < 192) {
- colorComponent = (g_sRGBSamples1[scale] / 255.0f);
- } else {
- colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f);
- }
- return colorComponent;
-}
-
-static void XYZ_to_sRGB(FX_FLOAT X,
- FX_FLOAT Y,
- FX_FLOAT Z,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) {
- FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z;
- FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z;
- FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z;
-
- R = RGB_Conversion(R1);
- G = RGB_Conversion(G1);
- B = RGB_Conversion(B1);
-}
-
-static void XYZ_to_sRGB_WhitePoint(FX_FLOAT X,
- FX_FLOAT Y,
- FX_FLOAT Z,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B,
- FX_FLOAT Xw,
- FX_FLOAT Yw,
- FX_FLOAT Zw) {
- // The following RGB_xyz is based on
- // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06}
-
- FX_FLOAT Rx = 0.64f, Ry = 0.33f;
- FX_FLOAT Gx = 0.30f, Gy = 0.60f;
- FX_FLOAT Bx = 0.15f, By = 0.06f;
- CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy,
- 1 - Bx - By);
- CFX_Vector_3by1 whitePoint(Xw, Yw, Zw);
- CFX_Vector_3by1 XYZ(X, Y, Z);
-
- CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint);
- CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0,
- 0, RGB_Sum_XYZ.c);
- CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG);
- CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ);
-
- R = RGB_Conversion(RGB.a);
- G = RGB_Conversion(RGB.b);
- B = RGB_Conversion(RGB.c);
-}
-class CPDF_CalGray : public CPDF_ColorSpace {
- public:
- explicit CPDF_CalGray(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {}
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- FX_BOOL SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const override;
- void TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask = FALSE) const override;
- private:
- FX_FLOAT m_WhitePoint[3];
- FX_FLOAT m_BlackPoint[3];
- FX_FLOAT m_Gamma;
-};
-
-FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Dictionary* pDict = pArray->GetDictAt(1);
- if (!pDict)
- return FALSE;
-
- CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
- int i;
- for (i = 0; i < 3; i++) {
- m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
- }
- pParam = pDict->GetArrayBy("BlackPoint");
- for (i = 0; i < 3; i++) {
- m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
- }
- m_Gamma = pDict->GetNumberBy("Gamma");
- if (m_Gamma == 0) {
- m_Gamma = 1.0f;
- }
- return TRUE;
-}
-FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- R = G = B = *pBuf;
- return TRUE;
-}
-FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const {
- if (R == G && R == B) {
- *pBuf = R;
- return TRUE;
- }
- return FALSE;
-}
-void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask) const {
- for (int i = 0; i < pixels; i++) {
- *pDestBuf++ = pSrcBuf[i];
- *pDestBuf++ = pSrcBuf[i];
- *pDestBuf++ = pSrcBuf[i];
- }
-}
-class CPDF_CalRGB : public CPDF_ColorSpace {
- public:
- explicit CPDF_CalRGB(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {}
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- FX_BOOL SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const override;
- void TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask = FALSE) const override;
-
- FX_FLOAT m_WhitePoint[3];
- FX_FLOAT m_BlackPoint[3];
- FX_FLOAT m_Gamma[3];
- FX_FLOAT m_Matrix[9];
- FX_BOOL m_bGamma;
- FX_BOOL m_bMatrix;
-};
-FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Dictionary* pDict = pArray->GetDictAt(1);
- if (!pDict)
- return FALSE;
-
- CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
- int i;
- for (i = 0; i < 3; i++) {
- m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
- }
- pParam = pDict->GetArrayBy("BlackPoint");
- for (i = 0; i < 3; i++) {
- m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
- }
- pParam = pDict->GetArrayBy("Gamma");
- if (pParam) {
- m_bGamma = TRUE;
- for (i = 0; i < 3; i++) {
- m_Gamma[i] = pParam->GetNumberAt(i);
- }
- } else {
- m_bGamma = FALSE;
- }
- pParam = pDict->GetArrayBy("Matrix");
- if (pParam) {
- m_bMatrix = TRUE;
- for (i = 0; i < 9; i++) {
- m_Matrix[i] = pParam->GetNumberAt(i);
- }
- } else {
- m_bMatrix = FALSE;
- }
- return TRUE;
-}
-FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- FX_FLOAT A_ = pBuf[0];
- FX_FLOAT B_ = pBuf[1];
- FX_FLOAT C_ = pBuf[2];
- if (m_bGamma) {
- A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]);
- B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]);
- C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]);
- }
- FX_FLOAT X, Y, Z;
- if (m_bMatrix) {
- X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_;
- Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_;
- Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_;
- } else {
- X = A_;
- Y = B_;
- Z = C_;
- }
- XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1],
- m_WhitePoint[2]);
- return TRUE;
-}
-FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const {
- pBuf[0] = R;
- pBuf[1] = G;
- pBuf[2] = B;
- return TRUE;
-}
-void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask) const {
- if (bTransMask) {
- FX_FLOAT Cal[3];
- FX_FLOAT R, G, B;
- for (int i = 0; i < pixels; i++) {
- Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255;
- Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255;
- Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255;
- GetRGB(Cal, R, G, B);
- pDestBuf[0] = FXSYS_round(B * 255);
- pDestBuf[1] = FXSYS_round(G * 255);
- pDestBuf[2] = FXSYS_round(R * 255);
- pSrcBuf += 3;
- pDestBuf += 3;
- }
- }
- ReverseRGB(pDestBuf, pSrcBuf, pixels);
-}
-class CPDF_LabCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_LabCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {}
- void GetDefaultValue(int iComponent,
- FX_FLOAT& value,
- FX_FLOAT& min,
- FX_FLOAT& max) const override;
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- FX_BOOL SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const override;
- void TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask = FALSE) const override;
-
- FX_FLOAT m_WhitePoint[3];
- FX_FLOAT m_BlackPoint[3];
- FX_FLOAT m_Ranges[4];
-};
-FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Dictionary* pDict = pArray->GetDictAt(1);
- if (!pDict) {
- return FALSE;
- }
- CPDF_Array* pParam = pDict->GetArrayBy("WhitePoint");
- int i;
- for (i = 0; i < 3; i++) {
- m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
- }
- pParam = pDict->GetArrayBy("BlackPoint");
- for (i = 0; i < 3; i++) {
- m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0;
- }
- pParam = pDict->GetArrayBy("Range");
- const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f,
- 100 * 1.0f};
- for (i = 0; i < 4; i++) {
- m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i];
- }
- return TRUE;
-}
-void CPDF_LabCS::GetDefaultValue(int iComponent,
- FX_FLOAT& value,
- FX_FLOAT& min,
- FX_FLOAT& max) const {
- assert(iComponent < 3);
- value = 0;
- if (iComponent == 0) {
- min = 0;
- max = 100 * 1.0f;
- } else {
- min = m_Ranges[iComponent * 2 - 2];
- max = m_Ranges[iComponent * 2 - 1];
- if (value < min) {
- value = min;
- } else if (value > max) {
- value = max;
- }
- }
-}
-FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- FX_FLOAT Lstar = pBuf[0];
- FX_FLOAT astar = pBuf[1];
- FX_FLOAT bstar = pBuf[2];
- FX_FLOAT M = (Lstar + 16.0f) / 116.0f;
- FX_FLOAT L = M + astar / 500.0f;
- FX_FLOAT N = M - bstar / 200.0f;
- FX_FLOAT X, Y, Z;
- if (L < 0.2069f) {
- X = 0.957f * 0.12842f * (L - 0.1379f);
- } else {
- X = 0.957f * L * L * L;
- }
- if (M < 0.2069f) {
- Y = 0.12842f * (M - 0.1379f);
- } else {
- Y = M * M * M;
- }
- if (N < 0.2069f) {
- Z = 1.0889f * 0.12842f * (N - 0.1379f);
- } else {
- Z = 1.0889f * N * N * N;
- }
- XYZ_to_sRGB(X, Y, Z, R, G, B);
- return TRUE;
-}
-FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const {
- return FALSE;
-}
-void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask) const {
- for (int i = 0; i < pixels; i++) {
- FX_FLOAT lab[3];
- FX_FLOAT R, G, B;
- lab[0] = (pSrcBuf[0] * 100 / 255.0f);
- lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128);
- lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128);
- GetRGB(lab, R, G, B);
- pDestBuf[0] = (int32_t)(B * 255);
- pDestBuf[1] = (int32_t)(G * 255);
- pDestBuf[2] = (int32_t)(R * 255);
- pDestBuf += 3;
- pSrcBuf += 3;
- }
-}
CPDF_IccProfile::CPDF_IccProfile(const uint8_t* pData, FX_DWORD dwSize)
: m_bsRGB(FALSE), m_pTransform(NULL), m_nSrcComponents(0) {
if (dwSize == 3144 &&
@@ -643,907 +232,4 @@ CPDF_IccProfile::~CPDF_IccProfile() {
CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform);
}
}
-class CPDF_ICCBasedCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_ICCBasedCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0),
- m_pAlterCS(nullptr),
- m_pProfile(nullptr),
- m_pCache(nullptr),
- m_pRanges(nullptr),
- m_bOwn(FALSE) {}
- ~CPDF_ICCBasedCS() override;
-
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- FX_BOOL SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const override;
- FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
- FX_FLOAT& c,
- FX_FLOAT& m,
- FX_FLOAT& y,
- FX_FLOAT& k) const override;
- void EnableStdConversion(FX_BOOL bEnabled) override;
- void TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask = FALSE) const override;
-
- CPDF_ColorSpace* m_pAlterCS;
- CPDF_IccProfile* m_pProfile;
- uint8_t* m_pCache;
- FX_FLOAT* m_pRanges;
- FX_BOOL m_bOwn;
-};
-
-CPDF_ICCBasedCS::~CPDF_ICCBasedCS() {
- FX_Free(m_pCache);
- FX_Free(m_pRanges);
- if (m_pAlterCS && m_bOwn) {
- m_pAlterCS->ReleaseCS();
- }
- if (m_pProfile && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile);
- }
-}
-
-FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Stream* pStream = pArray->GetStreamAt(1);
- if (!pStream) {
- return FALSE;
- }
- m_pProfile = pDoc->LoadIccProfile(pStream);
- if (!m_pProfile) {
- return FALSE;
- }
- m_nComponents =
- m_pProfile
- ->GetComponents(); // Try using the nComponents from ICC profile
- CPDF_Dictionary* pDict = pStream->GetDict();
- if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB
- CPDF_Object* pAlterCSObj =
- pDict ? pDict->GetElementValue("Alternate") : NULL;
- if (pAlterCSObj) {
- CPDF_ColorSpace* pAlterCS = CPDF_ColorSpace::Load(pDoc, pAlterCSObj);
- if (pAlterCS) {
- if (m_nComponents == 0) { // NO valid ICC profile
- if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace
- m_nComponents = pAlterCS->CountComponents();
- m_pAlterCS = pAlterCS;
- m_bOwn = TRUE;
- } else { // No valid alternative colorspace
- pAlterCS->ReleaseCS();
- int32_t nDictComponents = pDict ? pDict->GetIntegerBy("N") : 0;
- if (nDictComponents != 1 && nDictComponents != 3 &&
- nDictComponents != 4) {
- return FALSE;
- }
- m_nComponents = nDictComponents;
- }
-
- } else { // Using sRGB
- if (pAlterCS->CountComponents() != m_nComponents) {
- pAlterCS->ReleaseCS();
- } else {
- m_pAlterCS = pAlterCS;
- m_bOwn = TRUE;
- }
- }
- }
- }
- if (!m_pAlterCS) {
- if (m_nComponents == 1) {
- m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY);
- } else if (m_nComponents == 3) {
- m_pAlterCS = GetStockCS(PDFCS_DEVICERGB);
- } else if (m_nComponents == 4) {
- m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK);
- }
- }
- }
- CPDF_Array* pRanges = pDict->GetArrayBy("Range");
- m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2);
- for (int i = 0; i < m_nComponents * 2; i++) {
- if (pRanges) {
- m_pRanges[i] = pRanges->GetNumberAt(i);
- } else if (i % 2) {
- m_pRanges[i] = 1.0f;
- } else {
- m_pRanges[i] = 0;
- }
- }
- return TRUE;
-}
-FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- if (m_pProfile && m_pProfile->m_bsRGB) {
- R = pBuf[0];
- G = pBuf[1];
- B = pBuf[2];
- return TRUE;
- }
- ICodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule();
- if (!m_pProfile->m_pTransform || !pIccModule) {
- if (m_pAlterCS) {
- return m_pAlterCS->GetRGB(pBuf, R, G, B);
- }
- R = G = B = 0.0f;
- return TRUE;
- }
- FX_FLOAT rgb[3];
- pIccModule->SetComponents(m_nComponents);
- pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb);
- R = rgb[0];
- G = rgb[1];
- B = rgb[2];
- return TRUE;
-}
-FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf,
- FX_FLOAT& c,
- FX_FLOAT& m,
- FX_FLOAT& y,
- FX_FLOAT& k) const {
- if (m_nComponents != 4) {
- return FALSE;
- }
- c = pBuf[0];
- m = pBuf[1];
- y = pBuf[2];
- k = pBuf[3];
- return TRUE;
-}
-FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf,
- FX_FLOAT R,
- FX_FLOAT G,
- FX_FLOAT B) const {
- return FALSE;
-}
-void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAlterCS) {
- m_pAlterCS->EnableStdConversion(bEnabled);
- }
-}
-void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf,
- const uint8_t* pSrcBuf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask) const {
- if (m_pProfile->m_bsRGB) {
- ReverseRGB(pDestBuf, pSrcBuf, pixels);
- } else if (m_pProfile->m_pTransform) {
- int nMaxColors = 1;
- for (int i = 0; i < m_nComponents; i++) {
- nMaxColors *= 52;
- }
- if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) {
- CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
- m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels);
- } else {
- if (!m_pCache) {
- ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3);
- uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents);
- uint8_t* pSrc = temp_src;
- for (int i = 0; i < nMaxColors; i++) {
- FX_DWORD color = i;
- FX_DWORD order = nMaxColors / 52;
- for (int c = 0; c < m_nComponents; c++) {
- *pSrc++ = (uint8_t)(color / order * 5);
- color %= order;
- order /= 52;
- }
- }
- CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline(
- m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors);
- FX_Free(temp_src);
- }
- for (int i = 0; i < pixels; i++) {
- int index = 0;
- for (int c = 0; c < m_nComponents; c++) {
- index = index * 52 + (*pSrcBuf) / 5;
- pSrcBuf++;
- }
- index *= 3;
- *pDestBuf++ = m_pCache[index];
- *pDestBuf++ = m_pCache[index + 1];
- *pDestBuf++ = m_pCache[index + 2];
- }
- }
- } else if (m_pAlterCS) {
- m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width,
- image_height);
- }
-}
-class CPDF_IndexedCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_IndexedCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1),
- m_pBaseCS(nullptr),
- m_pCountedBaseCS(nullptr),
- m_pCompMinMax(nullptr) {}
- ~CPDF_IndexedCS() override;
-
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- CPDF_ColorSpace* GetBaseCS() const override;
- void EnableStdConversion(FX_BOOL bEnabled) override;
-
- CPDF_ColorSpace* m_pBaseCS;
- CPDF_CountedColorSpace* m_pCountedBaseCS;
- int m_nBaseComponents;
- int m_MaxIndex;
- CFX_ByteString m_Table;
- FX_FLOAT* m_pCompMinMax;
-};
-CPDF_IndexedCS::~CPDF_IndexedCS() {
- FX_Free(m_pCompMinMax);
- CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
- if (pCS && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
- }
-}
-FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- if (pArray->GetCount() < 4) {
- return FALSE;
- }
- CPDF_Object* pBaseObj = pArray->GetElementValue(1);
- if (pBaseObj == m_pArray) {
- return FALSE;
- }
- CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
- m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, NULL);
- if (!m_pBaseCS) {
- return FALSE;
- }
- m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
- m_nBaseComponents = m_pBaseCS->CountComponents();
- m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2);
- FX_FLOAT defvalue;
- for (int i = 0; i < m_nBaseComponents; i++) {
- m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2],
- m_pCompMinMax[i * 2 + 1]);
- m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2];
- }
- m_MaxIndex = pArray->GetIntegerAt(2);
-
- CPDF_Object* pTableObj = pArray->GetElementValue(3);
- if (!pTableObj)
- return FALSE;
-
- if (CPDF_String* pString = pTableObj->AsString()) {
- m_Table = pString->GetString();
- } else if (CPDF_Stream* pStream = pTableObj->AsStream()) {
- CPDF_StreamAcc acc;
- acc.LoadAllData(pStream, FALSE);
- m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize());
- }
- return TRUE;
-}
-
-FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- int index = (int32_t)(*pBuf);
- if (index < 0 || index > m_MaxIndex) {
- return FALSE;
- }
- if (m_nBaseComponents) {
- if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents ||
- (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) {
- R = G = B = 0;
- return FALSE;
- }
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> Comps(m_nBaseComponents);
- FX_FLOAT* comps = Comps;
- const uint8_t* pTable = m_Table;
- for (int i = 0; i < m_nBaseComponents; i++) {
- comps[i] =
- m_pCompMinMax[i * 2] +
- m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255;
- }
- return m_pBaseCS->GetRGB(comps, R, G, B);
-}
-CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const {
- return m_pBaseCS;
-}
-void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pBaseCS) {
- m_pBaseCS->EnableStdConversion(bEnabled);
- }
-}
-
-#define MAX_PATTERN_COLORCOMPS 16
-struct PatternValue {
- CPDF_Pattern* m_pPattern;
- CPDF_CountedPattern* m_pCountedPattern;
- int m_nComps;
- FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
-};
-CPDF_PatternCS::~CPDF_PatternCS() {
- CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : NULL;
- if (pCS && m_pDocument) {
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
- }
-}
-FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Object* pBaseCS = pArray->GetElementValue(1);
- if (pBaseCS == m_pArray) {
- return FALSE;
- }
- CPDF_DocPageData* pDocPageData = pDoc->GetPageData();
- m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, NULL);
- if (m_pBaseCS) {
- if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) {
- return FALSE;
- }
- m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray());
- m_nComponents = m_pBaseCS->CountComponents() + 1;
- if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) {
- return FALSE;
- }
- } else {
- m_nComponents = 1;
- }
- return TRUE;
-}
-FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- if (m_pBaseCS) {
- ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN);
- PatternValue* pvalue = (PatternValue*)pBuf;
- if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) {
- return TRUE;
- }
- }
- R = G = B = 0.75f;
- return FALSE;
-}
-CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const {
- return m_pBaseCS;
-}
-class CPDF_SeparationCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_SeparationCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1),
- m_pAltCS(nullptr),
- m_pFunc(nullptr) {}
- ~CPDF_SeparationCS() override;
-
- // CPDF_ColorSpace:
- void GetDefaultValue(int iComponent,
- FX_FLOAT& value,
- FX_FLOAT& min,
- FX_FLOAT& max) const override;
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- void EnableStdConversion(FX_BOOL bEnabled) override;
-
- CPDF_ColorSpace* m_pAltCS;
- CPDF_Function* m_pFunc;
- enum { None, All, Colorant } m_Type;
-};
-CPDF_SeparationCS::~CPDF_SeparationCS() {
- if (m_pAltCS) {
- m_pAltCS->ReleaseCS();
- }
- delete m_pFunc;
-}
-void CPDF_SeparationCS::GetDefaultValue(int iComponent,
- FX_FLOAT& value,
- FX_FLOAT& min,
- FX_FLOAT& max) const {
- value = 1.0f;
- min = 0;
- max = 1.0f;
-}
-FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CFX_ByteString name = pArray->GetStringAt(1);
- if (name == "None") {
- m_Type = None;
- } else {
- m_Type = Colorant;
- CPDF_Object* pAltCS = pArray->GetElementValue(2);
- if (pAltCS == m_pArray) {
- return FALSE;
- }
- m_pAltCS = Load(pDoc, pAltCS);
- if (!m_pAltCS) {
- return FALSE;
- }
- CPDF_Object* pFuncObj = pArray->GetElementValue(3);
- if (pFuncObj && !pFuncObj->IsName())
- m_pFunc = CPDF_Function::Load(pFuncObj);
-
- if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
- delete m_pFunc;
- m_pFunc = NULL;
- }
- }
- return TRUE;
-}
-FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- if (m_Type == None) {
- return FALSE;
- }
- if (!m_pFunc) {
- if (!m_pAltCS) {
- return FALSE;
- }
- int nComps = m_pAltCS->CountComponents();
- CFX_FixedBufGrow<FX_FLOAT, 16> results(nComps);
- for (int i = 0; i < nComps; i++) {
- results[i] = *pBuf;
- }
- return m_pAltCS->GetRGB(results, R, G, B);
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
- int nresults = 0;
- m_pFunc->Call(pBuf, 1, results, nresults);
- if (nresults == 0) {
- return FALSE;
- }
- if (m_pAltCS) {
- return m_pAltCS->GetRGB(results, R, G, B);
- }
- R = G = B = 0;
- return FALSE;
-}
-void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAltCS) {
- m_pAltCS->EnableStdConversion(bEnabled);
- }
-}
-class CPDF_DeviceNCS : public CPDF_ColorSpace {
- public:
- explicit CPDF_DeviceNCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0),
- m_pAltCS(nullptr),
- m_pFunc(nullptr) {}
- ~CPDF_DeviceNCS() override;
-
- // CPDF_ColorSpace:
- void GetDefaultValue(int iComponent,
- FX_FLOAT& value,
- FX_FLOAT& min,
- FX_FLOAT& max) const override;
- FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
- FX_BOOL GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const override;
- void EnableStdConversion(FX_BOOL bEnabled) override;
-
- CPDF_ColorSpace* m_pAltCS;
- CPDF_Function* m_pFunc;
-};
-CPDF_DeviceNCS::~CPDF_DeviceNCS() {
- delete m_pFunc;
- if (m_pAltCS) {
- m_pAltCS->ReleaseCS();
- }
-}
-void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
- FX_FLOAT& value,
- FX_FLOAT& min,
- FX_FLOAT& max) const {
- value = 1.0f;
- min = 0;
- max = 1.0f;
-}
-FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
- CPDF_Array* pObj = ToArray(pArray->GetElementValue(1));
- if (!pObj)
- return FALSE;
-
- m_nComponents = pObj->GetCount();
- CPDF_Object* pAltCS = pArray->GetElementValue(2);
- if (!pAltCS || pAltCS == m_pArray) {
- return FALSE;
- }
- m_pAltCS = Load(pDoc, pAltCS);
- m_pFunc = CPDF_Function::Load(pArray->GetElementValue(3));
- if (!m_pAltCS || !m_pFunc) {
- return FALSE;
- }
- if (m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) {
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf,
- FX_FLOAT& R,
- FX_FLOAT& G,
- FX_FLOAT& B) const {
- if (!m_pFunc) {
- return FALSE;
- }
- CFX_FixedBufGrow<FX_FLOAT, 16> results(m_pFunc->CountOutputs());
- int nresults = 0;
- m_pFunc->Call(pBuf, m_nComponents, results, nresults);
- if (nresults == 0) {
- return FALSE;
- }
- return m_pAltCS->GetRGB(results, R, G, B);
-}
-void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) {
- CPDF_ColorSpace::EnableStdConversion(bEnabled);
- if (m_pAltCS) {
- m_pAltCS->EnableStdConversion(bEnabled);
- }
-}
-
-CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) {
- return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family);
-}
-
-CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name) {
- if (name == "DeviceRGB" || name == "RGB") {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
- }
- if (name == "DeviceGray" || name == "G") {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY);
- }
- if (name == "DeviceCMYK" || name == "CMYK") {
- return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK);
- }
- if (name == "Pattern") {
- return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
- }
- return NULL;
-}
-CPDF_ColorSpace* CPDF_ColorSpace::Load(CPDF_Document* pDoc, CPDF_Object* pObj) {
- if (!pObj)
- return nullptr;
- if (pObj->IsName())
- return _CSFromName(pObj->GetString());
-
- if (CPDF_Stream* pStream = pObj->AsStream()) {
- CPDF_Dictionary* pDict = pStream->GetDict();
- if (!pDict)
- return nullptr;
-
- for (const auto& it : *pDict) {
- CPDF_ColorSpace* pRet = nullptr;
- CPDF_Object* pValue = it.second;
- if (ToName(pValue))
- pRet = _CSFromName(pValue->GetString());
- if (pRet)
- return pRet;
- }
- return nullptr;
- }
-
- CPDF_Array* pArray = pObj->AsArray();
- if (!pArray || pArray->GetCount() == 0)
- return nullptr;
-
- CPDF_Object* pFamilyObj = pArray->GetElementValue(0);
- if (!pFamilyObj)
- return nullptr;
-
- CFX_ByteString familyname = pFamilyObj->GetString();
- if (pArray->GetCount() == 1)
- return _CSFromName(familyname);
-
- CPDF_ColorSpace* pCS = NULL;
- FX_DWORD id = familyname.GetID();
- if (id == FXBSTR_ID('C', 'a', 'l', 'G')) {
- pCS = new CPDF_CalGray(pDoc);
- } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) {
- pCS = new CPDF_CalRGB(pDoc);
- } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) {
- pCS = new CPDF_LabCS(pDoc);
- } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) {
- pCS = new CPDF_ICCBasedCS(pDoc);
- } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') ||
- id == FXBSTR_ID('I', 0, 0, 0)) {
- pCS = new CPDF_IndexedCS(pDoc);
- } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) {
- pCS = new CPDF_SeparationCS(pDoc);
- } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) {
- pCS = new CPDF_DeviceNCS(pDoc);
- } else if (id == FXBSTR_ID('P', 'a', 't', 't')) {
- pCS = new CPDF_PatternCS(pDoc);
- } else {
- return NULL;
- }
- pCS->m_pArray = pArray;
- if (!pCS->v_Load(pDoc, pArray)) {
- pCS->ReleaseCS();
- return NULL;
- }
- return pCS;
-}
-void CPDF_ColorSpace::ReleaseCS() {
- if (this == GetStockCS(PDFCS_DEVICERGB)) {
- return;
- }
- if (this == GetStockCS(PDFCS_DEVICEGRAY)) {
- return;
- }
- if (this == GetStockCS(PDFCS_DEVICECMYK)) {
- return;
- }
- if (this == GetStockCS(PDFCS_PATTERN)) {
- return;
- }
- delete this;
-}
-int CPDF_ColorSpace::GetBufSize() const {
- if (m_Family == PDFCS_PATTERN) {
- return sizeof(PatternValue);
- }
- return m_nComponents * sizeof(FX_FLOAT);
-}
-FX_FLOAT* CPDF_ColorSpace::CreateBuf() {
- int size = GetBufSize();
- uint8_t* pBuf = FX_Alloc(uint8_t, size);
- return (FX_FLOAT*)pBuf;
-}
-FX_BOOL CPDF_ColorSpace::sRGB() const {
- if (m_Family == PDFCS_DEVICERGB) {
- return TRUE;
- }
- if (m_Family != PDFCS_ICCBASED) {
- return FALSE;
- }
- CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this;
- return pCS->m_pProfile->m_bsRGB;
-}
-FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf,
- FX_FLOAT& c,
- FX_FLOAT& m,
- FX_FLOAT& y,
- FX_FLOAT& k) const {
- if (v_GetCMYK(pBuf, c, m, y, k)) {
- return TRUE;
- }
- FX_FLOAT R, G, B;
- if (!GetRGB(pBuf, R, G, B)) {
- return FALSE;
- }
- sRGB_to_AdobeCMYK(R, G, B, c, m, y, k);
- return TRUE;
-}
-FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf,
- FX_FLOAT c,
- FX_FLOAT m,
- FX_FLOAT y,
- FX_FLOAT k) const {
- if (v_SetCMYK(pBuf, c, m, y, k)) {
- return TRUE;
- }
- FX_FLOAT R, G, B;
- AdobeCMYK_to_sRGB(c, m, y, k, R, G, B);
- return SetRGB(pBuf, R, G, B);
-}
-void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const {
- if (!buf || m_Family == PDFCS_PATTERN) {
- return;
- }
- FX_FLOAT min, max;
- for (int i = 0; i < m_nComponents; i++) {
- GetDefaultValue(i, buf[i], min, max);
- }
-}
-int CPDF_ColorSpace::GetMaxIndex() const {
- if (m_Family != PDFCS_INDEXED) {
- return 0;
- }
- CPDF_IndexedCS* pCS = (CPDF_IndexedCS*)this;
- return pCS->m_MaxIndex;
-}
-void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf,
- const uint8_t* src_buf,
- int pixels,
- int image_width,
- int image_height,
- FX_BOOL bTransMask) const {
- CFX_FixedBufGrow<FX_FLOAT, 16> srcbuf(m_nComponents);
- FX_FLOAT* src = srcbuf;
- FX_FLOAT R, G, B;
- for (int i = 0; i < pixels; i++) {
- for (int j = 0; j < m_nComponents; j++)
- if (m_Family == PDFCS_INDEXED) {
- src[j] = (FX_FLOAT)(*src_buf++);
- } else {
- src[j] = (FX_FLOAT)(*src_buf++) / 255;
- }
- GetRGB(src, R, G, B);
- *dest_buf++ = (int32_t)(B * 255);
- *dest_buf++ = (int32_t)(G * 255);
- *dest_buf++ = (int32_t)(R * 255);
- }
-}
-void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) {
- if (bEnabled) {
- m_dwStdConversion++;
- } else if (m_dwStdConversion) {
- m_dwStdConversion--;
- }
-}
-CPDF_Color::CPDF_Color(int family) {
- m_pCS = CPDF_ColorSpace::GetStockCS(family);
- int nComps = 3;
- if (family == PDFCS_DEVICEGRAY) {
- nComps = 1;
- } else if (family == PDFCS_DEVICECMYK) {
- nComps = 4;
- }
- m_pBuffer = FX_Alloc(FX_FLOAT, nComps);
- for (int i = 0; i < nComps; i++) {
- m_pBuffer[i] = 0;
- }
-}
-CPDF_Color::~CPDF_Color() {
- ReleaseBuffer();
- ReleaseColorSpace();
-}
-void CPDF_Color::ReleaseBuffer() {
- if (!m_pBuffer) {
- return;
- }
- if (m_pCS->GetFamily() == PDFCS_PATTERN) {
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- CPDF_Pattern* pPattern =
- pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : NULL;
- if (pPattern && pPattern->m_pDocument) {
- CPDF_DocPageData* pPageData = pPattern->m_pDocument->GetPageData();
- if (pPageData) {
- pPageData->ReleasePattern(pPattern->m_pPatternObj);
- }
- }
- }
- FX_Free(m_pBuffer);
- m_pBuffer = NULL;
-}
-void CPDF_Color::ReleaseColorSpace() {
- if (m_pCS && m_pCS->m_pDocument && m_pCS->GetArray()) {
- m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray());
- m_pCS = NULL;
- }
-}
-void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) {
- if (m_pCS == pCS) {
- if (!m_pBuffer) {
- m_pBuffer = pCS->CreateBuf();
- }
- ReleaseColorSpace();
- m_pCS = pCS;
- return;
- }
- ReleaseBuffer();
- ReleaseColorSpace();
- m_pCS = pCS;
- if (m_pCS) {
- m_pBuffer = pCS->CreateBuf();
- pCS->GetDefaultColor(m_pBuffer);
- }
-}
-void CPDF_Color::SetValue(FX_FLOAT* comps) {
- if (!m_pBuffer) {
- return;
- }
- if (m_pCS->GetFamily() != PDFCS_PATTERN) {
- FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT));
- }
-}
-void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) {
- if (ncomps > MAX_PATTERN_COLORCOMPS) {
- return;
- }
- if (!m_pCS || m_pCS->GetFamily() != PDFCS_PATTERN) {
- FX_Free(m_pBuffer);
- m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN);
- m_pBuffer = m_pCS->CreateBuf();
- }
- CPDF_DocPageData* pDocPageData = NULL;
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
- pDocPageData = pvalue->m_pPattern->m_pDocument->GetPageData();
- if (pDocPageData) {
- pDocPageData->ReleasePattern(pvalue->m_pPattern->m_pPatternObj);
- }
- }
- pvalue->m_nComps = ncomps;
- pvalue->m_pPattern = pPattern;
- if (ncomps) {
- FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT));
- }
- pvalue->m_pCountedPattern = NULL;
- if (pPattern && pPattern->m_pDocument) {
- if (!pDocPageData) {
- pDocPageData = pPattern->m_pDocument->GetPageData();
- }
- pvalue->m_pCountedPattern =
- pDocPageData->FindPatternPtr(pPattern->m_pPatternObj);
- }
-}
-void CPDF_Color::Copy(const CPDF_Color* pSrc) {
- ReleaseBuffer();
- ReleaseColorSpace();
- m_pCS = pSrc->m_pCS;
- if (m_pCS && m_pCS->m_pDocument) {
- CPDF_Array* pArray = m_pCS->GetArray();
- if (pArray) {
- m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray);
- }
- }
- if (!m_pCS) {
- return;
- }
- m_pBuffer = m_pCS->CreateBuf();
- FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize());
- if (m_pCS->GetFamily() == PDFCS_PATTERN) {
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- if (pvalue->m_pPattern && pvalue->m_pPattern->m_pDocument) {
- pvalue->m_pPattern =
- pvalue->m_pPattern->m_pDocument->GetPageData()->GetPattern(
- pvalue->m_pPattern->m_pPatternObj, FALSE,
- &pvalue->m_pPattern->m_ParentMatrix);
- }
- }
-}
-FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const {
- if (!m_pCS || !m_pBuffer) {
- return FALSE;
- }
- FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f;
- if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) {
- return FALSE;
- }
- R = (int32_t)(r * 255 + 0.5f);
- G = (int32_t)(g * 255 + 0.5f);
- B = (int32_t)(b * 255 + 0.5f);
- return TRUE;
-}
-CPDF_Pattern* CPDF_Color::GetPattern() const {
- if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) {
- return NULL;
- }
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- return pvalue->m_pPattern;
-}
-CPDF_ColorSpace* CPDF_Color::GetPatternCS() const {
- if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) {
- return NULL;
- }
- return m_pCS->GetBaseCS();
-}
-FX_FLOAT* CPDF_Color::GetPatternColor() const {
- if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) {
- return NULL;
- }
- PatternValue* pvalue = (PatternValue*)m_pBuffer;
- return pvalue->m_nComps ? pvalue->m_Comps : NULL;
-}
-FX_BOOL CPDF_Color::IsEqual(const CPDF_Color& other) const {
- return m_pCS && m_pCS == other.m_pCS &&
- FXSYS_memcmp(m_pBuffer, other.m_pBuffer, m_pCS->GetBufSize()) == 0;
-}
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp
index 0d0c373c56..2e68702127 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp
@@ -7,10 +7,16 @@
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fdrm/crypto/include/fx_crypt.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type1font.h"
#include "core/fpdfapi/fpdf_font/font_int.h"
+#include "core/fpdfapi/fpdf_page/cpdf_pattern.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
+#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fpdfapi/ipdf_pagemodule.h"
@@ -91,7 +97,6 @@ CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) {
return GetValidatePageData()->GetFontFileStreamAcc(pStream);
}
-CPDF_ColorSpace* _CSFromName(const CFX_ByteString& name);
CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj,
CPDF_Dictionary* pResources) {
return GetValidatePageData()->GetColorSpace(pCSObj, pResources);
@@ -322,7 +327,7 @@ CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace(
if (pCSObj->IsName()) {
CFX_ByteString name = pCSObj->GetConstString();
- CPDF_ColorSpace* pCS = _CSFromName(name);
+ CPDF_ColorSpace* pCS = CPDF_ColorSpace::ColorspaceFromName(name);
if (!pCS && pResources) {
CPDF_Dictionary* pList = pResources->GetDictBy("ColorSpace");
if (pList) {
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
index cea7d6b8e7..96aad6d87f 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
@@ -15,6 +15,8 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fxcrt/include/fx_safe_types.h"
#include "third_party/base/numerics/safe_conversions_impl.h"
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_image.cpp b/core/fpdfapi/fpdf_page/fpdf_page_image.cpp
deleted file mode 100644
index f66823657f..0000000000
--- a/core/fpdfapi/fpdf_page/fpdf_page_image.cpp
+++ /dev/null
@@ -1,66 +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_page/pageint.h"
-
-#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
-
-void CPDF_Image::Release() {
- if (m_bInline || (m_pStream && m_pStream->GetObjNum() == 0)) {
- delete this;
- }
-}
-CPDF_Image* CPDF_Image::Clone() {
- if (m_pStream->GetObjNum())
- return m_pDocument->GetPageData()->GetImage(m_pStream);
-
- CPDF_Image* pImage = new CPDF_Image(m_pDocument);
- pImage->LoadImageF(ToStream(m_pStream->Clone()), m_bInline);
- if (m_bInline)
- pImage->SetInlineDict(ToDictionary(m_pInlineDict->Clone(TRUE)));
-
- return pImage;
-}
-CPDF_Image::CPDF_Image(CPDF_Document* pDoc) {
- m_pDocument = pDoc;
- m_pStream = NULL;
- m_pOC = NULL;
- m_bInline = FALSE;
- m_pInlineDict = NULL;
- m_pDIBSource = NULL;
- m_pMask = NULL;
- m_MatteColor = 0;
-}
-CPDF_Image::~CPDF_Image() {
- if (m_bInline) {
- if (m_pStream) {
- m_pStream->Release();
- }
- if (m_pInlineDict) {
- m_pInlineDict->Release();
- }
- }
-}
-FX_BOOL CPDF_Image::LoadImageF(CPDF_Stream* pStream, FX_BOOL bInline) {
- m_pStream = pStream;
- if (m_bInline && m_pInlineDict) {
- m_pInlineDict->Release();
- m_pInlineDict = NULL;
- }
- m_bInline = bInline;
- CPDF_Dictionary* pDict = pStream->GetDict();
- if (m_bInline) {
- m_pInlineDict = ToDictionary(pDict->Clone());
- }
- m_pOC = pDict->GetDictBy("OC");
- m_bIsMask =
- !pDict->KeyExist("ColorSpace") || pDict->GetIntegerBy("ImageMask");
- m_bInterpolate = pDict->GetIntegerBy("Interpolate");
- m_Height = pDict->GetIntegerBy("Height");
- m_Width = pDict->GetIntegerBy("Width");
- return TRUE;
-}
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp
index 700103ed41..63c84bbd22 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp
@@ -9,9 +9,13 @@
#include <vector>
#include "core/fpdfapi/fpdf_edit/include/cpdf_creator.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
#include "core/fpdfapi/fpdf_page/cpdf_allstates.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
@@ -23,6 +27,8 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
namespace {
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
index c0d7c08ee1..04211041fe 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
@@ -8,6 +8,7 @@
#include <limits.h>
+#include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
#include "core/fpdfapi/fpdf_page/cpdf_allstates.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
@@ -21,6 +22,8 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_pattern.cpp b/core/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
index fbb2c28373..822d06d84c 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_pattern.cpp
@@ -8,10 +8,13 @@
#include <algorithm>
+#include "core/fpdfapi/fpdf_page/cpdf_meshstream.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
namespace {
@@ -22,245 +25,9 @@ const int kCoonsCoordinatePairs = 12;
const int kSingleColorPerPatch = 1;
const int kQuadColorsPerPatch = 4;
-ShadingType ToShadingType(int type) {
- return (type > static_cast<int>(kInvalidShading) &&
- type < static_cast<int>(kMaxShading))
- ? static_cast<ShadingType>(type)
- : kInvalidShading;
-}
-
} // namespace
-CPDF_Pattern::CPDF_Pattern(PatternType type,
- CPDF_Document* pDoc,
- CPDF_Object* pObj,
- const CFX_Matrix* pParentMatrix)
- : m_PatternType(type),
- m_pDocument(pDoc),
- m_pPatternObj(pObj),
- m_bForceClear(FALSE) {
- if (pParentMatrix)
- m_ParentMatrix = *pParentMatrix;
-}
-CPDF_Pattern::~CPDF_Pattern() {}
-CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc,
- CPDF_Object* pPatternObj,
- const CFX_Matrix* parentMatrix)
- : CPDF_Pattern(TILING, pDoc, pPatternObj, parentMatrix) {
- CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
- m_Pattern2Form = pDict->GetMatrixBy("Matrix");
- m_bColored = pDict->GetIntegerBy("PaintType") == 1;
- if (parentMatrix) {
- m_Pattern2Form.Concat(*parentMatrix);
- }
- m_pForm = NULL;
-}
-CPDF_TilingPattern::~CPDF_TilingPattern() {
- delete m_pForm;
- m_pForm = NULL;
-}
-FX_BOOL CPDF_TilingPattern::Load() {
- if (m_pForm)
- return TRUE;
-
- CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
- if (!pDict)
- return FALSE;
-
- m_bColored = pDict->GetIntegerBy("PaintType") == 1;
- m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberBy("XStep"));
- m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberBy("YStep"));
-
- CPDF_Stream* pStream = m_pPatternObj->AsStream();
- if (!pStream)
- return FALSE;
-
- m_pForm = new CPDF_Form(m_pDocument, NULL, pStream);
- m_pForm->ParseContent(NULL, &m_ParentMatrix, NULL, NULL);
- m_BBox = pDict->GetRectBy("BBox");
- return TRUE;
-}
-CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc,
- CPDF_Object* pPatternObj,
- FX_BOOL bShading,
- const CFX_Matrix* parentMatrix)
- : CPDF_Pattern(SHADING,
- pDoc,
- bShading ? nullptr : pPatternObj,
- parentMatrix),
- m_ShadingType(kInvalidShading),
- m_bShadingObj(bShading),
- m_pShadingObj(pPatternObj),
- m_pCS(nullptr),
- m_pCountedCS(nullptr),
- m_nFuncs(0) {
- if (!bShading) {
- CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
- m_Pattern2Form = pDict->GetMatrixBy("Matrix");
- m_pShadingObj = pDict->GetElementValue("Shading");
- if (parentMatrix)
- m_Pattern2Form.Concat(*parentMatrix);
- }
- for (int i = 0; i < FX_ArraySize(m_pFunctions); ++i)
- m_pFunctions[i] = nullptr;
-}
-
-CPDF_ShadingPattern::~CPDF_ShadingPattern() {
- for (int i = 0; i < m_nFuncs; ++i)
- delete m_pFunctions[i];
-
- CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->get() : NULL;
- if (pCS && m_pDocument)
- m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
-}
-
-FX_BOOL CPDF_ShadingPattern::Load() {
- if (m_ShadingType != kInvalidShading)
- return TRUE;
-
- CPDF_Dictionary* pShadingDict =
- m_pShadingObj ? m_pShadingObj->GetDict() : NULL;
- if (!pShadingDict) {
- return FALSE;
- }
- if (m_nFuncs) {
- for (int i = 0; i < m_nFuncs; i++)
- delete m_pFunctions[i];
- m_nFuncs = 0;
- }
- CPDF_Object* pFunc = pShadingDict->GetElementValue("Function");
- if (pFunc) {
- if (CPDF_Array* pArray = pFunc->AsArray()) {
- m_nFuncs = std::min<int>(pArray->GetCount(), 4);
- for (int i = 0; i < m_nFuncs; i++) {
- m_pFunctions[i] = CPDF_Function::Load(pArray->GetElementValue(i));
- }
- } else {
- m_pFunctions[0] = CPDF_Function::Load(pFunc);
- m_nFuncs = 1;
- }
- }
- CPDF_Object* pCSObj = pShadingDict->GetElementValue("ColorSpace");
- if (!pCSObj) {
- return FALSE;
- }
- CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
- m_pCS = pDocPageData->GetColorSpace(pCSObj, NULL);
- if (m_pCS) {
- m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray());
- }
-
- m_ShadingType = ToShadingType(pShadingDict->GetIntegerBy("ShadingType"));
-
- // We expect to have a stream if our shading type is a mesh.
- if (IsMeshShading() && !ToStream(m_pShadingObj))
- return FALSE;
-
- return TRUE;
-}
-FX_BOOL CPDF_MeshStream::Load(CPDF_Stream* pShadingStream,
- CPDF_Function** pFuncs,
- int nFuncs,
- CPDF_ColorSpace* pCS) {
- m_Stream.LoadAllData(pShadingStream);
- m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize());
- m_pFuncs = pFuncs;
- m_nFuncs = nFuncs;
- m_pCS = pCS;
- CPDF_Dictionary* pDict = pShadingStream->GetDict();
- m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate");
- m_nCompBits = pDict->GetIntegerBy("BitsPerComponent");
- m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag");
- if (!m_nCoordBits || !m_nCompBits) {
- return FALSE;
- }
- FX_DWORD nComps = pCS->CountComponents();
- if (nComps > 8) {
- return FALSE;
- }
- m_nComps = nFuncs ? 1 : nComps;
- if (((int)m_nComps < 0) || m_nComps > 8) {
- return FALSE;
- }
- m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1;
- m_CompMax = (1 << m_nCompBits) - 1;
- CPDF_Array* pDecode = pDict->GetArrayBy("Decode");
- if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2) {
- return FALSE;
- }
- m_xmin = pDecode->GetNumberAt(0);
- m_xmax = pDecode->GetNumberAt(1);
- m_ymin = pDecode->GetNumberAt(2);
- m_ymax = pDecode->GetNumberAt(3);
- for (FX_DWORD i = 0; i < m_nComps; i++) {
- m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4);
- m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5);
- }
- return TRUE;
-}
-FX_DWORD CPDF_MeshStream::GetFlag() {
- return m_BitStream.GetBits(m_nFlagBits) & 0x03;
-}
-void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) {
- if (m_nCoordBits == 32) {
- x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) *
- (m_xmax - m_xmin) / (double)m_CoordMax);
- y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) *
- (m_ymax - m_ymin) / (double)m_CoordMax);
- } else {
- x = m_xmin +
- m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax;
- y = m_ymin +
- m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax;
- }
-}
-void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) {
- FX_DWORD i;
- FX_FLOAT color_value[8];
- for (i = 0; i < m_nComps; i++) {
- color_value[i] = m_ColorMin[i] +
- m_BitStream.GetBits(m_nCompBits) *
- (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax;
- }
- if (m_nFuncs) {
- static const int kMaxResults = 8;
- FX_FLOAT result[kMaxResults];
- int nResults;
- FXSYS_memset(result, 0, sizeof(result));
- for (FX_DWORD i = 0; i < m_nFuncs; i++) {
- if (m_pFuncs[i] && m_pFuncs[i]->CountOutputs() <= kMaxResults) {
- m_pFuncs[i]->Call(color_value, 1, result, nResults);
- }
- }
- m_pCS->GetRGB(result, r, g, b);
- } else {
- m_pCS->GetRGB(color_value, r, g, b);
- }
-}
-FX_DWORD CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex,
- CFX_Matrix* pObject2Bitmap) {
- FX_DWORD flag = GetFlag();
- GetCoords(vertex.x, vertex.y);
- pObject2Bitmap->Transform(vertex.x, vertex.y);
- GetColor(vertex.r, vertex.g, vertex.b);
- m_BitStream.ByteAlign();
- return flag;
-}
-FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex,
- int count,
- CFX_Matrix* pObject2Bitmap) {
- for (int i = 0; i < count; i++) {
- if (m_BitStream.IsEOF()) {
- return FALSE;
- }
- GetCoords(vertex[i].x, vertex[i].y);
- pObject2Bitmap->Transform(vertex[i].x, vertex[i].y);
- GetColor(vertex[i].r, vertex[i].g, vertex[i].b);
- m_BitStream.ByteAlign();
- }
- return TRUE;
-}
CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream,
ShadingType type,
diff --git a/core/fpdfapi/fpdf_page/include/cpdf_color.h b/core/fpdfapi/fpdf_page/include/cpdf_color.h
new file mode 100644
index 0000000000..9e20684d83
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/include/cpdf_color.h
@@ -0,0 +1,47 @@
+// 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_PAGE_INCLUDE_CPDF_COLOR_H_
+#define CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_COLOR_H_
+
+#include "core/fpdfapi/fpdf_page/include/cpdf_colorspace.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_Pattern;
+
+class CPDF_Color {
+ public:
+ CPDF_Color() : m_pCS(nullptr), m_pBuffer(nullptr) {}
+ explicit CPDF_Color(int family);
+ ~CPDF_Color();
+
+ FX_BOOL IsNull() const { return !m_pBuffer; }
+ FX_BOOL IsEqual(const CPDF_Color& other) const;
+ FX_BOOL IsPattern() const {
+ return m_pCS && m_pCS->GetFamily() == PDFCS_PATTERN;
+ }
+
+ void Copy(const CPDF_Color* pSrc);
+
+ void SetColorSpace(CPDF_ColorSpace* pCS);
+ void SetValue(FX_FLOAT* comp);
+ void SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comp, int ncomps);
+
+ FX_BOOL GetRGB(int& R, int& G, int& B) const;
+ CPDF_Pattern* GetPattern() const;
+ CPDF_ColorSpace* GetPatternCS() const;
+ FX_FLOAT* GetPatternColor() const;
+
+ CPDF_ColorSpace* m_pCS;
+
+ protected:
+ void ReleaseBuffer();
+ void ReleaseColorSpace();
+
+ FX_FLOAT* m_pBuffer;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_COLOR_H_
diff --git a/core/fpdfapi/fpdf_page/include/cpdf_colorspace.h b/core/fpdfapi/fpdf_page/include/cpdf_colorspace.h
new file mode 100644
index 0000000000..afdd71dc4d
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/include/cpdf_colorspace.h
@@ -0,0 +1,122 @@
+// 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_PAGE_INCLUDE_CPDF_COLORSPACE_H_
+#define CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_COLORSPACE_H_
+
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+
+#define PDFCS_DEVICEGRAY 1
+#define PDFCS_DEVICERGB 2
+#define PDFCS_DEVICECMYK 3
+#define PDFCS_CALGRAY 4
+#define PDFCS_CALRGB 5
+#define PDFCS_LAB 6
+#define PDFCS_ICCBASED 7
+#define PDFCS_SEPARATION 8
+#define PDFCS_DEVICEN 9
+#define PDFCS_INDEXED 10
+#define PDFCS_PATTERN 11
+
+class CPDF_Array;
+class CPDF_Document;
+class CPDF_Object;
+
+class CPDF_ColorSpace {
+ public:
+ static CPDF_ColorSpace* GetStockCS(int Family);
+ static CPDF_ColorSpace* Load(CPDF_Document* pDoc, CPDF_Object* pCSObj);
+ static CPDF_ColorSpace* ColorspaceFromName(const CFX_ByteString& name);
+
+ void ReleaseCS();
+
+ int GetBufSize() const;
+ FX_FLOAT* CreateBuf();
+ void GetDefaultColor(FX_FLOAT* buf) const;
+ FX_DWORD CountComponents() const { return m_nComponents; }
+ int GetFamily() const { return m_Family; }
+ virtual void GetDefaultValue(int iComponent,
+ FX_FLOAT& value,
+ FX_FLOAT& min,
+ FX_FLOAT& max) const {
+ value = 0;
+ min = 0;
+ max = 1.0f;
+ }
+
+ FX_BOOL sRGB() const;
+ virtual FX_BOOL GetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT& R,
+ FX_FLOAT& G,
+ FX_FLOAT& B) const = 0;
+ virtual FX_BOOL SetRGB(FX_FLOAT* pBuf,
+ FX_FLOAT R,
+ FX_FLOAT G,
+ FX_FLOAT B) const {
+ return FALSE;
+ }
+
+ FX_BOOL GetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT& c,
+ FX_FLOAT& m,
+ FX_FLOAT& y,
+ FX_FLOAT& k) const;
+ FX_BOOL SetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT c,
+ FX_FLOAT m,
+ FX_FLOAT y,
+ FX_FLOAT k) const;
+
+ virtual void TranslateImageLine(uint8_t* dest_buf,
+ const uint8_t* src_buf,
+ int pixels,
+ int image_width,
+ int image_height,
+ FX_BOOL bTransMask = FALSE) const;
+
+ CPDF_Array*& GetArray() { return m_pArray; }
+ int GetMaxIndex() const;
+ virtual CPDF_ColorSpace* GetBaseCS() const { return NULL; }
+
+ virtual void EnableStdConversion(FX_BOOL bEnabled);
+
+ CPDF_Document* const m_pDocument;
+
+ protected:
+ CPDF_ColorSpace(CPDF_Document* pDoc, int family, FX_DWORD nComponents)
+ : m_pDocument(pDoc),
+ m_Family(family),
+ m_nComponents(nComponents),
+ m_pArray(nullptr),
+ m_dwStdConversion(0) {}
+ virtual ~CPDF_ColorSpace() {}
+
+ virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
+ return TRUE;
+ }
+ virtual FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT& c,
+ FX_FLOAT& m,
+ FX_FLOAT& y,
+ FX_FLOAT& k) const {
+ return FALSE;
+ }
+ virtual FX_BOOL v_SetCMYK(FX_FLOAT* pBuf,
+ FX_FLOAT c,
+ FX_FLOAT m,
+ FX_FLOAT y,
+ FX_FLOAT k) const {
+ return FALSE;
+ }
+
+ int m_Family;
+ FX_DWORD m_nComponents;
+ CPDF_Array* m_pArray;
+ FX_DWORD m_dwStdConversion;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_COLORSPACE_H_
diff --git a/core/fpdfapi/fpdf_page/include/cpdf_formobject.h b/core/fpdfapi/fpdf_page/include/cpdf_formobject.h
index 234cd73328..b12d68c312 100644
--- a/core/fpdfapi/fpdf_page/include/cpdf_formobject.h
+++ b/core/fpdfapi/fpdf_page/include/cpdf_formobject.h
@@ -10,7 +10,7 @@
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
#include "core/fxcrt/include/fx_coordinates.h"
-class Form;
+class CPDF_Form;
class CPDF_FormObject : public CPDF_PageObject {
public:
diff --git a/core/fpdfapi/fpdf_page/include/cpdf_image.h b/core/fpdfapi/fpdf_page/include/cpdf_image.h
new file mode 100644
index 0000000000..048b86d171
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/include/cpdf_image.h
@@ -0,0 +1,98 @@
+// 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_PAGE_INCLUDE_CPDF_IMAGE_H_
+#define CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_IMAGE_H_
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
+#include "core/fxcrt/include/fx_system.h"
+
+#define PDF_IMAGE_NO_COMPRESS 0x0000
+#define PDF_IMAGE_LOSSY_COMPRESS 0x0001
+#define PDF_IMAGE_LOSSLESS_COMPRESS 0x0002
+#define PDF_IMAGE_MASK_LOSSY_COMPRESS 0x0004
+#define PDF_IMAGE_MASK_LOSSLESS_COMPRESS 0x0008
+
+class CFX_DIBitmap;
+class CFX_DIBSource;
+class CPDF_Dictionay;
+class CPDF_Document;
+class CPDF_Page;
+class IFX_FileRead;
+class IFX_FileWrite;
+class IFX_Pause;
+
+class CPDF_Image {
+ public:
+ explicit CPDF_Image(CPDF_Document* pDoc);
+ ~CPDF_Image();
+
+ FX_BOOL LoadImageF(CPDF_Stream* pImageStream, FX_BOOL bInline);
+
+ void Release();
+
+ CPDF_Image* Clone();
+
+ CPDF_Dictionary* GetInlineDict() const { return m_pInlineDict; }
+ CPDF_Stream* GetStream() const { return m_pStream; }
+ CPDF_Dictionary* GetDict() const {
+ return m_pStream ? m_pStream->GetDict() : NULL;
+ }
+ CPDF_Dictionary* GetOC() const { return m_pOC; }
+ CPDF_Document* GetDocument() const { return m_pDocument; }
+
+ int32_t GetPixelHeight() const { return m_Height; }
+ int32_t GetPixelWidth() const { return m_Width; }
+
+ FX_BOOL IsInline() { return m_bInline; }
+ FX_BOOL IsMask() const { return m_bIsMask; }
+ FX_BOOL IsInterpol() const { return m_bInterpolate; }
+
+ CFX_DIBSource* LoadDIBSource(CFX_DIBSource** ppMask = NULL,
+ FX_DWORD* pMatteColor = NULL,
+ FX_BOOL bStdCS = FALSE,
+ FX_DWORD GroupFamily = 0,
+ FX_BOOL bLoadMask = FALSE) const;
+
+ void SetInlineDict(CPDF_Dictionary* pDict) { m_pInlineDict = pDict; }
+ void SetImage(const CFX_DIBitmap* pDIBitmap,
+ int32_t iCompress,
+ IFX_FileWrite* pFileWrite = NULL,
+ IFX_FileRead* pFileRead = NULL,
+ const CFX_DIBitmap* pMask = NULL);
+ void SetJpegImage(uint8_t* pImageData, FX_DWORD size);
+ void SetJpegImage(IFX_FileRead* pFile);
+
+ void ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pDIBitmap);
+
+ FX_BOOL StartLoadDIBSource(CPDF_Dictionary* pFormResource,
+ CPDF_Dictionary* pPageResource,
+ FX_BOOL bStdCS = FALSE,
+ FX_DWORD GroupFamily = 0,
+ FX_BOOL bLoadMask = FALSE);
+ FX_BOOL Continue(IFX_Pause* pPause);
+ CFX_DIBSource* DetachBitmap();
+ CFX_DIBSource* DetachMask();
+
+ CFX_DIBSource* m_pDIBSource;
+ CFX_DIBSource* m_pMask;
+ FX_DWORD m_MatteColor;
+
+ private:
+ CPDF_Dictionary* InitJPEG(uint8_t* pData, FX_DWORD size);
+
+ CPDF_Stream* m_pStream;
+ FX_BOOL m_bInline;
+ CPDF_Dictionary* m_pInlineDict;
+ int32_t m_Height;
+ int32_t m_Width;
+ FX_BOOL m_bIsMask;
+ FX_BOOL m_bInterpolate;
+ CPDF_Document* m_pDocument;
+ CPDF_Dictionary* m_pOC;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_IMAGE_H_
diff --git a/core/fpdfapi/fpdf_page/pageint.h b/core/fpdfapi/fpdf_page/pageint.h
index e6a150072e..d254477dc3 100644
--- a/core/fpdfapi/fpdf_page/pageint.h
+++ b/core/fpdfapi/fpdf_page/pageint.h
@@ -13,9 +13,9 @@
#include <vector>
#include "core/fpdfapi/fpdf_page/cpdf_contentmark.h"
+#include "core/fpdfapi/fpdf_page/cpdf_countedobject.h"
#include "core/fpdfapi/fpdf_page/cpdf_parseoptions.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_ge.h"
class CPDF_AllStates;
@@ -26,6 +26,7 @@ class CPDF_Form;
class CPDF_IccProfile;
class CPDF_Image;
class CPDF_ImageObject;
+class CPDF_Page;
class CPDF_ParseOptions;
class CPDF_Pattern;
class CPDF_StreamAcc;
@@ -438,10 +439,7 @@ class CPDF_DeviceCS : public CPDF_ColorSpace {
class CPDF_PatternCS : public CPDF_ColorSpace {
public:
- explicit CPDF_PatternCS(CPDF_Document* pDoc)
- : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1),
- m_pBaseCS(nullptr),
- m_pCountedBaseCS(nullptr) {}
+ explicit CPDF_PatternCS(CPDF_Document* pDoc);
~CPDF_PatternCS() override;
FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
FX_BOOL GetRGB(FX_FLOAT* pBuf,
@@ -455,6 +453,14 @@ class CPDF_PatternCS : public CPDF_ColorSpace {
CPDF_CountedColorSpace* m_pCountedBaseCS;
};
+#define MAX_PATTERN_COLORCOMPS 16
+struct PatternValue {
+ CPDF_Pattern* m_pPattern;
+ CPDF_CountedPattern* m_pCountedPattern;
+ int m_nComps;
+ FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
+};
+
void PDF_ReplaceAbbr(CPDF_Object* pObj);
bool IsPathOperator(const uint8_t* buf, size_t len);
diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp
index 6a6e40f1c6..eb9a483e6e 100644
--- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp
+++ b/core/fpdfapi/fpdf_parser/cpdf_document.cpp
@@ -12,6 +12,7 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
#include "core/fpdfapi/fpdf_render/render_int.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fpdfapi/ipdf_rendermodule.h"
diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp
index 3f79abe1b8..24ca282322 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render.cpp
@@ -6,10 +6,13 @@
#include "core/fpdfapi/fpdf_render/render_int.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
#include "core/fpdfapi/fpdf_page/cpdf_colorstatedata.h"
#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp
index bda2a4469f..b28aee6980 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp
@@ -10,7 +10,10 @@
#include <vector>
#include "core/fpdfapi/fpdf_page/cpdf_parseoptions.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
+#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
index 5c4f7f593c..1ad091e7af 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
@@ -11,6 +11,7 @@
#include <vector>
#include "core/fpdfapi/fpdf_page/cpdf_parseoptions.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
#include "core/fpdfapi/fpdf_page/pageint.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
@@ -92,71 +93,6 @@ const int kMaxImageDimension = 0x01FFFF;
} // namespace
-CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask,
- FX_DWORD* pMatteColor,
- FX_BOOL bStdCS,
- FX_DWORD GroupFamily,
- FX_BOOL bLoadMask) const {
- std::unique_ptr<CPDF_DIBSource> source(new CPDF_DIBSource);
- if (source->Load(m_pDocument, m_pStream,
- reinterpret_cast<CPDF_DIBSource**>(ppMask), pMatteColor,
- nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) {
- return source.release();
- }
- return nullptr;
-}
-
-CFX_DIBSource* CPDF_Image::DetachBitmap() {
- CFX_DIBSource* pBitmap = m_pDIBSource;
- m_pDIBSource = nullptr;
- return pBitmap;
-}
-
-CFX_DIBSource* CPDF_Image::DetachMask() {
- CFX_DIBSource* pBitmap = m_pMask;
- m_pMask = nullptr;
- return pBitmap;
-}
-
-FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource,
- CPDF_Dictionary* pPageResource,
- FX_BOOL bStdCS,
- FX_DWORD GroupFamily,
- FX_BOOL bLoadMask) {
- std::unique_ptr<CPDF_DIBSource> source(new CPDF_DIBSource);
- int ret =
- source->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource,
- pPageResource, bStdCS, GroupFamily, bLoadMask);
- if (ret == 2) {
- m_pDIBSource = source.release();
- return TRUE;
- }
- if (!ret) {
- m_pDIBSource = nullptr;
- return FALSE;
- }
- m_pMask = source->DetachMask();
- m_MatteColor = source->GetMatteColor();
- m_pDIBSource = source.release();
- return FALSE;
-}
-
-FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) {
- CPDF_DIBSource* pSource = static_cast<CPDF_DIBSource*>(m_pDIBSource);
- int ret = pSource->ContinueLoadDIBSource(pPause);
- if (ret == 2) {
- return TRUE;
- }
- if (!ret) {
- delete m_pDIBSource;
- m_pDIBSource = nullptr;
- return FALSE;
- }
- m_pMask = pSource->DetachMask();
- m_MatteColor = pSource->GetMatteColor();
- return FALSE;
-}
-
CPDF_DIBSource::CPDF_DIBSource()
: m_pDocument(nullptr),
m_pStream(nullptr),
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
index 9006f2011f..d4dd8ec211 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
@@ -7,7 +7,10 @@
#include "core/fpdfapi/fpdf_render/render_int.h"
#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h"
+#include "core/fpdfapi/fpdf_page/cpdf_meshstream.h"
#include "core/fpdfapi/fpdf_page/cpdf_parseoptions.h"
+#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
+#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
index 44e57e49ea..04b0c93507 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp
@@ -6,6 +6,10 @@
#include "core/fpdfapi/fpdf_render/render_int.h"
+#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
#include "core/fpdfapi/fpdf_page/cpdf_parseoptions.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
@@ -318,27 +322,7 @@ static void ReleaseCachedType3(CPDF_Type3Font* pFont) {
pFont->m_pDocument->GetRenderData()->ReleaseCachedType3(pFont);
pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict());
}
-FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) {
- if (m_pBitmap || !m_pForm) {
- return TRUE;
- }
- if (m_pForm->GetPageObjectList()->size() == 1 && !m_bColored) {
- auto& pPageObj = m_pForm->GetPageObjectList()->front();
- if (pPageObj->IsImage()) {
- m_ImageMatrix = pPageObj->AsImage()->m_Matrix;
- const CFX_DIBSource* pSource =
- pPageObj->AsImage()->m_pImage->LoadDIBSource();
- if (pSource) {
- m_pBitmap = pSource->Clone();
- delete pSource;
- }
- delete m_pForm;
- m_pForm = NULL;
- return TRUE;
- }
- }
- return FALSE;
-}
+
class CPDF_RefType3Cache {
public:
CPDF_RefType3Cache(CPDF_Type3Font* pType3Font) {
diff --git a/core/fpdfapi/fpdf_render/render_int.h b/core/fpdfapi/fpdf_render/render_int.h
index b171b60fbe..ea1b1d8f6b 100644
--- a/core/fpdfapi/fpdf_render/render_int.h
+++ b/core/fpdfapi/fpdf_render/render_int.h
@@ -10,10 +10,11 @@
#include <map>
#include <memory>
+#include "core/fpdfapi/fpdf_page/cpdf_countedobject.h"
#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h"
#include "core/fpdfapi/fpdf_page/include/cpdf_clippath.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
class CPDF_PageObjectHolder;
class CPDF_PageRenderCache;
@@ -40,6 +41,7 @@ class CPDF_TilingPattern;
class CPDF_Color;
class CPDF_Dictionary;
class CPDF_ImageObject;
+class CPDF_Stream;
#define TYPE3_MAX_BLUES 16