OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "core/fpdfapi/fpdf_font/cpdf_truetypefont.h" | |
8 | |
9 #include "core/fpdfapi/fpdf_font/font_int.h" | |
10 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" | |
11 #include "core/fxge/fx_font.h" | |
12 | |
13 namespace { | |
14 | |
15 const uint8_t kPrefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; | |
16 | |
17 } // namespace | |
18 | |
19 CPDF_TrueTypeFont::CPDF_TrueTypeFont() {} | |
20 | |
21 bool CPDF_TrueTypeFont::IsTrueTypeFont() const { | |
22 return true; | |
23 } | |
24 | |
25 const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const { | |
26 return this; | |
27 } | |
28 | |
29 CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() { | |
30 return this; | |
31 } | |
32 | |
33 bool CPDF_TrueTypeFont::Load() { | |
34 return LoadCommon(); | |
35 } | |
36 | |
37 void CPDF_TrueTypeFont::LoadGlyphMap() { | |
38 if (!m_Font.GetFace()) | |
39 return; | |
40 | |
41 int baseEncoding = m_BaseEncoding; | |
42 if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 && | |
43 (baseEncoding == PDFFONT_ENCODING_MACROMAN || | |
44 baseEncoding == PDFFONT_ENCODING_WINANSI) && | |
45 (m_Flags & PDFFONT_SYMBOLIC)) { | |
46 FX_BOOL bSupportWin = FALSE; | |
47 FX_BOOL bSupportMac = FALSE; | |
48 for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) { | |
49 int platform_id = FXFT_Get_Charmap_PlatformID( | |
50 FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]); | |
51 if (platform_id == 0 || platform_id == 3) { | |
52 bSupportWin = TRUE; | |
53 } else if (platform_id == 0 || platform_id == 1) { | |
54 bSupportMac = TRUE; | |
55 } | |
56 } | |
57 if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { | |
58 baseEncoding = | |
59 bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; | |
60 } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { | |
61 baseEncoding = | |
62 bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; | |
63 } | |
64 } | |
65 if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || | |
66 baseEncoding == PDFFONT_ENCODING_WINANSI) && | |
67 m_CharNames.empty()) || | |
68 (m_Flags & PDFFONT_NONSYMBOLIC)) { | |
69 if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && | |
70 (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { | |
71 int nStartChar = m_pFontDict->GetIntegerFor("FirstChar"); | |
72 if (nStartChar < 0 || nStartChar > 255) | |
73 return; | |
74 | |
75 int charcode = 0; | |
76 for (; charcode < nStartChar; charcode++) { | |
77 m_GlyphIndex[charcode] = 0; | |
78 } | |
79 uint16_t nGlyph = charcode - nStartChar + 3; | |
80 for (; charcode < 256; charcode++, nGlyph++) { | |
81 m_GlyphIndex[charcode] = nGlyph; | |
82 } | |
83 return; | |
84 } | |
85 bool bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); | |
86 bool bMacRoman = false; | |
87 bool bMSSymbol = false; | |
88 if (!bMSUnicode) { | |
89 if (m_Flags & PDFFONT_NONSYMBOLIC) { | |
90 bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); | |
91 bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); | |
92 } else { | |
93 bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0); | |
94 bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0); | |
95 } | |
96 } | |
97 FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode"); | |
98 for (int charcode = 0; charcode < 256; charcode++) { | |
99 const FX_CHAR* name = | |
100 GetAdobeCharName(baseEncoding, m_CharNames, charcode); | |
101 if (!name) { | |
102 m_GlyphIndex[charcode] = | |
103 m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1; | |
104 continue; | |
105 } | |
106 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | |
107 if (bMSSymbol) { | |
108 for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { | |
109 uint16_t unicode = kPrefix[j] * 256 + charcode; | |
110 m_GlyphIndex[charcode] = | |
111 FXFT_Get_Char_Index(m_Font.GetFace(), unicode); | |
112 if (m_GlyphIndex[charcode]) { | |
113 break; | |
114 } | |
115 } | |
116 } else if (m_Encoding.m_Unicodes[charcode]) { | |
117 if (bMSUnicode) { | |
118 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( | |
119 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); | |
120 } else if (bMacRoman) { | |
121 uint32_t maccode = FT_CharCodeFromUnicode( | |
122 FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); | |
123 if (!maccode) { | |
124 m_GlyphIndex[charcode] = | |
125 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); | |
126 } else { | |
127 m_GlyphIndex[charcode] = | |
128 FXFT_Get_Char_Index(m_Font.GetFace(), maccode); | |
129 } | |
130 } | |
131 } | |
132 if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && | |
133 name) { | |
134 if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { | |
135 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32); | |
136 } else { | |
137 m_GlyphIndex[charcode] = | |
138 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); | |
139 if (m_GlyphIndex[charcode] == 0) { | |
140 if (bToUnicode) { | |
141 CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); | |
142 if (!wsUnicode.IsEmpty()) { | |
143 m_GlyphIndex[charcode] = | |
144 FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]); | |
145 m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; | |
146 } | |
147 } | |
148 if (m_GlyphIndex[charcode] == 0) { | |
149 m_GlyphIndex[charcode] = | |
150 FXFT_Get_Char_Index(m_Font.GetFace(), charcode); | |
151 } | |
152 } | |
153 } | |
154 } | |
155 } | |
156 return; | |
157 } | |
158 if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { | |
159 bool bFound = false; | |
160 for (int charcode = 0; charcode < 256; charcode++) { | |
161 for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { | |
162 uint16_t unicode = kPrefix[j] * 256 + charcode; | |
163 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); | |
164 if (m_GlyphIndex[charcode]) { | |
165 bFound = true; | |
166 break; | |
167 } | |
168 } | |
169 } | |
170 if (bFound) { | |
171 if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { | |
172 for (int charcode = 0; charcode < 256; charcode++) { | |
173 const FX_CHAR* name = | |
174 GetAdobeCharName(baseEncoding, m_CharNames, charcode); | |
175 if (name) | |
176 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | |
177 } | |
178 } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { | |
179 for (int charcode = 0; charcode < 256; charcode++) { | |
180 m_Encoding.m_Unicodes[charcode] = | |
181 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); | |
182 } | |
183 } | |
184 return; | |
185 } | |
186 } | |
187 if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { | |
188 bool bFound = false; | |
189 for (int charcode = 0; charcode < 256; charcode++) { | |
190 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); | |
191 m_Encoding.m_Unicodes[charcode] = | |
192 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); | |
193 if (m_GlyphIndex[charcode]) { | |
194 bFound = true; | |
195 } | |
196 } | |
197 if (m_pFontFile || bFound) | |
198 return; | |
199 } | |
200 if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { | |
201 bool bFound = false; | |
202 const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); | |
203 for (int charcode = 0; charcode < 256; charcode++) { | |
204 if (m_pFontFile) { | |
205 m_Encoding.m_Unicodes[charcode] = charcode; | |
206 } else { | |
207 const FX_CHAR* name = GetAdobeCharName(0, m_CharNames, charcode); | |
208 if (name) | |
209 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | |
210 else if (pUnicodes) | |
211 m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; | |
212 } | |
213 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( | |
214 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); | |
215 if (m_GlyphIndex[charcode]) | |
216 bFound = true; | |
217 } | |
218 if (bFound) | |
219 return; | |
220 } | |
221 for (int charcode = 0; charcode < 256; charcode++) | |
222 m_GlyphIndex[charcode] = charcode; | |
223 } | |
OLD | NEW |