• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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