Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_document.cpp

Issue 1925453002: Move CPDF_Document code into cpdf_document.cpp. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: nits Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" 7 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
8 8
9 #include <set> 9 #include <set>
10 10
11 #include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
11 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" 12 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h"
12 #include "core/fpdfapi/fpdf_page/pageint.h" 13 #include "core/fpdfapi/fpdf_page/pageint.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
14 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
15 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h" 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h"
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" 17 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h"
17 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" 18 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
18 #include "core/fpdfapi/fpdf_render/render_int.h" 19 #include "core/fpdfapi/fpdf_render/render_int.h"
19 #include "core/fpdfapi/include/cpdf_modulemgr.h" 20 #include "core/fpdfapi/include/cpdf_modulemgr.h"
20 #include "core/fxge/include/fx_font.h" 21 #include "core/fxge/include/fx_font.h"
21 #include "third_party/base/stl_util.h" 22 #include "third_party/base/stl_util.h"
22 23
23 namespace { 24 namespace {
24 25
26 const int FX_MAX_PAGE_LEVEL = 1024;
27
28 const uint16_t g_FX_CP874Unicodes[128] = {
29 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x0000,
30 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
31 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x0000, 0x0000,
32 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0E01, 0x0E02, 0x0E03,
33 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C,
34 0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15,
35 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E,
36 0x0E1F, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
37 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, 0x0E30,
38 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39,
39 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, 0x0E40, 0x0E41, 0x0E42,
40 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B,
41 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54,
42 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000,
43 0x0000, 0x0000,
44 };
45 const uint16_t g_FX_CP1250Unicodes[128] = {
46 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
47 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0000, 0x2018,
48 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161,
49 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, 0x00A0, 0x02C7, 0x02D8, 0x0141,
50 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC,
51 0x00AD, 0x00AE, 0x017B, 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5,
52 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E,
53 0x017C, 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
54 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 0x0110,
55 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E,
56 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 0x0155, 0x00E1, 0x00E2,
57 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB,
58 0x011B, 0x00ED, 0x00EE, 0x010F, 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4,
59 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD,
60 0x0163, 0x02D9,
61 };
62 const uint16_t g_FX_CP1251Unicodes[128] = {
63 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC,
64 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018,
65 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459,
66 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408,
67 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC,
68 0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5,
69 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455,
70 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
71 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
72 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429,
73 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432,
74 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
75 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444,
76 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D,
77 0x044E, 0x044F,
78 };
79 const uint16_t g_FX_CP1253Unicodes[128] = {
80 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
81 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
82 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
83 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0385, 0x0386, 0x00A3,
84 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC,
85 0x00AD, 0x00AE, 0x2015, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5,
86 0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E,
87 0x038F, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
88 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
89 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
90 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03B1, 0x03B2,
91 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
92 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4,
93 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD,
94 0x03CE, 0x0000,
95 };
96 const uint16_t g_FX_CP1254Unicodes[128] = {
97 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
98 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
99 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161,
100 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
101 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC,
102 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
103 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
104 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
105 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x011E,
106 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9,
107 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, 0x00E0, 0x00E1, 0x00E2,
108 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
109 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4,
110 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131,
111 0x015F, 0x00FF,
112 };
113 const uint16_t g_FX_CP1255Unicodes[128] = {
114 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
115 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
116 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0000,
117 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
118 0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC,
119 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
120 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
121 0x00BF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
122 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, 0x05C0,
123 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x0000,
124 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05D0, 0x05D1, 0x05D2,
125 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB,
126 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4,
127 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E,
128 0x200F, 0x0000,
129 };
130 const uint16_t g_FX_CP1256Unicodes[128] = {
131 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
132 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x06AF, 0x2018,
133 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691,
134 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, 0x00A0, 0x060C, 0x00A2, 0x00A3,
135 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC,
136 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
137 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
138 0x061F, 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
139 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630,
140 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638,
141 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, 0x00E0, 0x0644, 0x00E2,
142 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
143 0x0649, 0x064A, 0x00EE, 0x00EF, 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4,
144 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E,
145 0x200F, 0x06D2,
146 };
147 const uint16_t g_FX_CP1257Unicodes[128] = {
148 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
149 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, 0x0000, 0x2018,
150 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
151 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, 0x00A0, 0x0000, 0x00A2, 0x00A3,
152 0x00A4, 0x0000, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC,
153 0x00AD, 0x00AE, 0x00C6, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
154 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
155 0x00E6, 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
156 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, 0x0160,
157 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141,
158 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, 0x0105, 0x012F, 0x0101,
159 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117,
160 0x0123, 0x0137, 0x012B, 0x013C, 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D,
161 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C,
162 0x017E, 0x02D9,
163 };
164
165 struct FX_CharsetUnicodes {
166 uint8_t m_Charset;
167 const uint16_t* m_pUnicodes;
168 };
169
170 const FX_CharsetUnicodes g_FX_CharsetUnicodes[] = {
171 {FXFONT_THAI_CHARSET, g_FX_CP874Unicodes},
172 {FXFONT_EASTEUROPE_CHARSET, g_FX_CP1250Unicodes},
173 {FXFONT_RUSSIAN_CHARSET, g_FX_CP1251Unicodes},
174 {FXFONT_GREEK_CHARSET, g_FX_CP1253Unicodes},
175 {FXFONT_TURKISH_CHARSET, g_FX_CP1254Unicodes},
176 {FXFONT_HEBREW_CHARSET, g_FX_CP1255Unicodes},
177 {FXFONT_ARABIC_CHARSET, g_FX_CP1256Unicodes},
178 {FXFONT_BALTIC_CHARSET, g_FX_CP1257Unicodes},
179 };
180
181 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
182 void InsertWidthArray(HDC hDC, int start, int end, CPDF_Array* pWidthArray) {
183 int size = end - start + 1;
184 int* widths = FX_Alloc(int, size);
185 GetCharWidth(hDC, start, end, widths);
186 int i;
187 for (i = 1; i < size; i++) {
188 if (widths[i] != *widths)
189 break;
190 }
191 if (i == size) {
192 int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1);
193 pWidthArray->AddInteger(first + size - 1);
194 pWidthArray->AddInteger(*widths);
195 } else {
196 CPDF_Array* pWidthArray1 = new CPDF_Array;
197 pWidthArray->Add(pWidthArray1);
198 for (i = 0; i < size; i++) {
199 pWidthArray1->AddInteger(widths[i]);
200 }
201 }
202 FX_Free(widths);
203 }
204
205 CFX_ByteString FPDF_GetPSNameFromTT(HDC hDC) {
206 CFX_ByteString result;
207 DWORD size = ::GetFontData(hDC, 'eman', 0, nullptr, 0);
208 if (size != GDI_ERROR) {
209 LPBYTE buffer = FX_Alloc(BYTE, size);
210 ::GetFontData(hDC, 'eman', 0, buffer, size);
211 result = GetNameFromTT(buffer, size, 6);
212 FX_Free(buffer);
213 }
214 return result;
215 }
216 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
217
218 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
219 struct FX_LANG2CS {
220 uint32_t uLang;
221 uint8_t uCharset;
222 };
223 const FX_LANG2CS gs_FXLang2CharsetTable[] = {
224 {3109, 0}, {3121, 178}, {3129, 162}, {3139, 204}, {3141, 204},
225 {3166, 0}, {3184, 238}, {3197, 0}, {3201, 0}, {3239, 161},
226 {3241, 0}, {3246, 0}, {3247, 186}, {3248, 0}, {3259, 178},
227 {3267, 0}, {3273, 0}, {3276, 0}, {3301, 0}, {3310, 1},
228 {3325, 177}, {3329, 1}, {3338, 238}, {3341, 238}, {3345, 1},
229 {3355, 0}, {3370, 0}, {3371, 0}, {3383, 128}, {3424, 204},
230 {3427, 1}, {3428, 129}, {3436, 178}, {3464, 186}, {3466, 186},
231 {3486, 204}, {3487, 0}, {3493, 1}, {3494, 0}, {3508, 0},
232 {3518, 0}, {3520, 0}, {3569, 1}, {3580, 238}, {3588, 0},
233 {3645, 238}, {3651, 204}, {3672, 238}, {3673, 238}, {3678, 238},
234 {3679, 238}, {3683, 0}, {3684, 0}, {3693, 1}, {3697, 1},
235 {3700, 222}, {3710, 162}, {3734, 204}, {3741, 178}, {3749, 162},
236 {3763, 163}, {3886, 134}, {105943, 0}, {106375, 1}, {3923451837, 134},
237 {3923451838, 136},
238 };
239
240 uint32_t FX_GetLangHashCode(const FX_CHAR* pStr) {
241 FXSYS_assert(pStr);
242 int32_t iLength = FXSYS_strlen(pStr);
243 const FX_CHAR* pStrEnd = pStr + iLength;
244 uint32_t uHashCode = 0;
245 while (pStr < pStrEnd)
246 uHashCode = 31 * uHashCode + tolower(*pStr++);
247 return uHashCode;
248 }
249
250 uint8_t FX_GetCsFromLangCode(uint32_t uCode) {
251 int32_t iStart = 0;
252 int32_t iEnd = FX_ArraySize(gs_FXLang2CharsetTable) - 1;
253 while (iStart <= iEnd) {
254 int32_t iMid = (iStart + iEnd) / 2;
255 const FX_LANG2CS& charset = gs_FXLang2CharsetTable[iMid];
256 if (uCode == charset.uLang)
257 return charset.uCharset;
258
259 if (uCode < charset.uLang)
260 iEnd = iMid - 1;
261 else
262 iStart = iMid + 1;
263 }
264 return 0;
265 }
266
267 uint8_t FX_GetCharsetFromLang(const FX_CHAR* pLang, int32_t iLength) {
268 FXSYS_assert(pLang);
269 if (iLength < 0)
270 iLength = FXSYS_strlen(pLang);
271
272 uint32_t uHash = FX_GetLangHashCode(pLang);
273 return FX_GetCsFromLangCode(uHash);
274 }
275
276 void CFString2CFXByteString(CFStringRef src, CFX_ByteString& dest) {
277 SInt32 len = CFStringGetLength(src);
278 CFRange range = CFRangeMake(0, len);
279 CFIndex used = 0;
280 UInt8* pBuffer = (UInt8*)calloc(len + 1, sizeof(UInt8));
281 CFStringGetBytes(src, range, kCFStringEncodingASCII, 0, false, pBuffer, len,
282 &used);
283 dest = (FX_CHAR*)pBuffer;
284 free(pBuffer);
285 }
286
287 bool HasCharSet(CFArrayRef languages, const std::vector<uint8_t>& charsets) {
288 for (int i = 0; i < CFArrayGetCount(languages); ++i) {
289 CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(languages, i);
290 uint8_t charset = FX_GetCharsetFromLang(
291 CFStringGetCStringPtr(language, kCFStringEncodingMacRoman), -1);
292 if (pdfium::ContainsValue(charsets, charset))
293 return true;
294 }
295 return false;
296 }
297
298 void FX_GetCharWidth(CTFontRef font, UniChar start, UniChar end, int* width) {
299 CGFloat size = CTFontGetSize(font);
300 for (; start <= end; ++start) {
301 CGGlyph pGlyph = 0;
302 CFIndex count = 1;
303 CTFontGetGlyphsForCharacters(font, &start, &pGlyph, count);
304 CGSize advances;
305 CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &pGlyph,
306 &advances, 1);
307 *width = (int)(advances.width / size * 1000);
308 width++;
309 }
310 }
311
312 void InsertWidthArray(CTFontRef font,
313 int start,
314 int end,
315 CPDF_Array* pWidthArray) {
316 int size = end - start + 1;
317 int* widths = FX_Alloc(int, size);
318 FX_GetCharWidth(font, start, end, widths);
319 int i;
320 for (i = 1; i < size; i++) {
321 if (widths[i] != *widths)
322 break;
323 }
324 if (i == size) {
325 int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1);
326 pWidthArray->AddInteger(first + size - 1);
327 pWidthArray->AddInteger(*widths);
328 } else {
329 CPDF_Array* pWidthArray1 = new CPDF_Array;
330 pWidthArray->Add(pWidthArray1);
331 for (i = 0; i < size; i++) {
332 pWidthArray1->AddInteger(widths[i]);
333 }
334 }
335 FX_Free(widths);
336 }
337 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
338
339 void InsertWidthArray1(CFX_Font* pFont,
340 CFX_UnicodeEncoding* pEncoding,
341 FX_WCHAR start,
342 FX_WCHAR end,
343 CPDF_Array* pWidthArray) {
344 int size = end - start + 1;
345 int* widths = FX_Alloc(int, size);
346 int i;
347 for (i = 0; i < size; i++) {
348 int glyph_index = pEncoding->GlyphFromCharCode(start + i);
349 widths[i] = pFont->GetGlyphWidth(glyph_index);
350 }
351 for (i = 1; i < size; i++) {
352 if (widths[i] != *widths)
353 break;
354 }
355 if (i == size) {
356 int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1);
357 pWidthArray->AddInteger(first + size - 1);
358 pWidthArray->AddInteger(*widths);
359 } else {
360 CPDF_Array* pWidthArray1 = new CPDF_Array;
361 pWidthArray->Add(pWidthArray1);
362 for (i = 0; i < size; i++) {
363 pWidthArray1->AddInteger(widths[i]);
364 }
365 }
366 FX_Free(widths);
367 }
368
369 int InsertDeletePDFPage(CPDF_Document* pDoc,
370 CPDF_Dictionary* pPages,
371 int nPagesToGo,
372 CPDF_Dictionary* pPage,
373 FX_BOOL bInsert,
374 std::set<CPDF_Dictionary*>* pVisited) {
375 CPDF_Array* pKidList = pPages->GetArrayBy("Kids");
376 if (!pKidList)
377 return -1;
378
379 for (size_t i = 0; i < pKidList->GetCount(); i++) {
380 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
381 if (pKid->GetStringBy("Type") == "Page") {
382 if (nPagesToGo == 0) {
383 if (bInsert) {
384 pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum()));
385 pPage->SetAtReference("Parent", pDoc, pPages->GetObjNum());
386 } else {
387 pKidList->RemoveAt(i);
388 }
389 pPages->SetAtInteger(
390 "Count", pPages->GetIntegerBy("Count") + (bInsert ? 1 : -1));
391 return 1;
392 }
393 nPagesToGo--;
394 } else {
395 int nPages = pKid->GetIntegerBy("Count");
396 if (nPagesToGo < nPages) {
397 if (pdfium::ContainsValue(*pVisited, pKid))
398 return -1;
399 pdfium::ScopedSetInsertion<CPDF_Dictionary*>(pVisited, pKid);
400 if (InsertDeletePDFPage(pDoc, pKid, nPagesToGo, pPage, bInsert,
401 pVisited) < 0) {
402 return -1;
403 }
404 pPages->SetAtInteger(
405 "Count", pPages->GetIntegerBy("Count") + (bInsert ? 1 : -1));
406 return 1;
407 }
408 nPagesToGo -= nPages;
409 }
410 }
411 return 0;
412 }
413
414 int InsertNewPage(CPDF_Document* pDoc,
415 int iPage,
416 CPDF_Dictionary* pPageDict,
417 CFX_ArrayTemplate<uint32_t>& pageList) {
418 CPDF_Dictionary* pRoot = pDoc->GetRoot();
419 if (!pRoot)
420 return -1;
421
422 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
423 if (!pPages)
424 return -1;
425
426 int nPages = pDoc->GetPageCount();
427 if (iPage < 0 || iPage > nPages)
428 return -1;
429
430 if (iPage == nPages) {
431 CPDF_Array* pPagesList = pPages->GetArrayBy("Kids");
432 if (!pPagesList) {
433 pPagesList = new CPDF_Array;
434 pPages->SetAt("Kids", pPagesList);
435 }
436 pPagesList->Add(pPageDict, pDoc);
437 pPages->SetAtInteger("Count", nPages + 1);
438 pPageDict->SetAtReference("Parent", pDoc, pPages->GetObjNum());
439 } else {
440 std::set<CPDF_Dictionary*> stack = {pPages};
441 if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0)
442 return -1;
443 }
444 pageList.InsertAt(iPage, pPageDict->GetObjNum());
445 return iPage;
446 }
447
25 int CountPages(CPDF_Dictionary* pPages, 448 int CountPages(CPDF_Dictionary* pPages,
26 std::set<CPDF_Dictionary*>* visited_pages) { 449 std::set<CPDF_Dictionary*>* visited_pages) {
27 int count = pPages->GetIntegerBy("Count"); 450 int count = pPages->GetIntegerBy("Count");
28 if (count > 0 && count < FPDF_PAGE_MAX_NUM) { 451 if (count > 0 && count < FPDF_PAGE_MAX_NUM) {
29 return count; 452 return count;
30 } 453 }
31 CPDF_Array* pKidList = pPages->GetArrayBy("Kids"); 454 CPDF_Array* pKidList = pPages->GetArrayBy("Kids");
32 if (!pKidList) { 455 if (!pKidList) {
33 return 0; 456 return 0;
34 } 457 }
(...skipping 17 matching lines...) Expand all
52 return count; 475 return count;
53 } 476 }
54 477
55 } // namespace 478 } // namespace
56 479
57 CPDF_Document::CPDF_Document(CPDF_Parser* pParser) 480 CPDF_Document::CPDF_Document(CPDF_Parser* pParser)
58 : CPDF_IndirectObjectHolder(pParser), 481 : CPDF_IndirectObjectHolder(pParser),
59 m_pRootDict(nullptr), 482 m_pRootDict(nullptr),
60 m_pInfoDict(nullptr), 483 m_pInfoDict(nullptr),
61 m_bLinearized(false), 484 m_bLinearized(false),
62 m_dwFirstPageNo(0), 485 m_iFirstPageNo(0),
63 m_dwFirstPageObjNum(0), 486 m_dwFirstPageObjNum(0),
64 m_pDocPage(new CPDF_DocPageData(this)), 487 m_pDocPage(new CPDF_DocPageData(this)),
65 m_pDocRender(new CPDF_DocRenderData(this)) { 488 m_pDocRender(new CPDF_DocRenderData(this)) {}
66 ASSERT(pParser);
67 }
68 489
69 CPDF_DocPageData* CPDF_Document::GetValidatePageData() { 490 CPDF_Document::~CPDF_Document() {
70 if (m_pDocPage) 491 delete m_pDocPage;
71 return m_pDocPage; 492 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
72
73 m_pDocPage = new CPDF_DocPageData(this);
74 return m_pDocPage;
75 }
76
77 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() {
78 if (m_pDocRender)
79 return m_pDocRender;
80
81 m_pDocRender = new CPDF_DocRenderData(this);
82 return m_pDocRender;
83 } 493 }
84 494
85 void CPDF_Document::LoadDoc() { 495 void CPDF_Document::LoadDoc() {
86 m_LastObjNum = m_pParser->GetLastObjNum(); 496 m_LastObjNum = m_pParser->GetLastObjNum();
87 CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); 497 CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum());
88 if (!pRootObj) { 498 if (!pRootObj) {
89 return; 499 return;
90 } 500 }
91 m_pRootDict = pRootObj->GetDict(); 501 m_pRootDict = pRootObj->GetDict();
92 if (!m_pRootDict) { 502 if (!m_pRootDict) {
93 return; 503 return;
94 } 504 }
95 CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); 505 CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum());
96 if (pInfoObj) { 506 if (pInfoObj) {
97 m_pInfoDict = pInfoObj->GetDict(); 507 m_pInfoDict = pInfoObj->GetDict();
98 } 508 }
99 CPDF_Array* pIDArray = m_pParser->GetIDArray(); 509 CPDF_Array* pIDArray = m_pParser->GetIDArray();
100 if (pIDArray) { 510 if (pIDArray) {
101 m_ID1 = pIDArray->GetStringAt(0); 511 m_ID1 = pIDArray->GetStringAt(0);
102 m_ID2 = pIDArray->GetStringAt(1); 512 m_ID2 = pIDArray->GetStringAt(1);
103 } 513 }
104 m_PageList.SetSize(RetrievePageCount()); 514 m_PageList.SetSize(RetrievePageCount());
105 } 515 }
516
106 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) { 517 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) {
107 m_bLinearized = TRUE; 518 m_bLinearized = true;
108 m_LastObjNum = m_pParser->GetLastObjNum(); 519 m_LastObjNum = m_pParser->GetLastObjNum();
109 CPDF_Object* pIndirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); 520 CPDF_Object* pIndirectObj = GetIndirectObject(m_pParser->GetRootObjNum());
110 m_pRootDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr; 521 m_pRootDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr;
111 if (!m_pRootDict) { 522 if (!m_pRootDict) {
112 return; 523 return;
113 } 524 }
114 pIndirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); 525 pIndirectObj = GetIndirectObject(m_pParser->GetInfoObjNum());
115 m_pInfoDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr; 526 m_pInfoDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr;
116 CPDF_Array* pIDArray = m_pParser->GetIDArray(); 527 CPDF_Array* pIDArray = m_pParser->GetIDArray();
117 if (pIDArray) { 528 if (pIDArray) {
118 m_ID1 = pIDArray->GetStringAt(0); 529 m_ID1 = pIDArray->GetStringAt(0);
119 m_ID2 = pIDArray->GetStringAt(1); 530 m_ID2 = pIDArray->GetStringAt(1);
120 } 531 }
121 uint32_t dwPageCount = 0; 532 uint32_t dwPageCount = 0;
122 CPDF_Object* pCount = pLinearized->GetObjectBy("N"); 533 CPDF_Object* pCount = pLinearized->GetObjectBy("N");
123 if (ToNumber(pCount)) 534 if (ToNumber(pCount))
124 dwPageCount = pCount->GetInteger(); 535 dwPageCount = pCount->GetInteger();
125 536
126 m_PageList.SetSize(dwPageCount); 537 m_PageList.SetSize(dwPageCount);
127 CPDF_Object* pNo = pLinearized->GetObjectBy("P"); 538 CPDF_Object* pNo = pLinearized->GetObjectBy("P");
128 if (ToNumber(pNo)) 539 if (ToNumber(pNo))
129 m_dwFirstPageNo = pNo->GetInteger(); 540 m_iFirstPageNo = pNo->GetInteger();
130 541
131 CPDF_Object* pObjNum = pLinearized->GetObjectBy("O"); 542 CPDF_Object* pObjNum = pLinearized->GetObjectBy("O");
132 if (ToNumber(pObjNum)) 543 if (ToNumber(pObjNum))
133 m_dwFirstPageObjNum = pObjNum->GetInteger(); 544 m_dwFirstPageObjNum = pObjNum->GetInteger();
134 } 545 }
135 546
136 void CPDF_Document::LoadPages() { 547 void CPDF_Document::LoadPages() {
137 m_PageList.SetSize(RetrievePageCount()); 548 m_PageList.SetSize(RetrievePageCount());
138 } 549 }
139 550
140 CPDF_Document::~CPDF_Document() { 551 CPDF_Dictionary* CPDF_Document::FindPDFPage(CPDF_Dictionary* pPages,
141 if (m_pDocPage) { 552 int iPage,
142 delete this->GetPageData(); 553 int nPagesToGo,
143 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); 554 int level) {
144 } 555 CPDF_Array* pKidList = pPages->GetArrayBy("Kids");
145 if (m_pDocRender) 556 if (!pKidList)
146 delete m_pDocRender; 557 return nPagesToGo == 0 ? pPages : nullptr;
147 }
148 558
149 #define FX_MAX_PAGE_LEVEL 1024 559 if (level >= FX_MAX_PAGE_LEVEL)
150 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, 560 return nullptr;
151 int iPage, 561
152 int nPagesToGo,
153 int level) {
154 CPDF_Array* pKidList = pPages->GetArrayBy("Kids");
155 if (!pKidList) {
156 if (nPagesToGo == 0) {
157 return pPages;
158 }
159 return NULL;
160 }
161 if (level >= FX_MAX_PAGE_LEVEL) {
162 return NULL;
163 }
164 for (size_t i = 0; i < pKidList->GetCount(); i++) { 562 for (size_t i = 0; i < pKidList->GetCount(); i++) {
165 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); 563 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
166 if (!pKid) { 564 if (!pKid) {
167 nPagesToGo--; 565 nPagesToGo--;
168 continue; 566 continue;
169 } 567 }
170 if (pKid == pPages) { 568 if (pKid == pPages) {
171 continue; 569 continue;
172 } 570 }
173 if (!pKid->KeyExist("Kids")) { 571 if (!pKid->KeyExist("Kids")) {
174 if (nPagesToGo == 0) { 572 if (nPagesToGo == 0) {
175 return pKid; 573 return pKid;
176 } 574 }
177 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); 575 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum());
178 nPagesToGo--; 576 nPagesToGo--;
179 } else { 577 } else {
180 int nPages = pKid->GetIntegerBy("Count"); 578 int nPages = pKid->GetIntegerBy("Count");
181 if (nPagesToGo < nPages) { 579 if (nPagesToGo < nPages) {
182 return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); 580 return FindPDFPage(pKid, iPage, nPagesToGo, level + 1);
183 } 581 }
184 nPagesToGo -= nPages; 582 nPagesToGo -= nPages;
185 } 583 }
186 } 584 }
187 return NULL; 585 return nullptr;
188 } 586 }
189 587
190 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { 588 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) {
191 if (iPage < 0 || iPage >= m_PageList.GetSize()) 589 if (iPage < 0 || iPage >= m_PageList.GetSize())
192 return nullptr; 590 return nullptr;
193 591
194 if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { 592 if (m_bLinearized && (iPage == m_iFirstPageNo)) {
195 if (CPDF_Dictionary* pDict = 593 if (CPDF_Dictionary* pDict =
196 ToDictionary(GetIndirectObject(m_dwFirstPageObjNum))) { 594 ToDictionary(GetIndirectObject(m_dwFirstPageObjNum))) {
197 return pDict; 595 return pDict;
198 } 596 }
199 } 597 }
200 598
201 int objnum = m_PageList.GetAt(iPage); 599 int objnum = m_PageList.GetAt(iPage);
202 if (objnum) { 600 if (objnum) {
203 if (CPDF_Dictionary* pDict = ToDictionary(GetIndirectObject(objnum))) 601 if (CPDF_Dictionary* pDict = ToDictionary(GetIndirectObject(objnum)))
204 return pDict; 602 return pDict;
205 } 603 }
206 604
207 CPDF_Dictionary* pRoot = GetRoot(); 605 CPDF_Dictionary* pRoot = GetRoot();
208 if (!pRoot) 606 if (!pRoot)
209 return nullptr; 607 return nullptr;
210 608
211 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); 609 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
212 if (!pPages) 610 if (!pPages)
213 return nullptr; 611 return nullptr;
214 612
215 CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); 613 CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0);
216 if (!pPage) 614 if (!pPage)
217 return nullptr; 615 return nullptr;
218 616
219 m_PageList.SetAt(iPage, pPage->GetObjNum()); 617 m_PageList.SetAt(iPage, pPage->GetObjNum());
220 return pPage; 618 return pPage;
221 } 619 }
222 620
223 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, 621 int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode,
224 uint32_t& skip_count, 622 uint32_t& skip_count,
225 uint32_t objnum, 623 uint32_t objnum,
226 int& index, 624 int& index,
227 int level) { 625 int level) {
228 if (pNode->KeyExist("Kids")) { 626 if (!pNode->KeyExist("Kids")) {
229 CPDF_Array* pKidList = pNode->GetArrayBy("Kids"); 627 if (objnum == pNode->GetObjNum())
230 if (!pKidList) { 628 return index;
231 return -1; 629
232 } 630 if (skip_count)
233 if (level >= FX_MAX_PAGE_LEVEL) { 631 skip_count--;
234 return -1; 632
235 } 633 index++;
236 size_t count = pNode->GetIntegerBy("Count"); 634 return -1;
237 if (count <= skip_count) { 635 }
238 skip_count -= count; 636
239 index += count; 637 CPDF_Array* pKidList = pNode->GetArrayBy("Kids");
240 return -1; 638 if (!pKidList)
241 } 639 return -1;
242 if (count && count == pKidList->GetCount()) { 640
243 for (size_t i = 0; i < count; i++) { 641 if (level >= FX_MAX_PAGE_LEVEL)
244 if (CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i))) { 642 return -1;
245 if (pKid->GetRefObjNum() == objnum) { 643
246 m_PageList.SetAt(index + i, objnum); 644 size_t count = pNode->GetIntegerBy("Count");
247 return static_cast<int>(index + i); 645 if (count <= skip_count) {
248 } 646 skip_count -= count;
647 index += count;
648 return -1;
649 }
650
651 if (count && count == pKidList->GetCount()) {
652 for (size_t i = 0; i < count; i++) {
653 if (CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i))) {
654 if (pKid->GetRefObjNum() == objnum) {
655 m_PageList.SetAt(index + i, objnum);
656 return static_cast<int>(index + i);
249 } 657 }
250 } 658 }
251 } 659 }
252 for (size_t i = 0; i < pKidList->GetCount(); i++) { 660 }
253 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); 661
254 if (!pKid) { 662 for (size_t i = 0; i < pKidList->GetCount(); i++) {
255 continue; 663 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
256 } 664 if (!pKid || pKid == pNode)
257 if (pKid == pNode) { 665 continue;
258 continue; 666
259 } 667 int found_index = FindPageIndex(pKid, skip_count, objnum, index, level + 1);
260 int found_index = 668 if (found_index >= 0)
261 _FindPageIndex(pKid, skip_count, objnum, index, level + 1); 669 return found_index;
262 if (found_index >= 0) {
263 return found_index;
264 }
265 }
266 } else {
267 if (objnum == pNode->GetObjNum()) {
268 return index;
269 }
270 if (skip_count) {
271 skip_count--;
272 }
273 index++;
274 } 670 }
275 return -1; 671 return -1;
276 } 672 }
673
277 int CPDF_Document::GetPageIndex(uint32_t objnum) { 674 int CPDF_Document::GetPageIndex(uint32_t objnum) {
278 uint32_t nPages = m_PageList.GetSize(); 675 uint32_t nPages = m_PageList.GetSize();
279 uint32_t skip_count = 0; 676 uint32_t skip_count = 0;
280 FX_BOOL bSkipped = FALSE; 677 bool bSkipped = false;
281 for (uint32_t i = 0; i < nPages; i++) { 678 for (uint32_t i = 0; i < nPages; i++) {
282 uint32_t objnum1 = m_PageList.GetAt(i); 679 uint32_t objnum1 = m_PageList.GetAt(i);
283 if (objnum1 == objnum) { 680 if (objnum1 == objnum)
284 return i; 681 return i;
285 } 682
286 if (!bSkipped && objnum1 == 0) { 683 if (!bSkipped && objnum1 == 0) {
287 skip_count = i; 684 skip_count = i;
288 bSkipped = TRUE; 685 bSkipped = true;
289 } 686 }
290 } 687 }
291 CPDF_Dictionary* pRoot = GetRoot(); 688 CPDF_Dictionary* pRoot = GetRoot();
292 if (!pRoot) { 689 if (!pRoot)
293 return -1; 690 return -1;
294 } 691
295 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); 692 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
296 if (!pPages) { 693 if (!pPages)
297 return -1; 694 return -1;
298 } 695
299 int index = 0; 696 int index = 0;
300 return _FindPageIndex(pPages, skip_count, objnum, index); 697 return FindPageIndex(pPages, skip_count, objnum, index);
301 } 698 }
699
302 int CPDF_Document::GetPageCount() const { 700 int CPDF_Document::GetPageCount() const {
303 return m_PageList.GetSize(); 701 return m_PageList.GetSize();
304 } 702 }
305 703
306 int CPDF_Document::RetrievePageCount() const { 704 int CPDF_Document::RetrievePageCount() const {
307 CPDF_Dictionary* pRoot = GetRoot(); 705 CPDF_Dictionary* pRoot = GetRoot();
308 if (!pRoot) { 706 if (!pRoot)
309 return 0; 707 return 0;
310 } 708
311 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); 709 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
312 if (!pPages) { 710 if (!pPages)
313 return 0; 711 return 0;
314 } 712
315 if (!pPages->KeyExist("Kids")) { 713 if (!pPages->KeyExist("Kids"))
316 return 1; 714 return 1;
317 } 715
318 std::set<CPDF_Dictionary*> visited_pages; 716 std::set<CPDF_Dictionary*> visited_pages;
319 visited_pages.insert(pPages); 717 visited_pages.insert(pPages);
320 return CountPages(pPages, &visited_pages); 718 return CountPages(pPages, &visited_pages);
321 } 719 }
322 720
323 uint32_t CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const { 721 uint32_t CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const {
324 if (!m_pParser) { 722 return m_pParser ? m_pParser->GetPermissions(bCheckRevision)
325 return (uint32_t)-1; 723 : static_cast<uint32_t>(-1);
326 }
327 return m_pParser->GetPermissions(bCheckRevision);
328 } 724 }
329 725
330 FX_BOOL CPDF_Document::IsFormStream(uint32_t objnum, FX_BOOL& bForm) const { 726 FX_BOOL CPDF_Document::IsFormStream(uint32_t objnum, FX_BOOL& bForm) const {
331 auto it = m_IndirectObjs.find(objnum); 727 auto it = m_IndirectObjs.find(objnum);
332 if (it != m_IndirectObjs.end()) { 728 if (it != m_IndirectObjs.end()) {
333 CPDF_Stream* pStream = it->second->AsStream(); 729 CPDF_Stream* pStream = it->second->AsStream();
334 bForm = pStream && pStream->GetDict()->GetStringBy("Subtype") == "Form"; 730 bForm = pStream && pStream->GetDict()->GetStringBy("Subtype") == "Form";
335 return TRUE; 731 return TRUE;
336 } 732 }
337 if (!m_pParser) { 733 if (!m_pParser) {
338 bForm = FALSE; 734 bForm = FALSE;
339 return TRUE; 735 return TRUE;
340 } 736 }
341 return m_pParser->IsFormStream(objnum, bForm); 737 return m_pParser->IsFormStream(objnum, bForm);
342 } 738 }
343 739
740 CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) {
741 ASSERT(pFontDict);
742 return m_pDocPage->GetFont(pFontDict, FALSE);
743 }
744
745 CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) {
746 return m_pDocPage->GetFontFileStreamAcc(pStream);
747 }
748
749 CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj,
750 CPDF_Dictionary* pResources) {
751 return m_pDocPage->GetColorSpace(pCSObj, pResources);
752 }
753
754 CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj,
755 FX_BOOL bShading,
756 const CFX_Matrix* matrix) {
757 return m_pDocPage->GetPattern(pPatternObj, bShading, matrix);
758 }
759
760 CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream) {
761 return m_pDocPage->GetIccProfile(pStream);
762 }
763
764 CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) {
765 if (!pObj)
766 return nullptr;
767
768 FXSYS_assert(pObj->GetObjNum());
769 return m_pDocPage->GetImage(pObj);
770 }
771
772 void CPDF_Document::RemoveColorSpaceFromPageData(CPDF_Object* pCSObj) {
773 if (pCSObj)
774 GetPageData()->ReleaseColorSpace(pCSObj);
775 }
776
344 void CPDF_Document::ClearPageData() { 777 void CPDF_Document::ClearPageData() {
345 if (m_pDocPage) 778 GetPageData()->Clear(FALSE);
346 this->GetPageData()->Clear(FALSE);
347 } 779 }
348 780
349 void CPDF_Document::ClearRenderData() { 781 void CPDF_Document::ClearRenderData() {
350 if (m_pDocRender) 782 m_pDocRender->Clear(FALSE);
351 m_pDocRender->Clear(FALSE);
352 } 783 }
353 784
354 void CPDF_Document::ClearRenderFont() { 785 void CPDF_Document::ClearRenderFont() {
355 if (!m_pDocRender)
356 return;
357
358 CFX_FontCache* pCache = m_pDocRender->GetFontCache(); 786 CFX_FontCache* pCache = m_pDocRender->GetFontCache();
359 if (pCache) 787 if (pCache)
360 pCache->FreeCache(FALSE); 788 pCache->FreeCache(FALSE);
361 } 789 }
790
791 void CPDF_Document::CreateNewDoc() {
792 ASSERT(!m_pRootDict && !m_pInfoDict);
793 m_pRootDict = new CPDF_Dictionary;
794 m_pRootDict->SetAtName("Type", "Catalog");
795 int objnum = AddIndirectObject(m_pRootDict);
796 CPDF_Dictionary* pPages = new CPDF_Dictionary;
797 pPages->SetAtName("Type", "Pages");
798 pPages->SetAtNumber("Count", 0);
799 pPages->SetAt("Kids", new CPDF_Array);
800 objnum = AddIndirectObject(pPages);
801 m_pRootDict->SetAtReference("Pages", this, objnum);
802 m_pInfoDict = new CPDF_Dictionary;
803 AddIndirectObject(m_pInfoDict);
804 }
805
806 CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
807 CPDF_Dictionary* pDict = new CPDF_Dictionary;
808 pDict->SetAtName("Type", "Page");
809 uint32_t dwObjNum = AddIndirectObject(pDict);
810 if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) {
811 ReleaseIndirectObject(dwObjNum);
812 return nullptr;
813 }
814 return pDict;
815 }
816
817 void CPDF_Document::DeletePage(int iPage) {
818 CPDF_Dictionary* pRoot = GetRoot();
819 if (!pRoot)
820 return;
821
822 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
823 if (!pPages)
824 return;
825
826 int nPages = pPages->GetIntegerBy("Count");
827 if (iPage < 0 || iPage >= nPages)
828 return;
829
830 std::set<CPDF_Dictionary*> stack = {pPages};
831 if (InsertDeletePDFPage(this, pPages, iPage, nullptr, FALSE, &stack) < 0)
832 return;
833
834 m_PageList.RemoveAt(iPage);
835 }
836
837 CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font,
838 CPDF_FontEncoding* pEncoding) {
839 CFX_ByteString name(font);
840 if (PDF_GetStandardFontName(&name) < 0)
841 return nullptr;
842 return GetPageData()->GetStandardFont(name.AsStringC(), pEncoding);
843 }
844
845 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) {
846 if (!pFont)
847 return nullptr;
848
849 bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET ||
850 charset == FXFONT_GB2312_CHARSET ||
851 charset == FXFONT_HANGEUL_CHARSET ||
852 charset == FXFONT_SHIFTJIS_CHARSET;
853 CFX_ByteString basefont = pFont->GetFamilyName();
854 basefont.Replace(" ", "");
855 int flags = 0;
856 if (pFont->IsBold())
857 flags |= PDFFONT_FORCEBOLD;
858 if (pFont->IsItalic())
859 flags |= PDFFONT_ITALIC;
860 if (pFont->IsFixedWidth())
861 flags |= PDFFONT_FIXEDPITCH;
862
863 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary;
864 pBaseDict->SetAtName("Type", "Font");
865 std::unique_ptr<CFX_UnicodeEncoding> pEncoding(
866 new CFX_UnicodeEncoding(pFont));
867 CPDF_Dictionary* pFontDict = pBaseDict;
868 if (!bCJK) {
869 CPDF_Array* pWidths = new CPDF_Array;
870 for (int charcode = 32; charcode < 128; charcode++) {
871 int glyph_index = pEncoding->GlyphFromCharCode(charcode);
872 int char_width = pFont->GetGlyphWidth(glyph_index);
873 pWidths->AddInteger(char_width);
874 }
875 if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
876 charset == FXFONT_SYMBOL_CHARSET) {
877 if (charset == FXFONT_SYMBOL_CHARSET) {
878 flags |= PDFFONT_SYMBOLIC;
879 } else {
880 flags |= PDFFONT_NONSYMBOLIC;
881 }
882 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding");
883 for (int charcode = 128; charcode <= 255; charcode++) {
884 int glyph_index = pEncoding->GlyphFromCharCode(charcode);
885 int char_width = pFont->GetGlyphWidth(glyph_index);
886 pWidths->AddInteger(char_width);
887 }
888 } else {
889 flags |= PDFFONT_NONSYMBOLIC;
890 size_t i;
891 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) {
892 if (g_FX_CharsetUnicodes[i].m_Charset == charset)
893 break;
894 }
895 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) {
896 CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary;
897 pEncodingDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
898 CPDF_Array* pArray = new CPDF_Array;
899 pArray->AddInteger(128);
900 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
901 for (int j = 0; j < 128; j++) {
902 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
903 pArray->AddName(name.IsEmpty() ? ".notdef" : name);
904 int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
905 int char_width = pFont->GetGlyphWidth(glyph_index);
906 pWidths->AddInteger(char_width);
907 }
908 pEncodingDict->SetAt("Differences", pArray);
909 AddIndirectObject(pEncodingDict);
910 pBaseDict->SetAtReference("Encoding", this, pEncodingDict);
911 }
912 }
913 if (pFont->IsBold() && pFont->IsItalic())
914 basefont += ",BoldItalic";
915 else if (pFont->IsBold())
916 basefont += ",Bold";
917 else if (pFont->IsItalic())
918 basefont += ",Italic";
919
920 pBaseDict->SetAtName("Subtype", "TrueType");
921 pBaseDict->SetAtName("BaseFont", basefont);
922 pBaseDict->SetAtNumber("FirstChar", 32);
923 pBaseDict->SetAtNumber("LastChar", 255);
924 pBaseDict->SetAt("Widths", pWidths);
925 } else {
926 flags |= PDFFONT_NONSYMBOLIC;
927 pFontDict = new CPDF_Dictionary;
928 CFX_ByteString cmap;
929 CFX_ByteString ordering;
930 int supplement = 0;
931 CPDF_Array* pWidthArray = new CPDF_Array;
932 switch (charset) {
933 case FXFONT_CHINESEBIG5_CHARSET:
934 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
935 ordering = "CNS1";
936 supplement = 4;
937 pWidthArray->AddInteger(1);
938 InsertWidthArray1(pFont, pEncoding.get(), 0x20, 0x7e, pWidthArray);
939 break;
940 case FXFONT_GB2312_CHARSET:
941 cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
942 ordering = "GB1";
943 supplement = 2;
944 pWidthArray->AddInteger(7716);
945 InsertWidthArray1(pFont, pEncoding.get(), 0x20, 0x20, pWidthArray);
946 pWidthArray->AddInteger(814);
947 InsertWidthArray1(pFont, pEncoding.get(), 0x21, 0x7e, pWidthArray);
948 break;
949 case FXFONT_HANGEUL_CHARSET:
950 cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
951 ordering = "Korea1";
952 supplement = 2;
953 pWidthArray->AddInteger(1);
954 InsertWidthArray1(pFont, pEncoding.get(), 0x20, 0x7e, pWidthArray);
955 break;
956 case FXFONT_SHIFTJIS_CHARSET:
957 cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
958 ordering = "Japan1";
959 supplement = 5;
960 pWidthArray->AddInteger(231);
961 InsertWidthArray1(pFont, pEncoding.get(), 0x20, 0x7d, pWidthArray);
962 pWidthArray->AddInteger(326);
963 InsertWidthArray1(pFont, pEncoding.get(), 0xa0, 0xa0, pWidthArray);
964 pWidthArray->AddInteger(327);
965 InsertWidthArray1(pFont, pEncoding.get(), 0xa1, 0xdf, pWidthArray);
966 pWidthArray->AddInteger(631);
967 InsertWidthArray1(pFont, pEncoding.get(), 0x7e, 0x7e, pWidthArray);
968 break;
969 }
970 pBaseDict->SetAtName("Subtype", "Type0");
971 pBaseDict->SetAtName("BaseFont", basefont);
972 pBaseDict->SetAtName("Encoding", cmap);
973 pFontDict->SetAt("W", pWidthArray);
974 pFontDict->SetAtName("Type", "Font");
975 pFontDict->SetAtName("Subtype", "CIDFontType2");
976 pFontDict->SetAtName("BaseFont", basefont);
977 CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary;
978 pCIDSysInfo->SetAtString("Registry", "Adobe");
979 pCIDSysInfo->SetAtString("Ordering", ordering);
980 pCIDSysInfo->SetAtInteger("Supplement", supplement);
981 pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
982 CPDF_Array* pArray = new CPDF_Array;
983 pBaseDict->SetAt("DescendantFonts", pArray);
984 AddIndirectObject(pFontDict);
985 pArray->AddReference(this, pFontDict);
986 }
987 AddIndirectObject(pBaseDict);
988 CPDF_Dictionary* pFontDesc = new CPDF_Dictionary;
989 pFontDesc->SetAtName("Type", "FontDescriptor");
990 pFontDesc->SetAtName("FontName", basefont);
991 pFontDesc->SetAtInteger("Flags", flags);
992 pFontDesc->SetAtInteger(
993 "ItalicAngle",
994 pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0);
995 pFontDesc->SetAtInteger("Ascent", pFont->GetAscent());
996 pFontDesc->SetAtInteger("Descent", pFont->GetDescent());
997 FX_RECT bbox;
998 pFont->GetBBox(bbox);
999 CPDF_Array* pBBox = new CPDF_Array;
1000 pBBox->AddInteger(bbox.left);
1001 pBBox->AddInteger(bbox.bottom);
1002 pBBox->AddInteger(bbox.right);
1003 pBBox->AddInteger(bbox.top);
1004 pFontDesc->SetAt("FontBBox", pBBox);
1005 int32_t nStemV = 0;
1006 if (pFont->GetSubstFont()) {
1007 nStemV = pFont->GetSubstFont()->m_Weight / 5;
1008 } else {
1009 static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'};
1010 const size_t count = FX_ArraySize(stem_chars);
1011 uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]);
1012 nStemV = pFont->GetGlyphWidth(glyph);
1013 for (size_t i = 1; i < count; i++) {
1014 glyph = pEncoding->GlyphFromCharCode(stem_chars[i]);
1015 int width = pFont->GetGlyphWidth(glyph);
1016 if (width > 0 && width < nStemV) {
1017 nStemV = width;
1018 }
1019 }
1020 }
1021 pFontDesc->SetAtInteger("StemV", nStemV);
1022 AddIndirectObject(pFontDesc);
1023 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
1024 return LoadFont(pBaseDict);
1025 }
1026
1027 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
1028 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont,
1029 FX_BOOL bVert,
1030 FX_BOOL bTranslateName) {
1031 LOGFONTA lfa;
1032 FXSYS_memcpy(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa);
1033 CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName);
1034 if (face.GetLength() >= LF_FACESIZE)
1035 return nullptr;
1036
1037 FXSYS_strcpy(lfa.lfFaceName, face.c_str());
1038 return AddWindowsFont(&lfa, bVert, bTranslateName);
1039 }
1040
1041 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
1042 FX_BOOL bVert,
1043 FX_BOOL bTranslateName) {
1044 pLogFont->lfHeight = -1000;
1045 pLogFont->lfWidth = 0;
1046 HGDIOBJ hFont = CreateFontIndirectA(pLogFont);
1047 HDC hDC = CreateCompatibleDC(nullptr);
1048 hFont = SelectObject(hDC, hFont);
1049 int tm_size = GetOutlineTextMetrics(hDC, 0, nullptr);
1050 if (tm_size == 0) {
1051 hFont = SelectObject(hDC, hFont);
1052 DeleteObject(hFont);
1053 DeleteDC(hDC);
1054 return nullptr;
1055 }
1056
1057 LPBYTE tm_buf = FX_Alloc(BYTE, tm_size);
1058 OUTLINETEXTMETRIC* ptm = (OUTLINETEXTMETRIC*)tm_buf;
1059 GetOutlineTextMetrics(hDC, tm_size, ptm);
1060 int flags = 0, italicangle, ascend, descend, capheight, bbox[4];
1061 if (pLogFont->lfItalic)
1062 flags |= PDFFONT_ITALIC;
1063 if ((pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH)
1064 flags |= PDFFONT_FIXEDPITCH;
1065 if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN)
1066 flags |= PDFFONT_SERIF;
1067 if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT)
1068 flags |= PDFFONT_SCRIPT;
1069
1070 bool bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET ||
1071 pLogFont->lfCharSet == GB2312_CHARSET ||
1072 pLogFont->lfCharSet == HANGEUL_CHARSET ||
1073 pLogFont->lfCharSet == SHIFTJIS_CHARSET;
1074 CFX_ByteString basefont;
1075 if (bTranslateName && bCJK)
1076 basefont = FPDF_GetPSNameFromTT(hDC);
1077
1078 if (basefont.IsEmpty())
1079 basefont = pLogFont->lfFaceName;
1080
1081 italicangle = ptm->otmItalicAngle / 10;
1082 ascend = ptm->otmrcFontBox.top;
1083 descend = ptm->otmrcFontBox.bottom;
1084 capheight = ptm->otmsCapEmHeight;
1085 bbox[0] = ptm->otmrcFontBox.left;
1086 bbox[1] = ptm->otmrcFontBox.bottom;
1087 bbox[2] = ptm->otmrcFontBox.right;
1088 bbox[3] = ptm->otmrcFontBox.top;
1089 FX_Free(tm_buf);
1090 basefont.Replace(" ", "");
1091 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary;
1092 pBaseDict->SetAtName("Type", "Font");
1093 CPDF_Dictionary* pFontDict = pBaseDict;
1094 if (!bCJK) {
1095 if (pLogFont->lfCharSet == ANSI_CHARSET ||
1096 pLogFont->lfCharSet == DEFAULT_CHARSET ||
1097 pLogFont->lfCharSet == SYMBOL_CHARSET) {
1098 if (pLogFont->lfCharSet == SYMBOL_CHARSET)
1099 flags |= PDFFONT_SYMBOLIC;
1100 else
1101 flags |= PDFFONT_NONSYMBOLIC;
1102 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding");
1103 } else {
1104 flags |= PDFFONT_NONSYMBOLIC;
1105 int i;
1106 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) {
1107 if (g_FX_CharsetUnicodes[i].m_Charset == pLogFont->lfCharSet)
1108 break;
1109 }
1110 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) {
1111 CPDF_Dictionary* pEncoding = new CPDF_Dictionary;
1112 pEncoding->SetAtName("BaseEncoding", "WinAnsiEncoding");
1113 CPDF_Array* pArray = new CPDF_Array;
1114 pArray->AddInteger(128);
1115 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
1116 for (int j = 0; j < 128; j++) {
1117 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
1118 pArray->AddName(name.IsEmpty() ? ".notdef" : name);
1119 }
1120 pEncoding->SetAt("Differences", pArray);
1121 AddIndirectObject(pEncoding);
1122 pBaseDict->SetAtReference("Encoding", this, pEncoding);
1123 }
1124 }
1125 if (pLogFont->lfWeight > FW_MEDIUM && pLogFont->lfItalic)
1126 basefont += ",BoldItalic";
1127 else if (pLogFont->lfWeight > FW_MEDIUM)
1128 basefont += ",Bold";
1129 else if (pLogFont->lfItalic)
1130 basefont += ",Italic";
1131
1132 pBaseDict->SetAtName("Subtype", "TrueType");
1133 pBaseDict->SetAtName("BaseFont", basefont);
1134 pBaseDict->SetAtNumber("FirstChar", 32);
1135 pBaseDict->SetAtNumber("LastChar", 255);
1136 int char_widths[224];
1137 GetCharWidth(hDC, 32, 255, char_widths);
1138 CPDF_Array* pWidths = new CPDF_Array;
1139 for (int i = 0; i < 224; i++)
1140 pWidths->AddInteger(char_widths[i]);
1141
1142 pBaseDict->SetAt("Widths", pWidths);
1143 } else {
1144 flags |= PDFFONT_NONSYMBOLIC;
1145 pFontDict = new CPDF_Dictionary;
1146 CFX_ByteString cmap;
1147 CFX_ByteString ordering;
1148 int supplement = 0;
1149 CPDF_Array* pWidthArray = new CPDF_Array;
1150 switch (pLogFont->lfCharSet) {
1151 case CHINESEBIG5_CHARSET:
1152 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
1153 ordering = "CNS1";
1154 supplement = 4;
1155 pWidthArray->AddInteger(1);
1156 InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray);
1157 break;
1158 case GB2312_CHARSET:
1159 cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
1160 ordering = "GB1", supplement = 2;
1161 pWidthArray->AddInteger(7716);
1162 InsertWidthArray(hDC, 0x20, 0x20, pWidthArray);
1163 pWidthArray->AddInteger(814);
1164 InsertWidthArray(hDC, 0x21, 0x7e, pWidthArray);
1165 break;
1166 case HANGEUL_CHARSET:
1167 cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
1168 ordering = "Korea1";
1169 supplement = 2;
1170 pWidthArray->AddInteger(1);
1171 InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray);
1172 break;
1173 case SHIFTJIS_CHARSET:
1174 cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
1175 ordering = "Japan1";
1176 supplement = 5;
1177 pWidthArray->AddInteger(231);
1178 InsertWidthArray(hDC, 0x20, 0x7d, pWidthArray);
1179 pWidthArray->AddInteger(326);
1180 InsertWidthArray(hDC, 0xa0, 0xa0, pWidthArray);
1181 pWidthArray->AddInteger(327);
1182 InsertWidthArray(hDC, 0xa1, 0xdf, pWidthArray);
1183 pWidthArray->AddInteger(631);
1184 InsertWidthArray(hDC, 0x7e, 0x7e, pWidthArray);
1185 break;
1186 }
1187 pBaseDict->SetAtName("Subtype", "Type0");
1188 pBaseDict->SetAtName("BaseFont", basefont);
1189 pBaseDict->SetAtName("Encoding", cmap);
1190 pFontDict->SetAt("W", pWidthArray);
1191 pFontDict->SetAtName("Type", "Font");
1192 pFontDict->SetAtName("Subtype", "CIDFontType2");
1193 pFontDict->SetAtName("BaseFont", basefont);
1194 CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary;
1195 pCIDSysInfo->SetAtString("Registry", "Adobe");
1196 pCIDSysInfo->SetAtString("Ordering", ordering);
1197 pCIDSysInfo->SetAtInteger("Supplement", supplement);
1198 pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
1199 CPDF_Array* pArray = new CPDF_Array;
1200 pBaseDict->SetAt("DescendantFonts", pArray);
1201 AddIndirectObject(pFontDict);
1202 pArray->AddReference(this, pFontDict);
1203 }
1204 AddIndirectObject(pBaseDict);
1205 CPDF_Dictionary* pFontDesc = new CPDF_Dictionary;
1206 pFontDesc->SetAtName("Type", "FontDescriptor");
1207 pFontDesc->SetAtName("FontName", basefont);
1208 pFontDesc->SetAtInteger("Flags", flags);
1209 CPDF_Array* pBBox = new CPDF_Array;
1210 for (int i = 0; i < 4; i++) {
1211 pBBox->AddInteger(bbox[i]);
1212 }
1213 pFontDesc->SetAt("FontBBox", pBBox);
1214 pFontDesc->SetAtInteger("ItalicAngle", italicangle);
1215 pFontDesc->SetAtInteger("Ascent", ascend);
1216 pFontDesc->SetAtInteger("Descent", descend);
1217 pFontDesc->SetAtInteger("CapHeight", capheight);
1218 pFontDesc->SetAtInteger("StemV", pLogFont->lfWeight / 5);
1219 AddIndirectObject(pFontDesc);
1220 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
1221 hFont = SelectObject(hDC, hFont);
1222 DeleteObject(hFont);
1223 DeleteDC(hDC);
1224 return LoadFont(pBaseDict);
1225 }
1226 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
1227
1228 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1229 CPDF_Font* CPDF_Document::AddMacFont(CTFontRef pFont,
1230 FX_BOOL bVert,
1231 FX_BOOL bTranslateName) {
1232 CTFontRef font = (CTFontRef)pFont;
1233 CTFontDescriptorRef descriptor = CTFontCopyFontDescriptor(font);
1234 if (!descriptor)
1235 return nullptr;
1236
1237 CFArrayRef languages = (CFArrayRef)CTFontDescriptorCopyAttribute(
1238 descriptor, kCTFontLanguagesAttribute);
1239 if (!languages) {
1240 CFRelease(descriptor);
1241 return nullptr;
1242 }
1243
1244 bool bCJK =
1245 HasCharSet(languages, {FXFONT_CHINESEBIG5_CHARSET, FXFONT_GB2312_CHARSET,
1246 FXFONT_HANGEUL_CHARSET, FXFONT_SHIFTJIS_CHARSET});
1247 CFRelease(descriptor);
1248 CFDictionaryRef traits = (CFDictionaryRef)CTFontCopyTraits(font);
1249 if (!traits) {
1250 CFRelease(languages);
1251 return nullptr;
1252 }
1253
1254 CFNumberRef sybolicTrait =
1255 (CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait);
1256 CTFontSymbolicTraits trait = 0;
1257 CFNumberGetValue(sybolicTrait, kCFNumberSInt32Type, &trait);
1258 int flags = 0;
1259 if (trait & kCTFontItalicTrait)
1260 flags |= PDFFONT_ITALIC;
1261 if (trait & kCTFontMonoSpaceTrait)
1262 flags |= PDFFONT_FIXEDPITCH;
1263 if (trait & kCTFontModernSerifsClass)
1264 flags |= PDFFONT_SERIF;
1265 if (trait & kCTFontScriptsClass)
1266 flags |= PDFFONT_SCRIPT;
1267
1268 CFNumberRef weightTrait =
1269 (CFNumberRef)CFDictionaryGetValue(traits, kCTFontWeightTrait);
1270 Float32 weight = 0;
1271 CFNumberGetValue(weightTrait, kCFNumberFloat32Type, &weight);
1272 int italicangle = CTFontGetSlantAngle(font);
1273 int ascend = CTFontGetAscent(font);
1274 int descend = CTFontGetDescent(font);
1275 int capheight = CTFontGetCapHeight(font);
1276 CGRect box = CTFontGetBoundingBox(font);
1277 int bbox[4];
1278 bbox[0] = box.origin.x;
1279 bbox[1] = box.origin.y;
1280 bbox[2] = box.origin.x + box.size.width;
1281 bbox[3] = box.origin.y + box.size.height;
1282 CFX_ByteString basefont;
1283 if (bTranslateName && bCJK) {
1284 CFStringRef postName = CTFontCopyPostScriptName(font);
1285 CFString2CFXByteString(postName, basefont);
1286 CFRelease(postName);
1287 }
1288 if (basefont.IsEmpty()) {
1289 CFStringRef fullName = CTFontCopyFullName(font);
1290 CFString2CFXByteString(fullName, basefont);
1291 CFRelease(fullName);
1292 }
1293 basefont.Replace(" ", "");
1294 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary;
1295 CPDF_Dictionary* pFontDict = pBaseDict;
1296 if (!bCJK) {
1297 if (HasCharSet(languages, {FXFONT_ANSI_CHARSET, FXFONT_DEFAULT_CHARSET,
1298 FXFONT_SYMBOL_CHARSET})) {
1299 if (HasCharSet(languages, {FXFONT_SYMBOL_CHARSET})) {
1300 flags |= PDFFONT_SYMBOLIC;
1301 } else {
1302 flags |= PDFFONT_NONSYMBOLIC;
1303 }
1304 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding");
1305 } else {
1306 flags |= PDFFONT_NONSYMBOLIC;
1307 size_t i;
1308 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) {
1309 if (HasCharSet(languages, {g_FX_CharsetUnicodes[i].m_Charset}))
1310 break;
1311 }
1312 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) {
1313 CPDF_Dictionary* pEncoding = new CPDF_Dictionary;
1314 pEncoding->SetAtName("BaseEncoding", "WinAnsiEncoding");
1315 CPDF_Array* pArray = new CPDF_Array;
1316 pArray->AddInteger(128);
1317 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
1318 for (int j = 0; j < 128; j++) {
1319 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
1320 pArray->AddName(name.IsEmpty() ? ".notdef" : name);
1321 }
1322 pEncoding->SetAt("Differences", pArray);
1323 AddIndirectObject(pEncoding);
1324 pBaseDict->SetAtReference("Encoding", this, pEncoding);
1325 }
1326 }
1327 if (weight > 0.0 && trait & kCTFontItalicTrait)
1328 basefont += ",BoldItalic";
1329 else if (weight > 0.0)
1330 basefont += ",Bold";
1331 else if (trait & kCTFontItalicTrait)
1332 basefont += ",Italic";
1333
1334 pBaseDict->SetAtName("Subtype", "TrueType");
1335 pBaseDict->SetAtName("BaseFont", basefont);
1336 pBaseDict->SetAtNumber("FirstChar", 32);
1337 pBaseDict->SetAtNumber("LastChar", 255);
1338 int char_widths[224];
1339 FX_GetCharWidth(font, 32, 255, char_widths);
1340 CPDF_Array* pWidths = new CPDF_Array;
1341 for (int i = 0; i < 224; i++)
1342 pWidths->AddInteger(char_widths[i]);
1343 pBaseDict->SetAt("Widths", pWidths);
1344 } else {
1345 flags |= PDFFONT_NONSYMBOLIC;
1346 CFX_ByteString cmap;
1347 CFX_ByteString ordering;
1348 int supplement;
1349 bool bFound = false;
1350 CPDF_Array* pWidthArray = new CPDF_Array;
1351 if (HasCharSet(languages, {FXFONT_CHINESEBIG5_CHARSET})) {
1352 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
1353 ordering = "CNS1";
1354 supplement = 4;
1355 pWidthArray->AddInteger(1);
1356 InsertWidthArray(font, 0x20, 0x7e, pWidthArray);
1357 bFound = true;
1358 }
1359 if (!bFound && HasCharSet(languages, {FXFONT_GB2312_CHARSET})) {
1360 cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
1361 ordering = "GB1", supplement = 2;
1362 pWidthArray->AddInteger(7716);
1363 InsertWidthArray(font, 0x20, 0x20, pWidthArray);
1364 pWidthArray->AddInteger(814);
1365 InsertWidthArray(font, 0x21, 0x7e, pWidthArray);
1366 bFound = true;
1367 }
1368 if (!bFound && HasCharSet(languages, {FXFONT_HANGEUL_CHARSET})) {
1369 cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
1370 ordering = "Korea1";
1371 supplement = 2;
1372 pWidthArray->AddInteger(1);
1373 InsertWidthArray(font, 0x20, 0x7e, pWidthArray);
1374 bFound = true;
1375 }
1376 if (!bFound && HasCharSet(languages, {FXFONT_SHIFTJIS_CHARSET})) {
1377 cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
1378 ordering = "Japan1";
1379 supplement = 5;
1380 pWidthArray->AddInteger(231);
1381 InsertWidthArray(font, 0x20, 0x7d, pWidthArray);
1382 pWidthArray->AddInteger(326);
1383 InsertWidthArray(font, 0xa0, 0xa0, pWidthArray);
1384 pWidthArray->AddInteger(327);
1385 InsertWidthArray(font, 0xa1, 0xdf, pWidthArray);
1386 pWidthArray->AddInteger(631);
1387 InsertWidthArray(font, 0x7e, 0x7e, pWidthArray);
1388 }
1389 pBaseDict->SetAtName("Subtype", "Type0");
1390 pBaseDict->SetAtName("BaseFont", basefont);
1391 pBaseDict->SetAtName("Encoding", cmap);
1392
1393 pFontDict = new CPDF_Dictionary;
1394 pFontDict->SetAt("W", pWidthArray);
1395 pFontDict->SetAtName("Type", "Font");
1396 pFontDict->SetAtName("Subtype", "CIDFontType2");
1397 pFontDict->SetAtName("BaseFont", basefont);
1398 CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary;
1399 pCIDSysInfo->SetAtString("Registry", "Adobe");
1400 pCIDSysInfo->SetAtString("Ordering", ordering);
1401 pCIDSysInfo->SetAtInteger("Supplement", supplement);
1402 pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
1403 CPDF_Array* pArray = new CPDF_Array;
1404 pBaseDict->SetAt("DescendantFonts", pArray);
1405 AddIndirectObject(pFontDict);
1406 pArray->AddReference(this, pFontDict);
1407 }
1408 AddIndirectObject(pBaseDict);
1409 CPDF_Dictionary* pFontDesc = new CPDF_Dictionary;
1410 pFontDesc->SetAtName("Type", "FontDescriptor");
1411 pFontDesc->SetAtName("FontName", basefont);
1412 pFontDesc->SetAtInteger("Flags", flags);
1413 CPDF_Array* pBBox = new CPDF_Array;
1414 for (int i = 0; i < 4; i++)
1415 pBBox->AddInteger(bbox[i]);
1416
1417 pFontDesc->SetAt("FontBBox", pBBox);
1418 pFontDesc->SetAtInteger("ItalicAngle", italicangle);
1419 pFontDesc->SetAtInteger("Ascent", ascend);
1420 pFontDesc->SetAtInteger("Descent", descend);
1421 pFontDesc->SetAtInteger("CapHeight", capheight);
1422 CGFloat fStemV = 0;
1423 int16_t min_width = SHRT_MAX;
1424
1425 static const UniChar stem_chars[] = {'i', 'I', '!', '1'};
1426 CGGlyph glyphs[FX_ArraySize(stem_chars)];
1427 CGRect boundingRects[FX_ArraySize(stem_chars)];
1428
1429 const size_t count = FX_ArraySize(stem_chars);
1430 if (CTFontGetGlyphsForCharacters(font, stem_chars, glyphs, count)) {
1431 CTFontGetBoundingRectsForGlyphs(font, kCTFontHorizontalOrientation, glyphs,
1432 boundingRects, count);
1433 for (size_t i = 0; i < count; i++) {
1434 int16_t width = boundingRects[i].size.width;
1435 if (width > 0 && width < min_width) {
1436 min_width = width;
1437 fStemV = min_width;
1438 }
1439 }
1440 }
1441 pFontDesc->SetAtInteger("StemV", fStemV);
1442 AddIndirectObject(pFontDesc);
1443 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
1444 CFRelease(traits);
1445 CFRelease(languages);
1446 return LoadFont(pBaseDict);
1447 }
1448 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_page/fpdf_page_doc.cpp ('k') | core/fpdfapi/fpdf_parser/include/cpdf_document.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698