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

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

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

Powered by Google App Engine
This is Rietveld 408576698