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