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