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