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
37namespace {
38
39const int FX_MAX_PAGE_LEVEL = 1024;
40
41const 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};
58const 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};
75const 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};
92const 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};
109const 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};
126const 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};
143const 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};
160const 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
178struct FX_CharsetUnicodes {
179  uint8_t m_Charset;
180  const uint16_t* m_pUnicodes;
181};
182
183const 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
194void 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_
213void 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
220ByteString 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
233void 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
248int 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
275int 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
299void 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
317std::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
341CPDF_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
356CPDF_Document::~CPDF_Document() {
357  CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
358}
359
360std::unique_ptr<CPDF_Object> CPDF_Document::ParseIndirectObject(
361    uint32_t objnum) {
362  return m_pParser ? m_pParser->ParseIndirectObject(this, objnum) : nullptr;
363}
364
365void 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
379void 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
388void CPDF_Document::LoadDoc() {
389  LoadDocInternal();
390  LoadPages();
391}
392
393void 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
402void CPDF_Document::LoadPages() {
403  m_PageList.resize(RetrievePageCount());
404}
405
406CPDF_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
472void CPDF_Document::ResetTraversal() {
473  m_iNextPageToTraverse = 0;
474  m_bReachedMaxPageLevel = false;
475  m_pTreeTraversal.clear();
476}
477
478CPDF_Dictionary* CPDF_Document::GetPagesDict() const {
479  const CPDF_Dictionary* pRoot = GetRoot();
480  return pRoot ? pRoot->GetDictFor("Pages") : nullptr;
481}
482
483bool CPDF_Document::IsPageLoaded(int iPage) const {
484  return !!m_PageList[iPage];
485}
486
487CPDF_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
515void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) {
516  m_PageList[iPage] = objNum;
517}
518
519int 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
569int 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
597int CPDF_Document::GetPageCount() const {
598  return pdfium::CollectionSize<int>(m_PageList);
599}
600
601int 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
614uint32_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
626CPDF_Font* CPDF_Document::LoadFont(CPDF_Dictionary* pFontDict) {
627  ASSERT(pFontDict);
628  return m_pDocPage->GetFont(pFontDict);
629}
630
631RetainPtr<CPDF_StreamAcc> CPDF_Document::LoadFontFile(CPDF_Stream* pStream) {
632  return m_pDocPage->GetFontFileStreamAcc(pStream);
633}
634
635CPDF_ColorSpace* CPDF_Document::LoadColorSpace(CPDF_Object* pCSObj,
636                                               CPDF_Dictionary* pResources) {
637  return m_pDocPage->GetColorSpace(pCSObj, pResources);
638}
639
640CPDF_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
646RetainPtr<CPDF_IccProfile> CPDF_Document::LoadIccProfile(CPDF_Stream* pStream) {
647  return m_pDocPage->GetIccProfile(pStream);
648}
649
650RetainPtr<CPDF_Image> CPDF_Document::LoadImageFromPageData(
651    uint32_t dwStreamObjNum) {
652  ASSERT(dwStreamObjNum);
653  return m_pDocPage->GetImage(dwStreamObjNum);
654}
655
656void 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
670CPDF_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
681bool 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
728bool 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
755void 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
771CPDF_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
779size_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
805CPDF_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
872CPDF_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_
957CPDF_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
971CPDF_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