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

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

Issue 2392603004: Move core/fpdfapi/fpdf_parser to core/fpdfapi/parser (Closed)
Patch Set: Rebase to master Created 4 years, 2 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
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_document.h ('k') | core/fpdfapi/fpdf_parser/cpdf_hint_tables.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fpdfapi/fpdf_parser/cpdf_document.h"
8
9 #include <memory>
10 #include <set>
11 #include <vector>
12
13 #include "core/fpdfapi/cpdf_modulemgr.h"
14 #include "core/fpdfapi/font/cpdf_fontencoding.h"
15 #include "core/fpdfapi/fpdf_parser/cpdf_array.h"
16 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
17 #include "core/fpdfapi/fpdf_parser/cpdf_parser.h"
18 #include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
19 #include "core/fpdfapi/fpdf_parser/cpdf_stream.h"
20 #include "core/fpdfapi/fpdf_render/render_int.h"
21 #include "core/fpdfapi/page/cpdf_pagemodule.h"
22 #include "core/fpdfapi/page/pageint.h"
23 #include "core/fxcodec/JBig2_DocumentContext.h"
24 #include "core/fxge/cfx_unicodeencoding.h"
25 #include "core/fxge/fx_font.h"
26 #include "third_party/base/ptr_util.h"
27 #include "third_party/base/stl_util.h"
28
29 namespace {
30
31 const int FX_MAX_PAGE_LEVEL = 1024;
32
33 const uint16_t g_FX_CP874Unicodes[128] = {
34 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x0000,
35 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
36 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x0000, 0x0000,
37 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0E01, 0x0E02, 0x0E03,
38 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C,
39 0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15,
40 0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E,
41 0x0E1F, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
42 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, 0x0E30,
43 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39,
44 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, 0x0E40, 0x0E41, 0x0E42,
45 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B,
46 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54,
47 0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000,
48 0x0000, 0x0000,
49 };
50 const uint16_t g_FX_CP1250Unicodes[128] = {
51 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
52 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0000, 0x2018,
53 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161,
54 0x203A, 0x015B, 0x0165, 0x017E, 0x017A, 0x00A0, 0x02C7, 0x02D8, 0x0141,
55 0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC,
56 0x00AD, 0x00AE, 0x017B, 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5,
57 0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E,
58 0x017C, 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
59 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 0x0110,
60 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E,
61 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 0x0155, 0x00E1, 0x00E2,
62 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB,
63 0x011B, 0x00ED, 0x00EE, 0x010F, 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4,
64 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD,
65 0x0163, 0x02D9,
66 };
67 const uint16_t g_FX_CP1251Unicodes[128] = {
68 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC,
69 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018,
70 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459,
71 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408,
72 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC,
73 0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5,
74 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455,
75 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
76 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
77 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429,
78 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432,
79 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
80 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444,
81 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D,
82 0x044E, 0x044F,
83 };
84 const uint16_t g_FX_CP1253Unicodes[128] = {
85 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
86 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
87 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
88 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0385, 0x0386, 0x00A3,
89 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC,
90 0x00AD, 0x00AE, 0x2015, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5,
91 0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E,
92 0x038F, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
93 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
94 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
95 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03B1, 0x03B2,
96 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
97 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4,
98 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD,
99 0x03CE, 0x0000,
100 };
101 const uint16_t g_FX_CP1254Unicodes[128] = {
102 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
103 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
104 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161,
105 0x203A, 0x0153, 0x0000, 0x0000, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
106 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC,
107 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
108 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
109 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
110 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x011E,
111 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9,
112 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, 0x00E0, 0x00E1, 0x00E2,
113 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
114 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4,
115 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131,
116 0x015F, 0x00FF,
117 };
118 const uint16_t g_FX_CP1255Unicodes[128] = {
119 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
120 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
121 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0000,
122 0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
123 0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC,
124 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
125 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
126 0x00BF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
127 0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, 0x05C0,
128 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x0000,
129 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05D0, 0x05D1, 0x05D2,
130 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB,
131 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4,
132 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E,
133 0x200F, 0x0000,
134 };
135 const uint16_t g_FX_CP1256Unicodes[128] = {
136 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
137 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x06AF, 0x2018,
138 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691,
139 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, 0x00A0, 0x060C, 0x00A2, 0x00A3,
140 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC,
141 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
142 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
143 0x061F, 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
144 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630,
145 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638,
146 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, 0x00E0, 0x0644, 0x00E2,
147 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
148 0x0649, 0x064A, 0x00EE, 0x00EF, 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4,
149 0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E,
150 0x200F, 0x06D2,
151 };
152 const uint16_t g_FX_CP1257Unicodes[128] = {
153 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
154 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, 0x0000, 0x2018,
155 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
156 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, 0x00A0, 0x0000, 0x00A2, 0x00A3,
157 0x00A4, 0x0000, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC,
158 0x00AD, 0x00AE, 0x00C6, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
159 0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
160 0x00E6, 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
161 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, 0x0160,
162 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141,
163 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, 0x0105, 0x012F, 0x0101,
164 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117,
165 0x0123, 0x0137, 0x012B, 0x013C, 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D,
166 0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C,
167 0x017E, 0x02D9,
168 };
169
170 struct FX_CharsetUnicodes {
171 uint8_t m_Charset;
172 const uint16_t* m_pUnicodes;
173 };
174
175 const FX_CharsetUnicodes g_FX_CharsetUnicodes[] = {
176 {FXFONT_THAI_CHARSET, g_FX_CP874Unicodes},
177 {FXFONT_EASTEUROPE_CHARSET, g_FX_CP1250Unicodes},
178 {FXFONT_RUSSIAN_CHARSET, g_FX_CP1251Unicodes},
179 {FXFONT_GREEK_CHARSET, g_FX_CP1253Unicodes},
180 {FXFONT_TURKISH_CHARSET, g_FX_CP1254Unicodes},
181 {FXFONT_HEBREW_CHARSET, g_FX_CP1255Unicodes},
182 {FXFONT_ARABIC_CHARSET, g_FX_CP1256Unicodes},
183 {FXFONT_BALTIC_CHARSET, g_FX_CP1257Unicodes},
184 };
185
186 void InsertWidthArrayImpl(int* widths, int size, CPDF_Array* pWidthArray) {
187 int i;
188 for (i = 1; i < size; i++) {
189 if (widths[i] != *widths)
190 break;
191 }
192 if (i == size) {
193 int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1);
194 pWidthArray->AddInteger(first + size - 1);
195 pWidthArray->AddInteger(*widths);
196 } else {
197 CPDF_Array* pWidthArray1 = new CPDF_Array;
198 pWidthArray->Add(pWidthArray1);
199 for (i = 0; i < size; i++)
200 pWidthArray1->AddInteger(widths[i]);
201 }
202 FX_Free(widths);
203 }
204
205 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
206 void InsertWidthArray(HDC hDC, int start, int end, CPDF_Array* pWidthArray) {
207 int size = end - start + 1;
208 int* widths = FX_Alloc(int, size);
209 GetCharWidth(hDC, start, end, widths);
210 InsertWidthArrayImpl(widths, size, pWidthArray);
211 }
212
213 CFX_ByteString FPDF_GetPSNameFromTT(HDC hDC) {
214 CFX_ByteString result;
215 DWORD size = ::GetFontData(hDC, 'eman', 0, nullptr, 0);
216 if (size != GDI_ERROR) {
217 LPBYTE buffer = FX_Alloc(BYTE, size);
218 ::GetFontData(hDC, 'eman', 0, buffer, size);
219 result = GetNameFromTT(buffer, size, 6);
220 FX_Free(buffer);
221 }
222 return result;
223 }
224 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
225
226 void InsertWidthArray1(CFX_Font* pFont,
227 CFX_UnicodeEncoding* pEncoding,
228 FX_WCHAR start,
229 FX_WCHAR end,
230 CPDF_Array* pWidthArray) {
231 int size = end - start + 1;
232 int* widths = FX_Alloc(int, size);
233 int i;
234 for (i = 0; i < size; i++) {
235 int glyph_index = pEncoding->GlyphFromCharCode(start + i);
236 widths[i] = pFont->GetGlyphWidth(glyph_index);
237 }
238 InsertWidthArrayImpl(widths, size, pWidthArray);
239 }
240
241 int InsertDeletePDFPage(CPDF_Document* pDoc,
242 CPDF_Dictionary* pPages,
243 int nPagesToGo,
244 CPDF_Dictionary* pPage,
245 FX_BOOL bInsert,
246 std::set<CPDF_Dictionary*>* pVisited) {
247 CPDF_Array* pKidList = pPages->GetArrayFor("Kids");
248 if (!pKidList)
249 return -1;
250
251 for (size_t i = 0; i < pKidList->GetCount(); i++) {
252 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
253 if (pKid->GetStringFor("Type") == "Page") {
254 if (nPagesToGo == 0) {
255 if (bInsert) {
256 pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum()));
257 pPage->SetReferenceFor("Parent", pDoc, pPages->GetObjNum());
258 } else {
259 pKidList->RemoveAt(i);
260 }
261 pPages->SetIntegerFor(
262 "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
263 return 1;
264 }
265 nPagesToGo--;
266 } else {
267 int nPages = pKid->GetIntegerFor("Count");
268 if (nPagesToGo < nPages) {
269 if (pdfium::ContainsKey(*pVisited, pKid))
270 return -1;
271
272 pdfium::ScopedSetInsertion<CPDF_Dictionary*> insertion(pVisited, pKid);
273 if (InsertDeletePDFPage(pDoc, pKid, nPagesToGo, pPage, bInsert,
274 pVisited) < 0) {
275 return -1;
276 }
277 pPages->SetIntegerFor(
278 "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1));
279 return 1;
280 }
281 nPagesToGo -= nPages;
282 }
283 }
284 return 0;
285 }
286
287 int InsertNewPage(CPDF_Document* pDoc,
288 int iPage,
289 CPDF_Dictionary* pPageDict,
290 CFX_ArrayTemplate<uint32_t>& pageList) {
291 CPDF_Dictionary* pRoot = pDoc->GetRoot();
292 CPDF_Dictionary* pPages = pRoot ? pRoot->GetDictFor("Pages") : nullptr;
293 if (!pPages)
294 return -1;
295
296 int nPages = pDoc->GetPageCount();
297 if (iPage < 0 || iPage > nPages)
298 return -1;
299
300 if (iPage == nPages) {
301 CPDF_Array* pPagesList = pPages->GetArrayFor("Kids");
302 if (!pPagesList) {
303 pPagesList = new CPDF_Array;
304 pPages->SetFor("Kids", pPagesList);
305 }
306 pPagesList->Add(new CPDF_Reference(pDoc, pPageDict->GetObjNum()));
307 pPages->SetIntegerFor("Count", nPages + 1);
308 pPageDict->SetReferenceFor("Parent", pDoc, pPages->GetObjNum());
309 } else {
310 std::set<CPDF_Dictionary*> stack = {pPages};
311 if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0)
312 return -1;
313 }
314 pageList.InsertAt(iPage, pPageDict->GetObjNum());
315 return iPage;
316 }
317
318 int CountPages(CPDF_Dictionary* pPages,
319 std::set<CPDF_Dictionary*>* visited_pages) {
320 int count = pPages->GetIntegerFor("Count");
321 if (count > 0 && count < FPDF_PAGE_MAX_NUM)
322 return count;
323 CPDF_Array* pKidList = pPages->GetArrayFor("Kids");
324 if (!pKidList)
325 return 0;
326 count = 0;
327 for (size_t i = 0; i < pKidList->GetCount(); i++) {
328 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
329 if (!pKid || pdfium::ContainsKey(*visited_pages, pKid))
330 continue;
331 if (pKid->KeyExist("Kids")) {
332 // Use |visited_pages| to help detect circular references of pages.
333 pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages,
334 pKid);
335 count += CountPages(pKid, visited_pages);
336 } else {
337 // This page is a leaf node.
338 count++;
339 }
340 }
341 pPages->SetIntegerFor("Count", count);
342 return count;
343 }
344
345 int CalculateFlags(bool bold,
346 bool italic,
347 bool fixedPitch,
348 bool serif,
349 bool script,
350 bool symbolic) {
351 int flags = 0;
352 if (bold)
353 flags |= PDFFONT_FORCEBOLD;
354 if (italic)
355 flags |= PDFFONT_ITALIC;
356 if (fixedPitch)
357 flags |= PDFFONT_FIXEDPITCH;
358 if (serif)
359 flags |= PDFFONT_SERIF;
360 if (script)
361 flags |= PDFFONT_SCRIPT;
362 if (symbolic)
363 flags |= PDFFONT_SYMBOLIC;
364 else
365 flags |= PDFFONT_NONSYMBOLIC;
366 return flags;
367 }
368
369 void ProcessNonbCJK(CPDF_Dictionary* pBaseDict,
370 bool bold,
371 bool italic,
372 CFX_ByteString basefont,
373 CPDF_Array* pWidths) {
374 if (bold && italic)
375 basefont += ",BoldItalic";
376 else if (bold)
377 basefont += ",Bold";
378 else if (italic)
379 basefont += ",Italic";
380 pBaseDict->SetNameFor("Subtype", "TrueType");
381 pBaseDict->SetNameFor("BaseFont", basefont);
382 pBaseDict->SetNumberFor("FirstChar", 32);
383 pBaseDict->SetNumberFor("LastChar", 255);
384 pBaseDict->SetFor("Widths", pWidths);
385 }
386
387 CPDF_Dictionary* CalculateFontDesc(CPDF_Document* pDoc,
388 CFX_ByteString basefont,
389 int flags,
390 int italicangle,
391 int ascend,
392 int descend,
393 CPDF_Array* bbox,
394 int32_t stemV) {
395 CPDF_Dictionary* pFontDesc = new CPDF_Dictionary(pDoc->GetByteStringPool());
396 pFontDesc->SetNameFor("Type", "FontDescriptor");
397 pFontDesc->SetNameFor("FontName", basefont);
398 pFontDesc->SetIntegerFor("Flags", flags);
399 pFontDesc->SetFor("FontBBox", bbox);
400 pFontDesc->SetIntegerFor("ItalicAngle", italicangle);
401 pFontDesc->SetIntegerFor("Ascent", ascend);
402 pFontDesc->SetIntegerFor("Descent", descend);
403 pFontDesc->SetIntegerFor("StemV", stemV);
404 return pFontDesc;
405 }
406
407 } // namespace
408
409 CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser)
410 : CPDF_IndirectObjectHolder(),
411 m_pParser(std::move(pParser)),
412 m_pRootDict(nullptr),
413 m_pInfoDict(nullptr),
414 m_bLinearized(false),
415 m_iFirstPageNo(0),
416 m_dwFirstPageObjNum(0),
417 m_pDocPage(new CPDF_DocPageData(this)),
418 m_pDocRender(new CPDF_DocRenderData(this)),
419 m_pByteStringPool(pdfium::MakeUnique<CFX_ByteStringPool>()) {
420 if (pParser)
421 SetLastObjNum(m_pParser->GetLastObjNum());
422 }
423
424 CPDF_Document::~CPDF_Document() {
425 delete m_pDocPage;
426 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
427 m_pByteStringPool.DeleteObject(); // Make weak.
428 }
429
430 CPDF_Object* CPDF_Document::ParseIndirectObject(uint32_t objnum) {
431 return m_pParser ? m_pParser->ParseIndirectObject(this, objnum) : nullptr;
432 }
433
434 void CPDF_Document::LoadDocInternal() {
435 SetLastObjNum(m_pParser->GetLastObjNum());
436
437 CPDF_Object* pRootObj = GetOrParseIndirectObject(m_pParser->GetRootObjNum());
438 if (!pRootObj)
439 return;
440
441 m_pRootDict = pRootObj->GetDict();
442 if (!m_pRootDict)
443 return;
444
445 CPDF_Object* pInfoObj = GetOrParseIndirectObject(m_pParser->GetInfoObjNum());
446 if (pInfoObj)
447 m_pInfoDict = pInfoObj->GetDict();
448 }
449
450 void CPDF_Document::LoadDoc() {
451 LoadDocInternal();
452 m_PageList.SetSize(RetrievePageCount());
453 }
454
455 void CPDF_Document::LoadLinearizedDoc(CPDF_Dictionary* pLinearizationParams) {
456 m_bLinearized = true;
457 LoadDocInternal();
458
459 uint32_t dwPageCount = 0;
460 CPDF_Object* pCount = pLinearizationParams->GetObjectFor("N");
461 if (ToNumber(pCount))
462 dwPageCount = pCount->GetInteger();
463 m_PageList.SetSize(dwPageCount);
464
465 CPDF_Object* pNo = pLinearizationParams->GetObjectFor("P");
466 if (ToNumber(pNo))
467 m_iFirstPageNo = pNo->GetInteger();
468
469 CPDF_Object* pObjNum = pLinearizationParams->GetObjectFor("O");
470 if (ToNumber(pObjNum))
471 m_dwFirstPageObjNum = pObjNum->GetInteger();
472 }
473
474 void CPDF_Document::LoadPages() {
475 m_PageList.SetSize(RetrievePageCount());
476 }
477
478 CPDF_Dictionary* CPDF_Document::FindPDFPage(CPDF_Dictionary* pPages,
479 int iPage,
480 int nPagesToGo,
481 int level) {
482 CPDF_Array* pKidList = pPages->GetArrayFor("Kids");
483 if (!pKidList)
484 return nPagesToGo == 0 ? pPages : nullptr;
485
486 if (level >= FX_MAX_PAGE_LEVEL)
487 return nullptr;
488
489 for (size_t i = 0; i < pKidList->GetCount(); i++) {
490 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
491 if (!pKid) {
492 nPagesToGo--;
493 continue;
494 }
495 if (pKid == pPages)
496 continue;
497 if (!pKid->KeyExist("Kids")) {
498 if (nPagesToGo == 0)
499 return pKid;
500
501 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum());
502 nPagesToGo--;
503 } else {
504 int nPages = pKid->GetIntegerFor("Count");
505 if (nPagesToGo < nPages)
506 return FindPDFPage(pKid, iPage, nPagesToGo, level + 1);
507
508 nPagesToGo -= nPages;
509 }
510 }
511 return nullptr;
512 }
513
514 CPDF_Dictionary* CPDF_Document::GetPagesDict() const {
515 CPDF_Dictionary* pRoot = GetRoot();
516 return pRoot ? pRoot->GetDictFor("Pages") : nullptr;
517 }
518
519 bool CPDF_Document::IsPageLoaded(int iPage) const {
520 return !!m_PageList.GetAt(iPage);
521 }
522
523 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) {
524 if (iPage < 0 || iPage >= m_PageList.GetSize())
525 return nullptr;
526
527 if (m_bLinearized && (iPage == m_iFirstPageNo)) {
528 if (CPDF_Dictionary* pDict =
529 ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) {
530 return pDict;
531 }
532 }
533
534 int objnum = m_PageList.GetAt(iPage);
535 if (objnum) {
536 if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum)))
537 return pDict;
538 }
539
540 CPDF_Dictionary* pPages = GetPagesDict();
541 if (!pPages)
542 return nullptr;
543
544 CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0);
545 if (!pPage)
546 return nullptr;
547
548 m_PageList.SetAt(iPage, pPage->GetObjNum());
549 return pPage;
550 }
551
552 void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) {
553 m_PageList.SetAt(iPage, objNum);
554 }
555
556 int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode,
557 uint32_t& skip_count,
558 uint32_t objnum,
559 int& index,
560 int level) {
561 if (!pNode->KeyExist("Kids")) {
562 if (objnum == pNode->GetObjNum())
563 return index;
564
565 if (skip_count)
566 skip_count--;
567
568 index++;
569 return -1;
570 }
571
572 CPDF_Array* pKidList = pNode->GetArrayFor("Kids");
573 if (!pKidList)
574 return -1;
575
576 if (level >= FX_MAX_PAGE_LEVEL)
577 return -1;
578
579 size_t count = pNode->GetIntegerFor("Count");
580 if (count <= skip_count) {
581 skip_count -= count;
582 index += count;
583 return -1;
584 }
585
586 if (count && count == pKidList->GetCount()) {
587 for (size_t i = 0; i < count; i++) {
588 if (CPDF_Reference* pKid = ToReference(pKidList->GetObjectAt(i))) {
589 if (pKid->GetRefObjNum() == objnum) {
590 m_PageList.SetAt(index + i, objnum);
591 return static_cast<int>(index + i);
592 }
593 }
594 }
595 }
596
597 for (size_t i = 0; i < pKidList->GetCount(); i++) {
598 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
599 if (!pKid || pKid == pNode)
600 continue;
601
602 int found_index = FindPageIndex(pKid, skip_count, objnum, index, level + 1);
603 if (found_index >= 0)
604 return found_index;
605 }
606 return -1;
607 }
608
609 int CPDF_Document::GetPageIndex(uint32_t objnum) {
610 uint32_t nPages = m_PageList.GetSize();
611 uint32_t skip_count = 0;
612 bool bSkipped = false;
613 for (uint32_t i = 0; i < nPages; i++) {
614 uint32_t objnum1 = m_PageList.GetAt(i);
615 if (objnum1 == objnum)
616 return i;
617
618 if (!bSkipped && objnum1 == 0) {
619 skip_count = i;
620 bSkipped = true;
621 }
622 }
623 CPDF_Dictionary* pPages = GetPagesDict();
624 if (!pPages)
625 return -1;
626
627 int index = 0;
628 return FindPageIndex(pPages, skip_count, objnum, index);
629 }
630
631 int CPDF_Document::GetPageCount() const {
632 return m_PageList.GetSize();
633 }
634
635 int CPDF_Document::RetrievePageCount() const {
636 CPDF_Dictionary* pPages = GetPagesDict();
637 if (!pPages)
638 return 0;
639
640 if (!pPages->KeyExist("Kids"))
641 return 1;
642
643 std::set<CPDF_Dictionary*> visited_pages;
644 visited_pages.insert(pPages);
645 return CountPages(pPages, &visited_pages);
646 }
647
648 uint32_t CPDF_Document::GetUserPermissions() const {
649 // https://bugs.chromium.org/p/pdfium/issues/detail?id=499
650 if (!m_pParser) {
651 #ifndef PDF_ENABLE_XFA
652 return 0;
653 #else // PDF_ENABLE_XFA
654 return 0xFFFFFFFF;
655 #endif
656 }
657 return m_pParser->GetPermissions();
658 }
659
660 CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) {
661 ASSERT(pFontDict);
662 return m_pDocPage->GetFont(pFontDict, FALSE);
663 }
664
665 CPDF_StreamAcc* CPDF_Document::LoadFontFile(CPDF_Stream* pStream) {
666 return m_pDocPage->GetFontFileStreamAcc(pStream);
667 }
668
669 CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj,
670 CPDF_Dictionary* pResources) {
671 return m_pDocPage->GetColorSpace(pCSObj, pResources);
672 }
673
674 CPDF_Pattern* CPDF_Document::LoadPattern(CPDF_Object* pPatternObj,
675 FX_BOOL bShading,
676 const CFX_Matrix& matrix) {
677 return m_pDocPage->GetPattern(pPatternObj, bShading, matrix);
678 }
679
680 CPDF_IccProfile* CPDF_Document::LoadIccProfile(CPDF_Stream* pStream) {
681 return m_pDocPage->GetIccProfile(pStream);
682 }
683
684 CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) {
685 if (!pObj)
686 return nullptr;
687
688 ASSERT(pObj->GetObjNum());
689 return m_pDocPage->GetImage(pObj);
690 }
691
692 void CPDF_Document::CreateNewDoc() {
693 ASSERT(!m_pRootDict && !m_pInfoDict);
694 m_pRootDict = new CPDF_Dictionary(m_pByteStringPool);
695 m_pRootDict->SetNameFor("Type", "Catalog");
696 AddIndirectObject(m_pRootDict);
697
698 CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool);
699 pPages->SetNameFor("Type", "Pages");
700 pPages->SetNumberFor("Count", 0);
701 pPages->SetFor("Kids", new CPDF_Array);
702 m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages));
703 m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool);
704 AddIndirectObject(m_pInfoDict);
705 }
706
707 CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
708 CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pByteStringPool);
709 pDict->SetNameFor("Type", "Page");
710 uint32_t dwObjNum = AddIndirectObject(pDict);
711 if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) {
712 ReleaseIndirectObject(dwObjNum);
713 return nullptr;
714 }
715 return pDict;
716 }
717
718 void CPDF_Document::DeletePage(int iPage) {
719 CPDF_Dictionary* pPages = GetPagesDict();
720 if (!pPages)
721 return;
722
723 int nPages = pPages->GetIntegerFor("Count");
724 if (iPage < 0 || iPage >= nPages)
725 return;
726
727 std::set<CPDF_Dictionary*> stack = {pPages};
728 if (InsertDeletePDFPage(this, pPages, iPage, nullptr, FALSE, &stack) < 0)
729 return;
730
731 m_PageList.RemoveAt(iPage);
732 }
733
734 CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font,
735 CPDF_FontEncoding* pEncoding) {
736 CFX_ByteString name(font);
737 if (PDF_GetStandardFontName(&name) < 0)
738 return nullptr;
739 return GetPageData()->GetStandardFont(name, pEncoding);
740 }
741
742 size_t CPDF_Document::CalculateEncodingDict(int charset,
743 CPDF_Dictionary* pBaseDict) {
744 size_t i;
745 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) {
746 if (g_FX_CharsetUnicodes[i].m_Charset == charset)
747 break;
748 }
749 if (i == FX_ArraySize(g_FX_CharsetUnicodes))
750 return i;
751 CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool);
752 pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding");
753 CPDF_Array* pArray = new CPDF_Array;
754 pArray->AddInteger(128);
755 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
756 for (int j = 0; j < 128; j++) {
757 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
758 pArray->AddName(name.IsEmpty() ? ".notdef" : name);
759 }
760 pEncodingDict->SetFor("Differences", pArray);
761 pBaseDict->SetReferenceFor("Encoding", this,
762 AddIndirectObject(pEncodingDict));
763
764 return i;
765 }
766
767 CPDF_Dictionary* CPDF_Document::ProcessbCJK(
768 CPDF_Dictionary* pBaseDict,
769 int charset,
770 FX_BOOL bVert,
771 CFX_ByteString basefont,
772 std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) {
773 CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool);
774 CFX_ByteString cmap;
775 CFX_ByteString ordering;
776 int supplement = 0;
777 CPDF_Array* pWidthArray = new CPDF_Array;
778 switch (charset) {
779 case FXFONT_CHINESEBIG5_CHARSET:
780 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
781 ordering = "CNS1";
782 supplement = 4;
783 pWidthArray->AddInteger(1);
784 Insert(0x20, 0x7e, pWidthArray);
785 break;
786 case FXFONT_GB2312_CHARSET:
787 cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
788 ordering = "GB1";
789 supplement = 2;
790 pWidthArray->AddInteger(7716);
791 Insert(0x20, 0x20, pWidthArray);
792 pWidthArray->AddInteger(814);
793 Insert(0x21, 0x7e, pWidthArray);
794 break;
795 case FXFONT_HANGUL_CHARSET:
796 cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
797 ordering = "Korea1";
798 supplement = 2;
799 pWidthArray->AddInteger(1);
800 Insert(0x20, 0x7e, pWidthArray);
801 break;
802 case FXFONT_SHIFTJIS_CHARSET:
803 cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
804 ordering = "Japan1";
805 supplement = 5;
806 pWidthArray->AddInteger(231);
807 Insert(0x20, 0x7d, pWidthArray);
808 pWidthArray->AddInteger(326);
809 Insert(0xa0, 0xa0, pWidthArray);
810 pWidthArray->AddInteger(327);
811 Insert(0xa1, 0xdf, pWidthArray);
812 pWidthArray->AddInteger(631);
813 Insert(0x7e, 0x7e, pWidthArray);
814 break;
815 }
816 pBaseDict->SetNameFor("Subtype", "Type0");
817 pBaseDict->SetNameFor("BaseFont", basefont);
818 pBaseDict->SetNameFor("Encoding", cmap);
819 pFontDict->SetFor("W", pWidthArray);
820 pFontDict->SetNameFor("Type", "Font");
821 pFontDict->SetNameFor("Subtype", "CIDFontType2");
822 pFontDict->SetNameFor("BaseFont", basefont);
823 CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool);
824 pCIDSysInfo->SetStringFor("Registry", "Adobe");
825 pCIDSysInfo->SetStringFor("Ordering", ordering);
826 pCIDSysInfo->SetIntegerFor("Supplement", supplement);
827 pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo);
828 CPDF_Array* pArray = new CPDF_Array;
829 pBaseDict->SetFor("DescendantFonts", pArray);
830 pArray->AddReference(this, AddIndirectObject(pFontDict));
831 return pFontDict;
832 }
833
834 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) {
835 if (!pFont)
836 return nullptr;
837
838 bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET ||
839 charset == FXFONT_GB2312_CHARSET ||
840 charset == FXFONT_HANGUL_CHARSET ||
841 charset == FXFONT_SHIFTJIS_CHARSET;
842 CFX_ByteString basefont = pFont->GetFamilyName();
843 basefont.Replace(" ", "");
844 int flags =
845 CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(),
846 false, false, charset == FXFONT_SYMBOL_CHARSET);
847
848 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool);
849 pBaseDict->SetNameFor("Type", "Font");
850 std::unique_ptr<CFX_UnicodeEncoding> pEncoding(
851 new CFX_UnicodeEncoding(pFont));
852 CPDF_Dictionary* pFontDict = pBaseDict;
853 if (!bCJK) {
854 CPDF_Array* pWidths = new CPDF_Array;
855 for (int charcode = 32; charcode < 128; charcode++) {
856 int glyph_index = pEncoding->GlyphFromCharCode(charcode);
857 int char_width = pFont->GetGlyphWidth(glyph_index);
858 pWidths->AddInteger(char_width);
859 }
860 if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
861 charset == FXFONT_SYMBOL_CHARSET) {
862 pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding");
863 for (int charcode = 128; charcode <= 255; charcode++) {
864 int glyph_index = pEncoding->GlyphFromCharCode(charcode);
865 int char_width = pFont->GetGlyphWidth(glyph_index);
866 pWidths->AddInteger(char_width);
867 }
868 } else {
869 size_t i = CalculateEncodingDict(charset, pBaseDict);
870 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) {
871 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
872 for (int j = 0; j < 128; j++) {
873 int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
874 int char_width = pFont->GetGlyphWidth(glyph_index);
875 pWidths->AddInteger(char_width);
876 }
877 }
878 }
879 ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont,
880 pWidths);
881 } else {
882 pFontDict = ProcessbCJK(pBaseDict, charset, bVert, basefont,
883 [pFont, &pEncoding](FX_WCHAR start, FX_WCHAR end,
884 CPDF_Array* widthArr) {
885 InsertWidthArray1(pFont, pEncoding.get(), start,
886 end, widthArr);
887 });
888 }
889 AddIndirectObject(pBaseDict);
890 int italicangle =
891 pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0;
892 FX_RECT bbox;
893 pFont->GetBBox(bbox);
894 CPDF_Array* pBBox = new CPDF_Array;
895 pBBox->AddInteger(bbox.left);
896 pBBox->AddInteger(bbox.bottom);
897 pBBox->AddInteger(bbox.right);
898 pBBox->AddInteger(bbox.top);
899 int32_t nStemV = 0;
900 if (pFont->GetSubstFont()) {
901 nStemV = pFont->GetSubstFont()->m_Weight / 5;
902 } else {
903 static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'};
904 const size_t count = FX_ArraySize(stem_chars);
905 uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]);
906 nStemV = pFont->GetGlyphWidth(glyph);
907 for (size_t i = 1; i < count; i++) {
908 glyph = pEncoding->GlyphFromCharCode(stem_chars[i]);
909 int width = pFont->GetGlyphWidth(glyph);
910 if (width > 0 && width < nStemV)
911 nStemV = width;
912 }
913 }
914 CPDF_Dictionary* pFontDesc =
915 CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(),
916 pFont->GetDescent(), pBBox, nStemV);
917 pFontDict->SetReferenceFor("FontDescriptor", this,
918 AddIndirectObject(pFontDesc));
919 return LoadFont(pBaseDict);
920 }
921
922 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
923 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont,
924 FX_BOOL bVert,
925 FX_BOOL bTranslateName) {
926 LOGFONTA lfa;
927 FXSYS_memcpy(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa);
928 CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName);
929 if (face.GetLength() >= LF_FACESIZE)
930 return nullptr;
931
932 FXSYS_strcpy(lfa.lfFaceName, face.c_str());
933 return AddWindowsFont(&lfa, bVert, bTranslateName);
934 }
935
936 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
937 FX_BOOL bVert,
938 FX_BOOL bTranslateName) {
939 pLogFont->lfHeight = -1000;
940 pLogFont->lfWidth = 0;
941 HGDIOBJ hFont = CreateFontIndirectA(pLogFont);
942 HDC hDC = CreateCompatibleDC(nullptr);
943 hFont = SelectObject(hDC, hFont);
944 int tm_size = GetOutlineTextMetrics(hDC, 0, nullptr);
945 if (tm_size == 0) {
946 hFont = SelectObject(hDC, hFont);
947 DeleteObject(hFont);
948 DeleteDC(hDC);
949 return nullptr;
950 }
951
952 LPBYTE tm_buf = FX_Alloc(BYTE, tm_size);
953 OUTLINETEXTMETRIC* ptm = reinterpret_cast<OUTLINETEXTMETRIC*>(tm_buf);
954 GetOutlineTextMetrics(hDC, tm_size, ptm);
955 int flags = CalculateFlags(false, pLogFont->lfItalic != 0,
956 (pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH,
957 (pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN,
958 (pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT,
959 pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET);
960
961 bool bCJK = pLogFont->lfCharSet == FXFONT_CHINESEBIG5_CHARSET ||
962 pLogFont->lfCharSet == FXFONT_GB2312_CHARSET ||
963 pLogFont->lfCharSet == FXFONT_HANGUL_CHARSET ||
964 pLogFont->lfCharSet == FXFONT_SHIFTJIS_CHARSET;
965 CFX_ByteString basefont;
966 if (bTranslateName && bCJK)
967 basefont = FPDF_GetPSNameFromTT(hDC);
968
969 if (basefont.IsEmpty())
970 basefont = pLogFont->lfFaceName;
971
972 int italicangle = ptm->otmItalicAngle / 10;
973 int ascend = ptm->otmrcFontBox.top;
974 int descend = ptm->otmrcFontBox.bottom;
975 int capheight = ptm->otmsCapEmHeight;
976 int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom,
977 ptm->otmrcFontBox.right, ptm->otmrcFontBox.top};
978 FX_Free(tm_buf);
979 basefont.Replace(" ", "");
980 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool);
981 pBaseDict->SetNameFor("Type", "Font");
982 CPDF_Dictionary* pFontDict = pBaseDict;
983 if (!bCJK) {
984 if (pLogFont->lfCharSet == FXFONT_ANSI_CHARSET ||
985 pLogFont->lfCharSet == FXFONT_DEFAULT_CHARSET ||
986 pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET) {
987 pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding");
988 } else {
989 CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict);
990 }
991 int char_widths[224];
992 GetCharWidth(hDC, 32, 255, char_widths);
993 CPDF_Array* pWidths = new CPDF_Array;
994 for (size_t i = 0; i < 224; i++)
995 pWidths->AddInteger(char_widths[i]);
996 ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM,
997 pLogFont->lfItalic != 0, basefont, pWidths);
998 } else {
999 pFontDict =
1000 ProcessbCJK(pBaseDict, pLogFont->lfCharSet, bVert, basefont,
1001 [&hDC](FX_WCHAR start, FX_WCHAR end, CPDF_Array* widthArr) {
1002 InsertWidthArray(hDC, start, end, widthArr);
1003 });
1004 }
1005 AddIndirectObject(pBaseDict);
1006 CPDF_Array* pBBox = new CPDF_Array;
1007 for (int i = 0; i < 4; i++)
1008 pBBox->AddInteger(bbox[i]);
1009 CPDF_Dictionary* pFontDesc =
1010 CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend,
1011 pBBox, pLogFont->lfWeight / 5);
1012 pFontDesc->SetIntegerFor("CapHeight", capheight);
1013 pFontDict->SetReferenceFor("FontDescriptor", this,
1014 AddIndirectObject(pFontDesc));
1015 hFont = SelectObject(hDC, hFont);
1016 DeleteObject(hFont);
1017 DeleteDC(hDC);
1018 return LoadFont(pBaseDict);
1019 }
1020 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_parser/cpdf_document.h ('k') | core/fpdfapi/fpdf_parser/cpdf_hint_tables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698