• 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_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