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