clang-format all pdfium code.
[pdfium.git] / core / src / fpdfapi / fpdf_edit / fpdf_edit_doc.cpp
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 "../../../include/fpdfapi/fpdf_page.h"
8 #include "../../../include/fpdfapi/fpdf_module.h"
9 #include "../fpdf_page/pageint.h"
10 #include <limits.h>
11 CPDF_Document::CPDF_Document() : CPDF_IndirectObjects(NULL) {
12   m_pRootDict = NULL;
13   m_pInfoDict = NULL;
14   m_bLinearized = FALSE;
15   m_dwFirstPageNo = 0;
16   m_dwFirstPageObjNum = 0;
17   m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
18   m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
19 }
20 void CPDF_Document::CreateNewDoc() {
21   ASSERT(m_pRootDict == NULL && m_pInfoDict == NULL);
22   m_pRootDict = new CPDF_Dictionary;
23   m_pRootDict->SetAtName("Type", "Catalog");
24   int objnum = AddIndirectObject(m_pRootDict);
25   CPDF_Dictionary* pPages = new CPDF_Dictionary;
26   pPages->SetAtName("Type", "Pages");
27   pPages->SetAtNumber("Count", 0);
28   pPages->SetAt("Kids", new CPDF_Array);
29   objnum = AddIndirectObject(pPages);
30   m_pRootDict->SetAtReference("Pages", this, objnum);
31   m_pInfoDict = new CPDF_Dictionary;
32   AddIndirectObject(m_pInfoDict);
33 }
34 static const FX_WCHAR g_FX_CP874Unicodes[128] = {
35     0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x0000,
36     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
37     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x0000, 0x0000,
38     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0E01, 0x0E02, 0x0E03,
39     0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C,
40     0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15,
41     0x0E16, 0x0E17, 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E,
42     0x0E1F, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
43     0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, 0x0E30,
44     0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39,
45     0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, 0x0E40, 0x0E41, 0x0E42,
46     0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48, 0x0E49, 0x0E4A, 0x0E4B,
47     0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54,
48     0x0E55, 0x0E56, 0x0E57, 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000,
49     0x0000, 0x0000,
50 };
51 static const FX_WCHAR g_FX_CP1250Unicodes[128] = {
52     0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
53     0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0000, 0x2018,
54     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161,
55     0x203A, 0x015B, 0x0165, 0x017E, 0x017A, 0x00A0, 0x02C7, 0x02D8, 0x0141,
56     0x00A4, 0x0104, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC,
57     0x00AD, 0x00AE, 0x017B, 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5,
58     0x00B6, 0x00B7, 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E,
59     0x017C, 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
60     0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 0x0110,
61     0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E,
62     0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 0x0155, 0x00E1, 0x00E2,
63     0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB,
64     0x011B, 0x00ED, 0x00EE, 0x010F, 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4,
65     0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD,
66     0x0163, 0x02D9,
67 };
68 static const FX_WCHAR g_FX_CP1251Unicodes[128] = {
69     0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC,
70     0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018,
71     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459,
72     0x203A, 0x045A, 0x045C, 0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408,
73     0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC,
74     0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5,
75     0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455,
76     0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
77     0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
78     0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429,
79     0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432,
80     0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B,
81     0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444,
82     0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D,
83     0x044E, 0x044F,
84 };
85 static const FX_WCHAR g_FX_CP1253Unicodes[128] = {
86     0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
87     0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
88     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
89     0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x0385, 0x0386, 0x00A3,
90     0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC,
91     0x00AD, 0x00AE, 0x2015, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5,
92     0x00B6, 0x00B7, 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E,
93     0x038F, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
94     0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
95     0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
96     0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03B1, 0x03B2,
97     0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB,
98     0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4,
99     0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD,
100     0x03CE, 0x0000,
101 };
102 static const FX_WCHAR g_FX_CP1254Unicodes[128] = {
103     0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
104     0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
105     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161,
106     0x203A, 0x0153, 0x0000, 0x0000, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
107     0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC,
108     0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
109     0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
110     0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
111     0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x011E,
112     0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9,
113     0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, 0x00E0, 0x00E1, 0x00E2,
114     0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
115     0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4,
116     0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131,
117     0x015F, 0x00FF,
118 };
119 static const FX_WCHAR g_FX_CP1255Unicodes[128] = {
120     0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
121     0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2018,
122     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0000,
123     0x203A, 0x0000, 0x0000, 0x0000, 0x0000, 0x00A0, 0x00A1, 0x00A2, 0x00A3,
124     0x20AA, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC,
125     0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
126     0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
127     0x00BF, 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
128     0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF, 0x05C0,
129     0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3, 0x05F4, 0x0000,
130     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x05D0, 0x05D1, 0x05D2,
131     0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB,
132     0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4,
133     0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E,
134     0x200F, 0x0000,
135 };
136 static const FX_WCHAR g_FX_CP1256Unicodes[128] = {
137     0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6,
138     0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x06AF, 0x2018,
139     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06A9, 0x2122, 0x0691,
140     0x203A, 0x0153, 0x200C, 0x200D, 0x06BA, 0x00A0, 0x060C, 0x00A2, 0x00A3,
141     0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC,
142     0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
143     0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
144     0x061F, 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
145     0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630,
146     0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7, 0x0637, 0x0638,
147     0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643, 0x00E0, 0x0644, 0x00E2,
148     0x0645, 0x0646, 0x0647, 0x0648, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB,
149     0x0649, 0x064A, 0x00EE, 0x00EF, 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4,
150     0x064F, 0x0650, 0x00F7, 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E,
151     0x200F, 0x06D2,
152 };
153 static const FX_WCHAR g_FX_CP1257Unicodes[128] = {
154     0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x0000,
155     0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, 0x0000, 0x2018,
156     0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0000,
157     0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000, 0x00A0, 0x0000, 0x00A2, 0x00A3,
158     0x00A4, 0x0000, 0x00A6, 0x00A7, 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC,
159     0x00AD, 0x00AE, 0x00C6, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5,
160     0x00B6, 0x00B7, 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE,
161     0x00E6, 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
162     0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, 0x0160,
163     0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, 0x0172, 0x0141,
164     0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, 0x0105, 0x012F, 0x0101,
165     0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, 0x010D, 0x00E9, 0x017A, 0x0117,
166     0x0123, 0x0137, 0x012B, 0x013C, 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D,
167     0x00F5, 0x00F6, 0x00F7, 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C,
168     0x017E, 0x02D9,
169 };
170 typedef struct {
171   uint8_t m_Charset;
172   const FX_WCHAR* m_pUnicodes;
173 } FX_CharsetUnicodes;
174 const FX_CharsetUnicodes g_FX_CharsetUnicodes[] = {
175     {FXFONT_THAI_CHARSET, g_FX_CP874Unicodes},
176     {FXFONT_EASTEUROPE_CHARSET, g_FX_CP1250Unicodes},
177     {FXFONT_RUSSIAN_CHARSET, g_FX_CP1251Unicodes},
178     {FXFONT_GREEK_CHARSET, g_FX_CP1253Unicodes},
179     {FXFONT_TURKISH_CHARSET, g_FX_CP1254Unicodes},
180     {FXFONT_HEBREW_CHARSET, g_FX_CP1255Unicodes},
181     {FXFONT_ARABIC_CHARSET, g_FX_CP1256Unicodes},
182     {FXFONT_BALTIC_CHARSET, g_FX_CP1257Unicodes},
183 };
184 #if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_)
185 static void _InsertWidthArray(HDC hDC,
186                               int start,
187                               int end,
188                               CPDF_Array* pWidthArray) {
189   int size = end - start + 1;
190   int* widths = FX_Alloc(int, size);
191   GetCharWidth(hDC, start, end, widths);
192   int i;
193   for (i = 1; i < size; i++)
194     if (widths[i] != *widths) {
195       break;
196     }
197   if (i == size) {
198     int first = pWidthArray->GetInteger(pWidthArray->GetCount() - 1);
199     pWidthArray->AddInteger(first + size - 1);
200     pWidthArray->AddInteger(*widths);
201   } else {
202     CPDF_Array* pWidthArray1 = new CPDF_Array;
203     pWidthArray->Add(pWidthArray1);
204     for (i = 0; i < size; i++) {
205       pWidthArray1->AddInteger(widths[i]);
206     }
207   }
208   FX_Free(widths);
209 }
210 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont,
211                                          FX_BOOL bVert,
212                                          FX_BOOL bTranslateName) {
213   LOGFONTA lfa;
214   FXSYS_memcpy(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa);
215   CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName);
216   if (face.GetLength() >= LF_FACESIZE) {
217     return NULL;
218   }
219   FXSYS_strcpy(lfa.lfFaceName, face.c_str());
220   return AddWindowsFont(&lfa, bVert, bTranslateName);
221 }
222 extern CFX_ByteString _FPDF_GetNameFromTT(const uint8_t* name_table,
223                                           FX_DWORD name);
224 CFX_ByteString _FPDF_GetPSNameFromTT(HDC hDC) {
225   CFX_ByteString result;
226   DWORD size = ::GetFontData(hDC, 'eman', 0, NULL, 0);
227   if (size != GDI_ERROR) {
228     LPBYTE buffer = FX_Alloc(BYTE, size);
229     ::GetFontData(hDC, 'eman', 0, buffer, size);
230     result = _FPDF_GetNameFromTT(buffer, 6);
231     FX_Free(buffer);
232   }
233   return result;
234 }
235 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont,
236                                          FX_BOOL bVert,
237                                          FX_BOOL bTranslateName) {
238   pLogFont->lfHeight = -1000;
239   pLogFont->lfWidth = 0;
240   HGDIOBJ hFont = CreateFontIndirectA(pLogFont);
241   HDC hDC = CreateCompatibleDC(NULL);
242   hFont = SelectObject(hDC, hFont);
243   int tm_size = GetOutlineTextMetrics(hDC, 0, NULL);
244   if (tm_size == 0) {
245     hFont = SelectObject(hDC, hFont);
246     DeleteObject(hFont);
247     DeleteDC(hDC);
248     return NULL;
249   }
250   LPBYTE tm_buf = FX_Alloc(BYTE, tm_size);
251   OUTLINETEXTMETRIC* ptm = (OUTLINETEXTMETRIC*)tm_buf;
252   GetOutlineTextMetrics(hDC, tm_size, ptm);
253   int flags = 0, italicangle, ascend, descend, capheight, bbox[4];
254   if (pLogFont->lfItalic) {
255     flags |= PDFFONT_ITALIC;
256   }
257   if ((pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH) {
258     flags |= PDFFONT_FIXEDPITCH;
259   }
260   if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN) {
261     flags |= PDFFONT_SERIF;
262   }
263   if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT) {
264     flags |= PDFFONT_SCRIPT;
265   }
266   FX_BOOL bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET ||
267                  pLogFont->lfCharSet == GB2312_CHARSET ||
268                  pLogFont->lfCharSet == HANGEUL_CHARSET ||
269                  pLogFont->lfCharSet == SHIFTJIS_CHARSET;
270   CFX_ByteString basefont;
271   if (bTranslateName && bCJK) {
272     basefont = _FPDF_GetPSNameFromTT(hDC);
273   }
274   if (basefont.IsEmpty()) {
275     basefont = pLogFont->lfFaceName;
276   }
277   italicangle = ptm->otmItalicAngle / 10;
278   ascend = ptm->otmrcFontBox.top;
279   descend = ptm->otmrcFontBox.bottom;
280   capheight = ptm->otmsCapEmHeight;
281   bbox[0] = ptm->otmrcFontBox.left;
282   bbox[1] = ptm->otmrcFontBox.bottom;
283   bbox[2] = ptm->otmrcFontBox.right;
284   bbox[3] = ptm->otmrcFontBox.top;
285   FX_Free(tm_buf);
286   basefont.Replace(" ", "");
287   CPDF_Dictionary* pBaseDict = new CPDF_Dictionary;
288   pBaseDict->SetAtName("Type", "Font");
289   CPDF_Dictionary* pFontDict = pBaseDict;
290   if (!bCJK) {
291     if (pLogFont->lfCharSet == ANSI_CHARSET ||
292         pLogFont->lfCharSet == DEFAULT_CHARSET ||
293         pLogFont->lfCharSet == SYMBOL_CHARSET) {
294       if (pLogFont->lfCharSet == SYMBOL_CHARSET) {
295         flags |= PDFFONT_SYMBOLIC;
296       } else {
297         flags |= PDFFONT_NONSYMBOLIC;
298       }
299       pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
300     } else {
301       flags |= PDFFONT_NONSYMBOLIC;
302       int i;
303       for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes);
304            i++)
305         if (g_FX_CharsetUnicodes[i].m_Charset == pLogFont->lfCharSet) {
306           break;
307         }
308       if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) {
309         CPDF_Dictionary* pEncoding = new CPDF_Dictionary;
310         pEncoding->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding");
311         CPDF_Array* pArray = new CPDF_Array;
312         pArray->AddInteger(128);
313         const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
314         for (int j = 0; j < 128; j++) {
315           CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
316           if (name.IsEmpty()) {
317             pArray->AddName(FX_BSTRC(".notdef"));
318           } else {
319             pArray->AddName(name);
320           }
321         }
322         pEncoding->SetAt(FX_BSTRC("Differences"), pArray);
323         AddIndirectObject(pEncoding);
324         pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncoding);
325       }
326     }
327     if (pLogFont->lfWeight > FW_MEDIUM && pLogFont->lfItalic) {
328       basefont += ",BoldItalic";
329     } else if (pLogFont->lfWeight > FW_MEDIUM) {
330       basefont += ",Bold";
331     } else if (pLogFont->lfItalic) {
332       basefont += ",Italic";
333     }
334     pBaseDict->SetAtName("Subtype", "TrueType");
335     pBaseDict->SetAtName("BaseFont", basefont);
336     pBaseDict->SetAtNumber("FirstChar", 32);
337     pBaseDict->SetAtNumber("LastChar", 255);
338     int char_widths[224];
339     GetCharWidth(hDC, 32, 255, char_widths);
340     CPDF_Array* pWidths = new CPDF_Array;
341     for (int i = 0; i < 224; i++) {
342       pWidths->AddInteger(char_widths[i]);
343     }
344     pBaseDict->SetAt("Widths", pWidths);
345   } else {
346     flags |= PDFFONT_NONSYMBOLIC;
347     pFontDict = new CPDF_Dictionary;
348     CFX_ByteString cmap;
349     CFX_ByteString ordering;
350     int supplement;
351     CPDF_Array* pWidthArray = new CPDF_Array;
352     switch (pLogFont->lfCharSet) {
353       case CHINESEBIG5_CHARSET:
354         cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
355         ordering = "CNS1";
356         supplement = 4;
357         pWidthArray->AddInteger(1);
358         _InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray);
359         break;
360       case GB2312_CHARSET:
361         cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
362         ordering = "GB1", supplement = 2;
363         pWidthArray->AddInteger(7716);
364         _InsertWidthArray(hDC, 0x20, 0x20, pWidthArray);
365         pWidthArray->AddInteger(814);
366         _InsertWidthArray(hDC, 0x21, 0x7e, pWidthArray);
367         break;
368       case HANGEUL_CHARSET:
369         cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
370         ordering = "Korea1";
371         supplement = 2;
372         pWidthArray->AddInteger(1);
373         _InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray);
374         break;
375       case SHIFTJIS_CHARSET:
376         cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
377         ordering = "Japan1";
378         supplement = 5;
379         pWidthArray->AddInteger(231);
380         _InsertWidthArray(hDC, 0x20, 0x7d, pWidthArray);
381         pWidthArray->AddInteger(326);
382         _InsertWidthArray(hDC, 0xa0, 0xa0, pWidthArray);
383         pWidthArray->AddInteger(327);
384         _InsertWidthArray(hDC, 0xa1, 0xdf, pWidthArray);
385         pWidthArray->AddInteger(631);
386         _InsertWidthArray(hDC, 0x7e, 0x7e, pWidthArray);
387         break;
388     }
389     pBaseDict->SetAtName("Subtype", "Type0");
390     pBaseDict->SetAtName("BaseFont", basefont);
391     pBaseDict->SetAtName("Encoding", cmap);
392     pFontDict->SetAt("W", pWidthArray);
393     pFontDict->SetAtName("Type", "Font");
394     pFontDict->SetAtName("Subtype", "CIDFontType2");
395     pFontDict->SetAtName("BaseFont", basefont);
396     CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary;
397     pCIDSysInfo->SetAtString("Registry", "Adobe");
398     pCIDSysInfo->SetAtString("Ordering", ordering);
399     pCIDSysInfo->SetAtInteger("Supplement", supplement);
400     pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
401     CPDF_Array* pArray = new CPDF_Array;
402     pBaseDict->SetAt("DescendantFonts", pArray);
403     AddIndirectObject(pFontDict);
404     pArray->AddReference(this, pFontDict);
405   }
406   AddIndirectObject(pBaseDict);
407   CPDF_Dictionary* pFontDesc = new CPDF_Dictionary;
408   pFontDesc->SetAtName("Type", "FontDescriptor");
409   pFontDesc->SetAtName("FontName", basefont);
410   pFontDesc->SetAtInteger("Flags", flags);
411   CPDF_Array* pBBox = new CPDF_Array;
412   for (int i = 0; i < 4; i++) {
413     pBBox->AddInteger(bbox[i]);
414   }
415   pFontDesc->SetAt("FontBBox", pBBox);
416   pFontDesc->SetAtInteger("ItalicAngle", italicangle);
417   pFontDesc->SetAtInteger("Ascent", ascend);
418   pFontDesc->SetAtInteger("Descent", descend);
419   pFontDesc->SetAtInteger("CapHeight", capheight);
420   pFontDesc->SetAtInteger("StemV", pLogFont->lfWeight / 5);
421   AddIndirectObject(pFontDesc);
422   pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
423   hFont = SelectObject(hDC, hFont);
424   DeleteObject(hFont);
425   DeleteDC(hDC);
426   return LoadFont(pBaseDict);
427 }
428 #endif
429 #if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_)
430 uint32_t FX_GetLangHashCode(const FX_CHAR* pStr) {
431   FXSYS_assert(pStr != NULL);
432   int32_t iLength = FXSYS_strlen(pStr);
433   const FX_CHAR* pStrEnd = pStr + iLength;
434   uint32_t uHashCode = 0;
435   while (pStr < pStrEnd) {
436     uHashCode = 31 * uHashCode + tolower(*pStr++);
437   }
438   return uHashCode;
439 }
440 struct FX_LANG2CS {
441   FX_DWORD uLang;
442   int uCharset;
443 } * FX_LPLANG2CS;
444 static const FX_LANG2CS gs_FXLang2CharsetTable[] = {
445     {3109, 0},         {3121, 178}, {3129, 162}, {3139, 204}, {3141, 204},
446     {3166, 0},         {3184, 238}, {3197, 0},   {3201, 0},   {3239, 161},
447     {3241, 0},         {3246, 0},   {3247, 186}, {3248, 0},   {3259, 178},
448     {3267, 0},         {3273, 0},   {3276, 0},   {3301, 0},   {3310, 1},
449     {3325, 177},       {3329, 1},   {3338, 238}, {3341, 238}, {3345, 1},
450     {3355, 0},         {3370, 0},   {3371, 0},   {3383, 128}, {3424, 204},
451     {3427, 1},         {3428, 129}, {3436, 178}, {3464, 186}, {3466, 186},
452     {3486, 204},       {3487, 0},   {3493, 1},   {3494, 0},   {3508, 0},
453     {3518, 0},         {3520, 0},   {3569, 1},   {3580, 238}, {3588, 0},
454     {3645, 238},       {3651, 204}, {3672, 238}, {3673, 238}, {3678, 238},
455     {3679, 238},       {3683, 0},   {3684, 0},   {3693, 1},   {3697, 1},
456     {3700, 222},       {3710, 162}, {3734, 204}, {3741, 178}, {3749, 162},
457     {3763, 163},       {3886, 134}, {105943, 0}, {106375, 1}, {3923451837, 134},
458     {3923451838, 136},
459 };
460 static FX_WORD FX_GetCsFromLangCode(uint32_t uCode) {
461   int32_t iStart = 0;
462   int32_t iEnd = sizeof(gs_FXLang2CharsetTable) / sizeof(FX_LANG2CS) - 1;
463   while (iStart <= iEnd) {
464     int32_t iMid = (iStart + iEnd) / 2;
465     const FX_LANG2CS& charset = gs_FXLang2CharsetTable[iMid];
466     if (uCode == charset.uLang) {
467       return charset.uCharset;
468     }
469     if (uCode < charset.uLang) {
470       iEnd = iMid - 1;
471     } else {
472       iStart = iMid + 1;
473     }
474   };
475   return 0;
476 }
477 static FX_WORD FX_GetCharsetFromLang(const FX_CHAR* pLang, int32_t iLength) {
478   FXSYS_assert(pLang);
479   if (iLength < 0) {
480     iLength = FXSYS_strlen(pLang);
481   }
482   uint32_t uHash = FX_GetLangHashCode(pLang);
483   return FX_GetCsFromLangCode(uHash);
484 }
485 static void _CFString2CFXByteString(CFStringRef src, CFX_ByteString& dest) {
486   SInt32 len = CFStringGetLength(src);
487   CFRange range = CFRangeMake(0, len);
488   CFIndex used = 0;
489   UInt8* pBuffer = (UInt8*)calloc(len + 1, sizeof(UInt8));
490   CFStringGetBytes(src, range, kCFStringEncodingASCII, 0, false, pBuffer, len,
491                    &used);
492   dest = (FX_CHAR*)pBuffer;
493   free(pBuffer);
494 }
495 FX_BOOL IsHasCharSet(CFArrayRef languages, const CFX_DWordArray& charSets) {
496   int iCount = charSets.GetSize();
497   for (int i = 0; i < CFArrayGetCount(languages); ++i) {
498     CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(languages, i);
499     FX_DWORD CharSet = FX_GetCharsetFromLang(
500         CFStringGetCStringPtr(language, kCFStringEncodingMacRoman), -1);
501     for (int j = 0; j < iCount; ++j) {
502       if (CharSet == charSets[j]) {
503         return TRUE;
504       }
505     }
506   }
507   return FALSE;
508 }
509 void FX_GetCharWidth(CTFontRef font, UniChar start, UniChar end, int* width) {
510   CGFloat size = CTFontGetSize(font);
511   for (; start <= end; ++start) {
512     CGGlyph pGlyph = 0;
513     CFIndex count = 1;
514     CTFontGetGlyphsForCharacters(font, &start, &pGlyph, count);
515     CGSize advances;
516     CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &pGlyph,
517                                &advances, 1);
518     *width = (int)(advances.width / size * 1000);
519     width++;
520   }
521 }
522 static void _InsertWidthArray(CTFontRef font,
523                               int start,
524                               int end,
525                               CPDF_Array* pWidthArray) {
526   int size = end - start + 1;
527   int* widths = FX_Alloc(int, size);
528   FX_GetCharWidth(font, start, end, widths);
529   int i;
530   for (i = 1; i < size; i++)
531     if (widths[i] != *widths) {
532       break;
533     }
534   if (i == size) {
535     int first = pWidthArray->GetInteger(pWidthArray->GetCount() - 1);
536     pWidthArray->AddInteger(first + size - 1);
537     pWidthArray->AddInteger(*widths);
538   } else {
539     CPDF_Array* pWidthArray1 = new CPDF_Array;
540     pWidthArray->Add(pWidthArray1);
541     for (i = 0; i < size; i++) {
542       pWidthArray1->AddInteger(widths[i]);
543     }
544   }
545   FX_Free(widths);
546 }
547 CPDF_Font* CPDF_Document::AddMacFont(CTFontRef pFont,
548                                      FX_BOOL bVert,
549                                      FX_BOOL bTranslateName) {
550   CTFontRef font = (CTFontRef)pFont;
551   CTFontDescriptorRef descriptor = CTFontCopyFontDescriptor(font);
552   if (descriptor == NULL) {
553     return NULL;
554   }
555   CFX_ByteString basefont;
556   FX_BOOL bCJK = FALSE;
557   int flags = 0, italicangle = 0, ascend = 0, descend = 0, capheight = 0,
558       bbox[4];
559   FXSYS_memset(bbox, 0, sizeof(int) * 4);
560   CFArrayRef languages = (CFArrayRef)CTFontDescriptorCopyAttribute(
561       descriptor, kCTFontLanguagesAttribute);
562   if (languages == NULL) {
563     CFRelease(descriptor);
564     return NULL;
565   }
566   CFX_DWordArray charSets;
567   charSets.Add(FXFONT_CHINESEBIG5_CHARSET);
568   charSets.Add(FXFONT_GB2312_CHARSET);
569   charSets.Add(FXFONT_HANGEUL_CHARSET);
570   charSets.Add(FXFONT_SHIFTJIS_CHARSET);
571   if (IsHasCharSet(languages, charSets)) {
572     bCJK = TRUE;
573   }
574   CFRelease(descriptor);
575   CFDictionaryRef traits = (CFDictionaryRef)CTFontCopyTraits(font);
576   if (traits == NULL) {
577     CFRelease(languages);
578     return NULL;
579   }
580   CFNumberRef sybolicTrait =
581       (CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait);
582   CTFontSymbolicTraits trait = 0;
583   CFNumberGetValue(sybolicTrait, kCFNumberSInt32Type, &trait);
584   if (trait & kCTFontItalicTrait) {
585     flags |= PDFFONT_ITALIC;
586   }
587   if (trait & kCTFontMonoSpaceTrait) {
588     flags |= PDFFONT_FIXEDPITCH;
589   }
590   if (trait & kCTFontModernSerifsClass) {
591     flags |= PDFFONT_SERIF;
592   }
593   if (trait & kCTFontScriptsClass) {
594     flags |= PDFFONT_SCRIPT;
595   }
596   CFNumberRef weightTrait =
597       (CFNumberRef)CFDictionaryGetValue(traits, kCTFontWeightTrait);
598   Float32 weight = 0;
599   CFNumberGetValue(weightTrait, kCFNumberFloat32Type, &weight);
600   italicangle = CTFontGetSlantAngle(font);
601   ascend = CTFontGetAscent(font);
602   descend = CTFontGetDescent(font);
603   capheight = CTFontGetCapHeight(font);
604   CGRect box = CTFontGetBoundingBox(font);
605   bbox[0] = box.origin.x;
606   bbox[1] = box.origin.y;
607   bbox[2] = box.origin.x + box.size.width;
608   bbox[3] = box.origin.y + box.size.height;
609   if (bTranslateName && bCJK) {
610     CFStringRef postName = CTFontCopyPostScriptName(font);
611     _CFString2CFXByteString(postName, basefont);
612     CFRelease(postName);
613   }
614   if (basefont.IsEmpty()) {
615     CFStringRef fullName = CTFontCopyFullName(font);
616     _CFString2CFXByteString(fullName, basefont);
617     CFRelease(fullName);
618   }
619   basefont.Replace(" ", "");
620   CPDF_Dictionary* pBaseDict = new CPDF_Dictionary;
621   CPDF_Dictionary* pFontDict = pBaseDict;
622   if (!bCJK) {
623     charSets.RemoveAll();
624     charSets.Add(FXFONT_ANSI_CHARSET);
625     charSets.Add(FXFONT_DEFAULT_CHARSET);
626     charSets.Add(FXFONT_SYMBOL_CHARSET);
627     if (IsHasCharSet(languages, charSets)) {
628       charSets.RemoveAll();
629       charSets.Add(FXFONT_SYMBOL_CHARSET);
630       if (IsHasCharSet(languages, charSets)) {
631         flags |= PDFFONT_SYMBOLIC;
632       } else {
633         flags |= PDFFONT_NONSYMBOLIC;
634       }
635       pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
636     } else {
637       flags |= PDFFONT_NONSYMBOLIC;
638       size_t i;
639       for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes);
640            i++) {
641         charSets.RemoveAll();
642         charSets.Add(g_FX_CharsetUnicodes[i].m_Charset);
643         if (IsHasCharSet(languages, charSets)) {
644           break;
645         }
646       }
647       if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) {
648         CPDF_Dictionary* pEncoding = new CPDF_Dictionary;
649         pEncoding->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding");
650         CPDF_Array* pArray = new CPDF_Array;
651         pArray->AddInteger(128);
652         const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
653         for (int j = 0; j < 128; j++) {
654           CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
655           if (name.IsEmpty()) {
656             pArray->AddName(FX_BSTRC(".notdef"));
657           } else {
658             pArray->AddName(name);
659           }
660         }
661         pEncoding->SetAt(FX_BSTRC("Differences"), pArray);
662         AddIndirectObject(pEncoding);
663         pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncoding);
664       }
665     }
666     if (weight > 0.0 && trait & kCTFontItalicTrait) {
667       basefont += ",BoldItalic";
668     } else if (weight > 0.0) {
669       basefont += ",Bold";
670     } else if (trait & kCTFontItalicTrait) {
671       basefont += ",Italic";
672     }
673     pBaseDict->SetAtName("Subtype", "TrueType");
674     pBaseDict->SetAtName("BaseFont", basefont);
675     pBaseDict->SetAtNumber("FirstChar", 32);
676     pBaseDict->SetAtNumber("LastChar", 255);
677     int char_widths[224];
678     FX_GetCharWidth(font, 32, 255, char_widths);
679     CPDF_Array* pWidths = new CPDF_Array;
680     for (int i = 0; i < 224; i++) {
681       pWidths->AddInteger(char_widths[i]);
682     }
683     pBaseDict->SetAt("Widths", pWidths);
684   } else {
685     flags |= PDFFONT_NONSYMBOLIC;
686     CPDF_Array* pArray = NULL;
687     pFontDict = new CPDF_Dictionary;
688     CFX_ByteString cmap;
689     CFX_ByteString ordering;
690     int supplement;
691     FX_BOOL bFound = FALSE;
692     CPDF_Array* pWidthArray = new CPDF_Array;
693     charSets.RemoveAll();
694     charSets.Add(FXFONT_CHINESEBIG5_CHARSET);
695     if (IsHasCharSet(languages, charSets)) {
696       cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
697       ordering = "CNS1";
698       supplement = 4;
699       pWidthArray->AddInteger(1);
700       _InsertWidthArray(font, 0x20, 0x7e, pWidthArray);
701       bFound = TRUE;
702     }
703     charSets.RemoveAll();
704     charSets.Add(FXFONT_GB2312_CHARSET);
705     if (!bFound && IsHasCharSet(languages, charSets)) {
706       cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
707       ordering = "GB1", supplement = 2;
708       pWidthArray->AddInteger(7716);
709       _InsertWidthArray(font, 0x20, 0x20, pWidthArray);
710       pWidthArray->AddInteger(814);
711       _InsertWidthArray(font, 0x21, 0x7e, pWidthArray);
712       bFound = TRUE;
713     }
714     charSets.RemoveAll();
715     charSets.Add(FXFONT_HANGEUL_CHARSET);
716     if (!bFound && IsHasCharSet(languages, charSets)) {
717       cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
718       ordering = "Korea1";
719       supplement = 2;
720       pWidthArray->AddInteger(1);
721       _InsertWidthArray(font, 0x20, 0x7e, pWidthArray);
722       bFound = TRUE;
723     }
724     charSets.RemoveAll();
725     charSets.Add(FXFONT_SHIFTJIS_CHARSET);
726     if (!bFound && IsHasCharSet(languages, charSets)) {
727       cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
728       ordering = "Japan1";
729       supplement = 5;
730       pWidthArray->AddInteger(231);
731       _InsertWidthArray(font, 0x20, 0x7d, pWidthArray);
732       pWidthArray->AddInteger(326);
733       _InsertWidthArray(font, 0xa0, 0xa0, pWidthArray);
734       pWidthArray->AddInteger(327);
735       _InsertWidthArray(font, 0xa1, 0xdf, pWidthArray);
736       pWidthArray->AddInteger(631);
737       _InsertWidthArray(font, 0x7e, 0x7e, pWidthArray);
738     }
739     pBaseDict->SetAtName("Subtype", "Type0");
740     pBaseDict->SetAtName("BaseFont", basefont);
741     pBaseDict->SetAtName("Encoding", cmap);
742     pFontDict->SetAt("W", pWidthArray);
743     pFontDict->SetAtName("Type", "Font");
744     pFontDict->SetAtName("Subtype", "CIDFontType2");
745     pFontDict->SetAtName("BaseFont", basefont);
746     CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary;
747     pCIDSysInfo->SetAtString("Registry", "Adobe");
748     pCIDSysInfo->SetAtString("Ordering", ordering);
749     pCIDSysInfo->SetAtInteger("Supplement", supplement);
750     pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
751     pArray = new CPDF_Array;
752     pBaseDict->SetAt("DescendantFonts", pArray);
753     AddIndirectObject(pFontDict);
754     pArray->AddReference(this, pFontDict);
755   }
756   AddIndirectObject(pBaseDict);
757   CPDF_Dictionary* pFontDesc = new CPDF_Dictionary;
758   pFontDesc->SetAtName("Type", "FontDescriptor");
759   pFontDesc->SetAtName("FontName", basefont);
760   pFontDesc->SetAtInteger("Flags", flags);
761   CPDF_Array* pBBox = new CPDF_Array;
762   for (int i = 0; i < 4; i++) {
763     pBBox->AddInteger(bbox[i]);
764   }
765   pFontDesc->SetAt("FontBBox", pBBox);
766   pFontDesc->SetAtInteger("ItalicAngle", italicangle);
767   pFontDesc->SetAtInteger("Ascent", ascend);
768   pFontDesc->SetAtInteger("Descent", descend);
769   pFontDesc->SetAtInteger("CapHeight", capheight);
770   CGFloat fStemV = 0;
771   int16_t min_width = SHRT_MAX;
772   static const UniChar stem_chars[] = {'i', 'I', '!', '1'};
773   const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
774   CGGlyph glyphs[count];
775   CGRect boundingRects[count];
776   if (CTFontGetGlyphsForCharacters(font, stem_chars, glyphs, count)) {
777     CTFontGetBoundingRectsForGlyphs(font, kCTFontHorizontalOrientation, glyphs,
778                                     boundingRects, count);
779     for (size_t i = 0; i < count; i++) {
780       int16_t width = boundingRects[i].size.width;
781       if (width > 0 && width < min_width) {
782         min_width = width;
783         fStemV = min_width;
784       }
785     }
786   }
787   pFontDesc->SetAtInteger("StemV", fStemV);
788   AddIndirectObject(pFontDesc);
789   pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
790   CFRelease(traits);
791   CFRelease(languages);
792   return LoadFont(pBaseDict);
793 }
794 #endif
795 static void _InsertWidthArray1(CFX_Font* pFont,
796                                IFX_FontEncoding* pEncoding,
797                                FX_WCHAR start,
798                                FX_WCHAR end,
799                                CPDF_Array* pWidthArray) {
800   int size = end - start + 1;
801   int* widths = FX_Alloc(int, size);
802   int i;
803   for (i = 0; i < size; i++) {
804     int glyph_index = pEncoding->GlyphFromCharCode(start + i);
805     widths[i] = pFont->GetGlyphWidth(glyph_index);
806   }
807   for (i = 1; i < size; i++)
808     if (widths[i] != *widths) {
809       break;
810     }
811   if (i == size) {
812     int first = pWidthArray->GetInteger(pWidthArray->GetCount() - 1);
813     pWidthArray->AddInteger(first + size - 1);
814     pWidthArray->AddInteger(*widths);
815   } else {
816     CPDF_Array* pWidthArray1 = new CPDF_Array;
817     pWidthArray->Add(pWidthArray1);
818     for (i = 0; i < size; i++) {
819       pWidthArray1->AddInteger(widths[i]);
820     }
821   }
822   FX_Free(widths);
823 }
824 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) {
825   if (pFont == NULL) {
826     return NULL;
827   }
828   FX_BOOL bCJK = charset == FXFONT_CHINESEBIG5_CHARSET ||
829                  charset == FXFONT_GB2312_CHARSET ||
830                  charset == FXFONT_HANGEUL_CHARSET ||
831                  charset == FXFONT_SHIFTJIS_CHARSET;
832   CFX_ByteString basefont = pFont->GetFamilyName();
833   basefont.Replace(" ", "");
834   int flags = 0;
835   if (pFont->IsBold()) {
836     flags |= PDFFONT_FORCEBOLD;
837   }
838   if (pFont->IsItalic()) {
839     flags |= PDFFONT_ITALIC;
840   }
841   if (pFont->IsFixedWidth()) {
842     flags |= PDFFONT_FIXEDPITCH;
843   }
844   CPDF_Dictionary* pBaseDict = new CPDF_Dictionary;
845   pBaseDict->SetAtName("Type", "Font");
846   IFX_FontEncoding* pEncoding = FXGE_CreateUnicodeEncoding(pFont);
847   CPDF_Dictionary* pFontDict = pBaseDict;
848   if (!bCJK) {
849     CPDF_Array* pWidths = new CPDF_Array;
850     int charcode;
851     for (charcode = 32; charcode < 128; charcode++) {
852       int glyph_index = pEncoding->GlyphFromCharCode(charcode);
853       int char_width = pFont->GetGlyphWidth(glyph_index);
854       pWidths->AddInteger(char_width);
855     }
856     if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
857         charset == FXFONT_SYMBOL_CHARSET) {
858       if (charset == FXFONT_SYMBOL_CHARSET) {
859         flags |= PDFFONT_SYMBOLIC;
860       } else {
861         flags |= PDFFONT_NONSYMBOLIC;
862       }
863       pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
864       for (charcode = 128; charcode <= 255; charcode++) {
865         int glyph_index = pEncoding->GlyphFromCharCode(charcode);
866         int char_width = pFont->GetGlyphWidth(glyph_index);
867         pWidths->AddInteger(char_width);
868       }
869     } else {
870       flags |= PDFFONT_NONSYMBOLIC;
871       size_t i;
872       for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes);
873            i++)
874         if (g_FX_CharsetUnicodes[i].m_Charset == charset) {
875           break;
876         }
877       if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) {
878         CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary;
879         pEncodingDict->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding");
880         CPDF_Array* pArray = new CPDF_Array;
881         pArray->AddInteger(128);
882         const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
883         for (int j = 0; j < 128; j++) {
884           CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
885           if (name.IsEmpty()) {
886             pArray->AddName(FX_BSTRC(".notdef"));
887           } else {
888             pArray->AddName(name);
889           }
890           int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
891           int char_width = pFont->GetGlyphWidth(glyph_index);
892           pWidths->AddInteger(char_width);
893         }
894         pEncodingDict->SetAt(FX_BSTRC("Differences"), pArray);
895         AddIndirectObject(pEncodingDict);
896         pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncodingDict);
897       }
898     }
899     if (pFont->IsBold() && pFont->IsItalic()) {
900       basefont += ",BoldItalic";
901     } else if (pFont->IsBold()) {
902       basefont += ",Bold";
903     } else if (pFont->IsItalic()) {
904       basefont += ",Italic";
905     }
906     pBaseDict->SetAtName("Subtype", "TrueType");
907     pBaseDict->SetAtName("BaseFont", basefont);
908     pBaseDict->SetAtNumber("FirstChar", 32);
909     pBaseDict->SetAtNumber("LastChar", 255);
910     pBaseDict->SetAt("Widths", pWidths);
911   } else {
912     flags |= PDFFONT_NONSYMBOLIC;
913     pFontDict = new CPDF_Dictionary;
914     CFX_ByteString cmap;
915     CFX_ByteString ordering;
916     int supplement;
917     CPDF_Array* pWidthArray = new CPDF_Array;
918     switch (charset) {
919       case FXFONT_CHINESEBIG5_CHARSET:
920         cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
921         ordering = "CNS1";
922         supplement = 4;
923         pWidthArray->AddInteger(1);
924         _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7e, pWidthArray);
925         break;
926       case FXFONT_GB2312_CHARSET:
927         cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
928         ordering = "GB1", supplement = 2;
929         pWidthArray->AddInteger(7716);
930         _InsertWidthArray1(pFont, pEncoding, 0x20, 0x20, pWidthArray);
931         pWidthArray->AddInteger(814);
932         _InsertWidthArray1(pFont, pEncoding, 0x21, 0x7e, pWidthArray);
933         break;
934       case FXFONT_HANGEUL_CHARSET:
935         cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
936         ordering = "Korea1";
937         supplement = 2;
938         pWidthArray->AddInteger(1);
939         _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7e, pWidthArray);
940         break;
941       case FXFONT_SHIFTJIS_CHARSET:
942         cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
943         ordering = "Japan1";
944         supplement = 5;
945         pWidthArray->AddInteger(231);
946         _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7d, pWidthArray);
947         pWidthArray->AddInteger(326);
948         _InsertWidthArray1(pFont, pEncoding, 0xa0, 0xa0, pWidthArray);
949         pWidthArray->AddInteger(327);
950         _InsertWidthArray1(pFont, pEncoding, 0xa1, 0xdf, pWidthArray);
951         pWidthArray->AddInteger(631);
952         _InsertWidthArray1(pFont, pEncoding, 0x7e, 0x7e, pWidthArray);
953         break;
954     }
955     pBaseDict->SetAtName("Subtype", "Type0");
956     pBaseDict->SetAtName("BaseFont", basefont);
957     pBaseDict->SetAtName("Encoding", cmap);
958     pFontDict->SetAt("W", pWidthArray);
959     pFontDict->SetAtName("Type", "Font");
960     pFontDict->SetAtName("Subtype", "CIDFontType2");
961     pFontDict->SetAtName("BaseFont", basefont);
962     CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary;
963     pCIDSysInfo->SetAtString("Registry", "Adobe");
964     pCIDSysInfo->SetAtString("Ordering", ordering);
965     pCIDSysInfo->SetAtInteger("Supplement", supplement);
966     pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
967     CPDF_Array* pArray = new CPDF_Array;
968     pBaseDict->SetAt("DescendantFonts", pArray);
969     AddIndirectObject(pFontDict);
970     pArray->AddReference(this, pFontDict);
971   }
972   AddIndirectObject(pBaseDict);
973   CPDF_Dictionary* pFontDesc = new CPDF_Dictionary;
974   pFontDesc->SetAtName("Type", "FontDescriptor");
975   pFontDesc->SetAtName("FontName", basefont);
976   pFontDesc->SetAtInteger("Flags", flags);
977   pFontDesc->SetAtInteger(
978       "ItalicAngle",
979       pFont->m_pSubstFont ? pFont->m_pSubstFont->m_ItalicAngle : 0);
980   pFontDesc->SetAtInteger("Ascent", pFont->GetAscent());
981   pFontDesc->SetAtInteger("Descent", pFont->GetDescent());
982   FX_RECT bbox;
983   pFont->GetBBox(bbox);
984   CPDF_Array* pBBox = new CPDF_Array;
985   pBBox->AddInteger(bbox.left);
986   pBBox->AddInteger(bbox.bottom);
987   pBBox->AddInteger(bbox.right);
988   pBBox->AddInteger(bbox.top);
989   pFontDesc->SetAt("FontBBox", pBBox);
990   int32_t nStemV = 0;
991   if (pFont->m_pSubstFont) {
992     nStemV = pFont->m_pSubstFont->m_Weight / 5;
993   } else {
994     static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'};
995     const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
996     FX_DWORD glyph = pEncoding->GlyphFromCharCode(stem_chars[0]);
997     nStemV = pFont->GetGlyphWidth(glyph);
998     for (size_t i = 1; i < count; i++) {
999       glyph = pEncoding->GlyphFromCharCode(stem_chars[i]);
1000       int width = pFont->GetGlyphWidth(glyph);
1001       if (width > 0 && width < nStemV) {
1002         nStemV = width;
1003       }
1004     }
1005   }
1006   delete pEncoding;
1007   pFontDesc->SetAtInteger("StemV", nStemV);
1008   AddIndirectObject(pFontDesc);
1009   pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
1010   return LoadFont(pBaseDict);
1011 }
1012 static int InsertDeletePDFPage(CPDF_Document* pDoc,
1013                                CPDF_Dictionary* pPages,
1014                                int nPagesToGo,
1015                                CPDF_Dictionary* pPage,
1016                                FX_BOOL bInsert,
1017                                CFX_PtrArray& stackList) {
1018   CPDF_Array* pKidList = pPages->GetArray("Kids");
1019   if (!pKidList) {
1020     return -1;
1021   }
1022   int nKids = pKidList->GetCount();
1023   for (int i = 0; i < nKids; i++) {
1024     CPDF_Dictionary* pKid = pKidList->GetDict(i);
1025     if (pKid->GetString("Type") == FX_BSTRC("Page")) {
1026       if (nPagesToGo == 0) {
1027         if (bInsert) {
1028           pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum()));
1029           pPage->SetAtReference("Parent", pDoc, pPages->GetObjNum());
1030         } else {
1031           pKidList->RemoveAt(i);
1032         }
1033         pPages->SetAtInteger("Count",
1034                              pPages->GetInteger("Count") + (bInsert ? 1 : -1));
1035         return 1;
1036       }
1037       nPagesToGo--;
1038     } else {
1039       int nPages = pKid->GetInteger("Count");
1040       if (nPagesToGo < nPages) {
1041         int stackCount = stackList.GetSize();
1042         for (int j = 0; j < stackCount; ++j) {
1043           if (pKid == stackList[j]) {
1044             return -1;
1045           }
1046         }
1047         stackList.Add(pKid);
1048         if (InsertDeletePDFPage(pDoc, pKid, nPagesToGo, pPage, bInsert,
1049                                 stackList) < 0) {
1050           return -1;
1051         }
1052         stackList.RemoveAt(stackCount);
1053         pPages->SetAtInteger("Count",
1054                              pPages->GetInteger("Count") + (bInsert ? 1 : -1));
1055         return 1;
1056       }
1057       nPagesToGo -= nPages;
1058     }
1059   }
1060   return 0;
1061 }
1062 static int InsertNewPage(CPDF_Document* pDoc,
1063                          int iPage,
1064                          CPDF_Dictionary* pPageDict,
1065                          CFX_DWordArray& pageList) {
1066   CPDF_Dictionary* pRoot = pDoc->GetRoot();
1067   if (!pRoot) {
1068     return -1;
1069   }
1070   CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
1071   if (!pPages) {
1072     return -1;
1073   }
1074   int nPages = pDoc->GetPageCount();
1075   if (iPage < 0 || iPage > nPages) {
1076     return -1;
1077   }
1078   if (iPage == nPages) {
1079     CPDF_Array* pPagesList = pPages->GetArray(FX_BSTRC("Kids"));
1080     if (!pPagesList) {
1081       pPagesList = new CPDF_Array;
1082       pPages->SetAt(FX_BSTRC("Kids"), pPagesList);
1083     }
1084     pPagesList->Add(pPageDict, pDoc);
1085     pPages->SetAtInteger(FX_BSTRC("Count"), nPages + 1);
1086     pPageDict->SetAtReference(FX_BSTRC("Parent"), pDoc, pPages->GetObjNum());
1087   } else {
1088     CFX_PtrArray stack;
1089     stack.Add(pPages);
1090     if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, stack) < 0) {
1091       return -1;
1092     }
1093   }
1094   pageList.InsertAt(iPage, pPageDict->GetObjNum());
1095   return iPage;
1096 }
1097 CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) {
1098   CPDF_Dictionary* pDict = new CPDF_Dictionary;
1099   pDict->SetAtName("Type", "Page");
1100   FX_DWORD dwObjNum = AddIndirectObject(pDict);
1101   if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) {
1102     ReleaseIndirectObject(dwObjNum);
1103     return NULL;
1104   }
1105   return pDict;
1106 }
1107 int _PDF_GetStandardFontName(CFX_ByteString& name);
1108 CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font,
1109                                           CPDF_FontEncoding* pEncoding) {
1110   CFX_ByteString name(font, -1);
1111   if (_PDF_GetStandardFontName(name) < 0) {
1112     return NULL;
1113   }
1114   return GetPageData()->GetStandardFont(name, pEncoding);
1115 }
1116 void CPDF_Document::DeletePage(int iPage) {
1117   CPDF_Dictionary* pRoot = GetRoot();
1118   if (pRoot == NULL) {
1119     return;
1120   }
1121   CPDF_Dictionary* pPages = pRoot->GetDict("Pages");
1122   if (pPages == NULL) {
1123     return;
1124   }
1125   int nPages = pPages->GetInteger("Count");
1126   if (iPage < 0 || iPage >= nPages) {
1127     return;
1128   }
1129   CFX_PtrArray stack;
1130   stack.Add(pPages);
1131   if (InsertDeletePDFPage(this, pPages, iPage, NULL, FALSE, stack) < 0) {
1132     return;
1133   }
1134   m_PageList.RemoveAt(iPage);
1135 }
1136 CPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict,
1137                                  const CFX_ByteStringC& name);
1138 void FPDFAPI_FlatPageAttr(CPDF_Dictionary* pPageDict,
1139                           const CFX_ByteStringC& name) {
1140   if (pPageDict->KeyExist(name)) {
1141     return;
1142   }
1143   CPDF_Object* pObj = FPDFAPI_GetPageAttr(pPageDict, name);
1144   if (pObj) {
1145     pPageDict->SetAt(name, pObj->Clone());
1146   }
1147 }