Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: core/fpdfapi/fpdf_edit/fpdf_edit_doc.cpp

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

Powered by Google App Engine
This is Rietveld 408576698