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