OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fpdfapi/fpdf_page.h" | 7 #include "../../../include/fpdfapi/fpdf_page.h" |
8 #include "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
9 #include "../../../include/fpdfapi/fpdf_pageobj.h" | 9 #include "../../../include/fpdfapi/fpdf_pageobj.h" |
10 #include "font_int.h" | 10 #include "font_int.h" |
11 #include "../fpdf_page/pageint.h" | 11 #include "../fpdf_page/pageint.h" |
12 #include "../../../include/fxge/fx_freetype.h" | 12 #include "../../../include/fxge/fx_freetype.h" |
13 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) | 13 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) { |
14 { | 14 for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { |
15 for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i ++) { | 15 if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == |
16 if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == plat
form_id && | 16 platform_id && |
17 FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) ==
encoding_id) { | 17 FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == |
18 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); | 18 encoding_id) { |
19 return TRUE; | 19 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); |
20 } | 20 return TRUE; |
21 } | 21 } |
| 22 } |
| 23 return FALSE; |
| 24 } |
| 25 extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int); |
| 26 CPDF_FontGlobals::CPDF_FontGlobals() { |
| 27 FXSYS_memset32(m_EmbeddedCharsets, 0, sizeof m_EmbeddedCharsets); |
| 28 FXSYS_memset32(m_EmbeddedToUnicodes, 0, sizeof m_EmbeddedToUnicodes); |
| 29 m_pContrastRamps = NULL; |
| 30 } |
| 31 CPDF_FontGlobals::~CPDF_FontGlobals() { |
| 32 ClearAll(); |
| 33 if (m_pContrastRamps) { |
| 34 FX_Free(m_pContrastRamps); |
| 35 } |
| 36 } |
| 37 class CFX_StockFontArray : public CFX_Object { |
| 38 public: |
| 39 CFX_StockFontArray() { |
| 40 FXSYS_memset32(m_pStockFonts, 0, sizeof(CPDF_Font*) * 14); |
| 41 } |
| 42 CPDF_Font* m_pStockFonts[14]; |
| 43 }; |
| 44 CPDF_Font* CPDF_FontGlobals::Find(void* key, int index) { |
| 45 void* value = NULL; |
| 46 if (!m_pStockMap.Lookup(key, value)) { |
| 47 return NULL; |
| 48 } |
| 49 if (!value) { |
| 50 return NULL; |
| 51 } |
| 52 return ((CFX_StockFontArray*)value)->m_pStockFonts[index]; |
| 53 } |
| 54 void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont) { |
| 55 void* value = NULL; |
| 56 if (m_pStockMap.Lookup(key, value)) { |
| 57 ((CFX_StockFontArray*)value)->m_pStockFonts[index] = pFont; |
| 58 return; |
| 59 } |
| 60 CFX_StockFontArray* pFonts = FX_NEW CFX_StockFontArray(); |
| 61 if (pFonts) { |
| 62 pFonts->m_pStockFonts[index] = pFont; |
| 63 } |
| 64 m_pStockMap.SetAt(key, pFonts); |
| 65 } |
| 66 void CPDF_FontGlobals::Clear(void* key) { |
| 67 void* value = NULL; |
| 68 if (!m_pStockMap.Lookup(key, value)) { |
| 69 return; |
| 70 } |
| 71 if (value) { |
| 72 CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value; |
| 73 for (int i = 0; i < 14; i++) { |
| 74 if (pStockFonts->m_pStockFonts[i]) { |
| 75 CPDF_Dictionary* pFontDict = |
| 76 pStockFonts->m_pStockFonts[i]->GetFontDict(); |
| 77 if (pFontDict) |
| 78 pFontDict->Release(); |
| 79 delete pStockFonts->m_pStockFonts[i]; |
| 80 } |
| 81 } |
| 82 delete pStockFonts; |
| 83 } |
| 84 m_pStockMap.RemoveKey(key); |
| 85 } |
| 86 void CPDF_FontGlobals::ClearAll() { |
| 87 FX_POSITION pos = m_pStockMap.GetStartPosition(); |
| 88 while (pos) { |
| 89 void* key = NULL; |
| 90 void* value = NULL; |
| 91 m_pStockMap.GetNextAssoc(pos, key, value); |
| 92 if (value) { |
| 93 CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value; |
| 94 for (int i = 0; i < 14; i++) { |
| 95 if (pStockFonts->m_pStockFonts[i]) { |
| 96 CPDF_Dictionary* pFontDict = |
| 97 pStockFonts->m_pStockFonts[i]->GetFontDict(); |
| 98 if (pFontDict) |
| 99 pFontDict->Release(); |
| 100 delete pStockFonts->m_pStockFonts[i]; |
| 101 } |
| 102 } |
| 103 delete pStockFonts; |
| 104 } |
| 105 m_pStockMap.RemoveKey(key); |
| 106 } |
| 107 } |
| 108 CPDF_Font::CPDF_Font() { |
| 109 m_FontType = 0; |
| 110 m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0; |
| 111 m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0; |
| 112 m_pFontFile = NULL; |
| 113 m_Flags = 0; |
| 114 m_pToUnicodeMap = NULL; |
| 115 m_bToUnicodeLoaded = FALSE; |
| 116 m_pCharMap = NULL; |
| 117 } |
| 118 FX_BOOL CPDF_Font::Initialize() { |
| 119 m_pCharMap = FX_NEW CPDF_FontCharMap(this); |
| 120 return TRUE; |
| 121 } |
| 122 CPDF_Font::~CPDF_Font() { |
| 123 if (m_pCharMap) { |
| 124 FX_Free(m_pCharMap); |
| 125 m_pCharMap = NULL; |
| 126 } |
| 127 if (m_pToUnicodeMap) { |
| 128 delete m_pToUnicodeMap; |
| 129 m_pToUnicodeMap = NULL; |
| 130 } |
| 131 if (m_pFontFile) { |
| 132 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( |
| 133 (CPDF_Stream*)m_pFontFile->GetStream()); |
| 134 } |
| 135 } |
| 136 FX_BOOL CPDF_Font::IsVertWriting() const { |
| 137 FX_BOOL bVertWriting = FALSE; |
| 138 CPDF_CIDFont* pCIDFont = GetCIDFont(); |
| 139 if (pCIDFont) { |
| 140 bVertWriting = pCIDFont->IsVertWriting(); |
| 141 } else { |
| 142 bVertWriting = m_Font.IsVertical(); |
| 143 } |
| 144 return bVertWriting; |
| 145 } |
| 146 CFX_ByteString CPDF_Font::GetFontTypeName() const { |
| 147 switch (m_FontType) { |
| 148 case PDFFONT_TYPE1: |
| 149 return FX_BSTRC("Type1"); |
| 150 case PDFFONT_TRUETYPE: |
| 151 return FX_BSTRC("TrueType"); |
| 152 case PDFFONT_TYPE3: |
| 153 return FX_BSTRC("Type3"); |
| 154 case PDFFONT_CIDFONT: |
| 155 return FX_BSTRC("Type0"); |
| 156 } |
| 157 return CFX_ByteString(); |
| 158 } |
| 159 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const { |
| 160 char buf[4]; |
| 161 int len = AppendChar(buf, charcode); |
| 162 if (len == 1) { |
| 163 str += buf[0]; |
| 164 } else { |
| 165 str += CFX_ByteString(buf, len); |
| 166 } |
| 167 } |
| 168 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const { |
| 169 if (!m_bToUnicodeLoaded) { |
| 170 ((CPDF_Font*)this)->LoadUnicodeMap(); |
| 171 } |
| 172 if (m_pToUnicodeMap) { |
| 173 CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode); |
| 174 if (!wsRet.IsEmpty()) { |
| 175 return wsRet; |
| 176 } |
| 177 } |
| 178 FX_WCHAR unicode = _UnicodeFromCharCode(charcode); |
| 179 if (unicode == 0) { |
| 180 return CFX_WideString(); |
| 181 } |
| 182 return unicode; |
| 183 } |
| 184 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { |
| 185 if (!m_bToUnicodeLoaded) { |
| 186 ((CPDF_Font*)this)->LoadUnicodeMap(); |
| 187 } |
| 188 if (m_pToUnicodeMap) { |
| 189 FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode); |
| 190 if (charcode) { |
| 191 return charcode; |
| 192 } |
| 193 } |
| 194 return _CharCodeFromUnicode(unicode); |
| 195 } |
| 196 CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const { |
| 197 CFX_WideString result; |
| 198 int src_len = str.GetLength(); |
| 199 result.Reserve(src_len); |
| 200 FX_LPCSTR src_buf = str; |
| 201 int src_pos = 0; |
| 202 while (src_pos < src_len) { |
| 203 FX_DWORD charcode = GetNextChar(src_buf, src_pos); |
| 204 CFX_WideString unicode = UnicodeFromCharCode(charcode); |
| 205 if (!unicode.IsEmpty()) { |
| 206 result += unicode; |
| 207 } else { |
| 208 result += (FX_WCHAR)charcode; |
| 209 } |
| 210 } |
| 211 return result; |
| 212 } |
| 213 CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const { |
| 214 CFX_ByteString result; |
| 215 int src_len = str.GetLength(); |
| 216 FX_LPSTR dest_buf = result.GetBuffer(src_len * 2); |
| 217 FX_LPCWSTR src_buf = str; |
| 218 int dest_pos = 0; |
| 219 for (int src_pos = 0; src_pos < src_len; src_pos++) { |
| 220 FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]); |
| 221 dest_pos += AppendChar(dest_buf + dest_pos, charcode); |
| 222 } |
| 223 result.ReleaseBuffer(dest_pos); |
| 224 return result; |
| 225 } |
| 226 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { |
| 227 m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC); |
| 228 int ItalicAngle = 0; |
| 229 FX_BOOL bExistItalicAngle = FALSE; |
| 230 if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) { |
| 231 ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle")); |
| 232 bExistItalicAngle = TRUE; |
| 233 } |
| 234 if (ItalicAngle < 0) { |
| 235 m_Flags |= PDFFONT_ITALIC; |
| 236 m_ItalicAngle = ItalicAngle; |
| 237 } |
| 238 FX_BOOL bExistStemV = FALSE; |
| 239 if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) { |
| 240 m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV")); |
| 241 bExistStemV = TRUE; |
| 242 } |
| 243 FX_BOOL bExistAscent = FALSE; |
| 244 if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) { |
| 245 m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent")); |
| 246 bExistAscent = TRUE; |
| 247 } |
| 248 FX_BOOL bExistDescent = FALSE; |
| 249 if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) { |
| 250 m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent")); |
| 251 bExistDescent = TRUE; |
| 252 } |
| 253 FX_BOOL bExistCapHeight = FALSE; |
| 254 if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) { |
| 255 bExistCapHeight = TRUE; |
| 256 } |
| 257 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && |
| 258 bExistStemV) { |
| 259 m_Flags |= PDFFONT_USEEXTERNATTR; |
| 260 } |
| 261 if (m_Descent > 10) { |
| 262 m_Descent = -m_Descent; |
| 263 } |
| 264 CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox")); |
| 265 if (pBBox) { |
| 266 m_FontBBox.left = pBBox->GetInteger(0); |
| 267 m_FontBBox.bottom = pBBox->GetInteger(1); |
| 268 m_FontBBox.right = pBBox->GetInteger(2); |
| 269 m_FontBBox.top = pBBox->GetInteger(3); |
| 270 } |
| 271 CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile")); |
| 272 if (pFontFile == NULL) { |
| 273 pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2")); |
| 274 } |
| 275 if (pFontFile == NULL) { |
| 276 pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3")); |
| 277 } |
| 278 if (pFontFile) { |
| 279 m_pFontFile = m_pDocument->LoadFontFile(pFontFile); |
| 280 if (m_pFontFile == NULL) { |
| 281 return; |
| 282 } |
| 283 FX_LPCBYTE pFontData = m_pFontFile->GetData(); |
| 284 FX_DWORD dwFontSize = m_pFontFile->GetSize(); |
| 285 m_Font.LoadEmbedded(pFontData, dwFontSize); |
| 286 if (m_Font.m_Face == NULL) { |
| 287 m_pFontFile = NULL; |
| 288 } |
| 289 } |
| 290 } |
| 291 short TT2PDF(int m, FXFT_Face face) { |
| 292 int upm = FXFT_Get_Face_UnitsPerEM(face); |
| 293 if (upm == 0) { |
| 294 return (short)m; |
| 295 } |
| 296 return (m * 1000 + upm / 2) / upm; |
| 297 } |
| 298 void CPDF_Font::CheckFontMetrics() { |
| 299 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && |
| 300 m_FontBBox.right == 0) { |
| 301 if (m_Font.m_Face) { |
| 302 m_FontBBox.left = |
| 303 TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m_Face); |
| 304 m_FontBBox.bottom = |
| 305 TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font.m_Face); |
| 306 m_FontBBox.right = |
| 307 TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.m_Face); |
| 308 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_Face); |
| 309 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Face); |
| 310 m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_Face); |
| 311 } else { |
| 312 FX_BOOL bFirst = TRUE; |
| 313 for (int i = 0; i < 256; i++) { |
| 314 FX_RECT rect; |
| 315 GetCharBBox(i, rect); |
| 316 if (rect.left == rect.right) { |
| 317 continue; |
| 318 } |
| 319 if (bFirst) { |
| 320 m_FontBBox = rect; |
| 321 bFirst = FALSE; |
| 322 } else { |
| 323 if (m_FontBBox.top < rect.top) { |
| 324 m_FontBBox.top = rect.top; |
| 325 } |
| 326 if (m_FontBBox.right < rect.right) { |
| 327 m_FontBBox.right = rect.right; |
| 328 } |
| 329 if (m_FontBBox.left > rect.left) { |
| 330 m_FontBBox.left = rect.left; |
| 331 } |
| 332 if (m_FontBBox.bottom > rect.bottom) { |
| 333 m_FontBBox.bottom = rect.bottom; |
| 334 } |
| 335 } |
| 336 } |
| 337 } |
| 338 } |
| 339 if (m_Ascent == 0 && m_Descent == 0) { |
| 340 FX_RECT rect; |
| 341 GetCharBBox('A', rect); |
| 342 if (rect.bottom == rect.top) { |
| 343 m_Ascent = m_FontBBox.top; |
| 344 } else { |
| 345 m_Ascent = rect.top; |
| 346 } |
| 347 GetCharBBox('g', rect); |
| 348 if (rect.bottom == rect.top) { |
| 349 m_Descent = m_FontBBox.bottom; |
| 350 } else { |
| 351 m_Descent = rect.bottom; |
| 352 } |
| 353 } |
| 354 } |
| 355 void CPDF_Font::LoadUnicodeMap() { |
| 356 m_bToUnicodeLoaded = TRUE; |
| 357 CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode")); |
| 358 if (pStream == NULL) { |
| 359 return; |
| 360 } |
| 361 m_pToUnicodeMap = FX_NEW CPDF_ToUnicodeMap; |
| 362 m_pToUnicodeMap->Load(pStream); |
| 363 } |
| 364 int CPDF_Font::GetStringWidth(FX_LPCSTR pString, int size) { |
| 365 int offset = 0; |
| 366 int width = 0; |
| 367 while (offset < size) { |
| 368 FX_DWORD charcode = GetNextChar(pString, offset); |
| 369 width += GetCharWidthF(charcode); |
| 370 } |
| 371 return width; |
| 372 } |
| 373 int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode) { |
| 374 if (m_Font.m_Face == NULL) { |
| 375 return 0; |
| 376 } |
| 377 int glyph_index = GlyphFromCharCode(charcode); |
| 378 if (glyph_index == 0xffff) { |
| 379 return 0; |
| 380 } |
| 381 return m_Font.GetGlyphWidth(glyph_index); |
| 382 } |
| 383 int _PDF_GetStandardFontName(CFX_ByteString& name); |
| 384 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, FX_BSTR name) { |
| 385 CFX_ByteString fontname(name); |
| 386 int font_id = _PDF_GetStandardFontName(fontname); |
| 387 if (font_id < 0) { |
| 388 return NULL; |
| 389 } |
| 390 CPDF_FontGlobals* pFontGlobals = |
| 391 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); |
| 392 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); |
| 393 if (pFont) { |
| 394 return pFont; |
| 395 } |
| 396 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 397 pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); |
| 398 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); |
| 399 pDict->SetAtName(FX_BSTRC("BaseFont"), fontname); |
| 400 pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding")); |
| 401 pFont = CPDF_Font::CreateFontF(NULL, pDict); |
| 402 pFontGlobals->Set(pDoc, font_id, pFont); |
| 403 return pFont; |
| 404 } |
| 405 const FX_BYTE ChineseFontNames[][5] = { { 0xCB, 0xCE, 0xCC, 0xE5, 0x00 }, |
| 406 { 0xBF, 0xAC, 0xCC, 0xE5, 0x00 }, |
| 407 { 0xBA, 0xDA, 0xCC, 0xE5, 0x00 }, |
| 408 { 0xB7, 0xC2, 0xCB, 0xCE, 0x00 }, |
| 409 { 0xD0, 0xC2, 0xCB, 0xCE, 0x00 } }; |
| 410 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, |
| 411 CPDF_Dictionary* pFontDict) { |
| 412 CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype")); |
| 413 CPDF_Font* pFont; |
| 414 if (type == FX_BSTRC("TrueType")) { |
| 415 { |
| 416 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \ |
| 417 _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \ |
| 418 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \ |
| 419 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 420 CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont")); |
| 421 CFX_ByteString tag = basefont.Left(4); |
| 422 int i; |
| 423 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]); |
| 424 for (i = 0; i < count; ++i) { |
| 425 if (tag == CFX_ByteString((FX_LPCSTR)ChineseFontNames[i])) { |
| 426 break; |
| 427 } |
| 428 } |
| 429 if (i < count) { |
| 430 CPDF_Dictionary* pFontDesc = |
| 431 pFontDict->GetDict(FX_BSTRC("FontDescriptor")); |
| 432 if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) { |
| 433 pFont = FX_NEW CPDF_CIDFont; |
| 434 pFont->Initialize(); |
| 435 pFont->m_FontType = PDFFONT_CIDFONT; |
| 436 pFont->m_pFontDict = pFontDict; |
| 437 pFont->m_pDocument = pDoc; |
| 438 if (!pFont->Load()) { |
| 439 delete pFont; |
| 440 return NULL; |
| 441 } |
| 442 return pFont; |
| 443 } |
| 444 } |
| 445 #endif |
| 446 } |
| 447 pFont = FX_NEW CPDF_TrueTypeFont; |
| 448 pFont->Initialize(); |
| 449 pFont->m_FontType = PDFFONT_TRUETYPE; |
| 450 } else if (type == FX_BSTRC("Type3")) { |
| 451 pFont = FX_NEW CPDF_Type3Font; |
| 452 pFont->Initialize(); |
| 453 pFont->m_FontType = PDFFONT_TYPE3; |
| 454 } else if (type == FX_BSTRC("Type0")) { |
| 455 pFont = FX_NEW CPDF_CIDFont; |
| 456 pFont->Initialize(); |
| 457 pFont->m_FontType = PDFFONT_CIDFONT; |
| 458 } else { |
| 459 pFont = FX_NEW CPDF_Type1Font; |
| 460 pFont->Initialize(); |
| 461 pFont->m_FontType = PDFFONT_TYPE1; |
| 462 } |
| 463 pFont->m_pFontDict = pFontDict; |
| 464 pFont->m_pDocument = pDoc; |
| 465 if (!pFont->Load()) { |
| 466 delete pFont; |
| 467 return NULL; |
| 468 } |
| 469 return pFont; |
| 470 } |
| 471 FX_BOOL CPDF_Font::Load() { |
| 472 if (m_pFontDict == NULL) { |
22 return FALSE; | 473 return FALSE; |
23 } | 474 } |
24 extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int); | 475 CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype")); |
25 CPDF_FontGlobals::CPDF_FontGlobals() | 476 m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont")); |
26 { | 477 if (type == FX_BSTRC("MMType1")) { |
27 FXSYS_memset32(m_EmbeddedCharsets, 0, sizeof m_EmbeddedCharsets); | 478 type = FX_BSTRC("Type1"); |
28 FXSYS_memset32(m_EmbeddedToUnicodes, 0, sizeof m_EmbeddedToUnicodes); | 479 } |
29 m_pContrastRamps = NULL; | 480 return _Load(); |
30 } | 481 } |
31 CPDF_FontGlobals::~CPDF_FontGlobals() | 482 static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, |
32 { | 483 const CFX_ByteString& bytestr) { |
33 ClearAll(); | 484 return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr); |
34 if (m_pContrastRamps) { | 485 } |
35 FX_Free(m_pContrastRamps); | 486 static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, |
36 } | 487 const CFX_WideString& widestr) { |
37 } | 488 return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr); |
38 class CFX_StockFontArray : public CFX_Object | 489 } |
39 { | 490 CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont) { |
40 public: | 491 m_GetByteString = _FontMap_GetByteString; |
41 CFX_StockFontArray() | 492 m_GetWideString = _FontMap_GetWideString; |
42 { | 493 m_pFont = pFont; |
43 FXSYS_memset32(m_pStockFonts, 0, sizeof(CPDF_Font*) * 14); | 494 } |
44 } | 495 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) { |
45 CPDF_Font*» » » m_pStockFonts[14]; | 496 FX_DWORD value; |
46 }; | 497 if (m_Map.Lookup(charcode, value)) { |
47 CPDF_Font* CPDF_FontGlobals::Find(void* key, int index) | 498 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); |
48 { | 499 if (unicode != 0xffff) { |
49 void* value = NULL; | 500 return unicode; |
50 if (!m_pStockMap.Lookup(key, value)) { | 501 } |
51 return NULL; | 502 FX_LPCWSTR buf = m_MultiCharBuf.GetBuffer(); |
52 } | 503 FX_DWORD buf_len = m_MultiCharBuf.GetLength(); |
53 if (!value) { | 504 if (buf == NULL || buf_len == 0) { |
54 return NULL; | 505 return CFX_WideString(); |
55 } | 506 } |
56 return ((CFX_StockFontArray*)value)->m_pStockFonts[index]; | 507 FX_DWORD index = value >> 16; |
57 } | 508 if (index >= buf_len) { |
58 void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont) | 509 return CFX_WideString(); |
59 { | 510 } |
60 void* value = NULL; | 511 FX_DWORD len = buf[index]; |
61 if (m_pStockMap.Lookup(key, value)) { | 512 if (index + len < index || index + len >= buf_len) { |
62 ((CFX_StockFontArray*)value)->m_pStockFonts[index] = pFont; | 513 return CFX_WideString(); |
63 return; | 514 } |
64 } | 515 return CFX_WideString(buf + index + 1, len); |
65 CFX_StockFontArray* pFonts = FX_NEW CFX_StockFontArray(); | 516 } |
66 if (pFonts) { | 517 if (m_pBaseMap) { |
67 pFonts->m_pStockFonts[index] = pFont; | 518 return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode); |
68 } | 519 } |
69 m_pStockMap.SetAt(key, pFonts); | 520 return CFX_WideString(); |
70 } | 521 } |
71 void CPDF_FontGlobals::Clear(void* key) | 522 FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) { |
72 { | 523 FX_POSITION pos = m_Map.GetStartPosition(); |
73 void* value = NULL; | 524 while (pos) { |
74 if (!m_pStockMap.Lookup(key, value)) { | 525 FX_DWORD key, value; |
75 return; | 526 m_Map.GetNextAssoc(pos, key, value); |
76 } | 527 if ((FX_WCHAR)value == unicode) { |
77 if (value) { | 528 return key; |
78 CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value; | 529 } |
79 for (int i = 0; i < 14; i ++) { | 530 } |
80 if (pStockFonts->m_pStockFonts[i]) { | 531 return 0; |
81 CPDF_Dictionary* pFontDict = pStockFonts->m_pStockFonts[i]->GetF
ontDict(); | 532 } |
82 if (pFontDict) | 533 static FX_DWORD _StringToCode(FX_BSTR str) { |
83 pFontDict->Release(); | 534 FX_LPCSTR buf = str.GetCStr(); |
84 delete pStockFonts->m_pStockFonts[i]; | 535 int len = str.GetLength(); |
| 536 if (len == 0) { |
| 537 return 0; |
| 538 } |
| 539 int result = 0; |
| 540 if (buf[0] == '<') { |
| 541 for (int i = 1; i < len; i++) { |
| 542 int digit; |
| 543 if (buf[i] >= '0' && buf[i] <= '9') { |
| 544 digit = buf[i] - '0'; |
| 545 } else if (buf[i] >= 'a' && buf[i] <= 'f') { |
| 546 digit = buf[i] - 'a' + 10; |
| 547 } else if (buf[i] >= 'A' && buf[i] <= 'F') { |
| 548 digit = buf[i] - 'A' + 10; |
| 549 } else { |
| 550 break; |
| 551 } |
| 552 result = result * 16 + digit; |
| 553 } |
| 554 return result; |
| 555 } else { |
| 556 for (int i = 0; i < len; i++) { |
| 557 if (buf[i] < '0' || buf[i] > '9') { |
| 558 break; |
| 559 } |
| 560 result = result * 10 + buf[i] - '0'; |
| 561 } |
| 562 } |
| 563 return result; |
| 564 } |
| 565 static CFX_WideString _StringDataAdd(CFX_WideString str) { |
| 566 CFX_WideString ret; |
| 567 int len = str.GetLength(); |
| 568 FX_WCHAR value = 1; |
| 569 for (int i = len - 1; i >= 0; --i) { |
| 570 FX_WCHAR ch = str[i] + value; |
| 571 if (ch < str[i]) { |
| 572 ret.Insert(0, 0); |
| 573 } else { |
| 574 ret.Insert(0, ch); |
| 575 value = 0; |
| 576 } |
| 577 } |
| 578 if (value) { |
| 579 ret.Insert(0, value); |
| 580 } |
| 581 return ret; |
| 582 } |
| 583 static CFX_WideString _StringToWideString(FX_BSTR str) { |
| 584 FX_LPCSTR buf = str.GetCStr(); |
| 585 int len = str.GetLength(); |
| 586 if (len == 0) { |
| 587 return CFX_WideString(); |
| 588 } |
| 589 CFX_WideString result; |
| 590 if (buf[0] == '<') { |
| 591 int byte_pos = 0; |
| 592 FX_WCHAR ch = 0; |
| 593 for (int i = 1; i < len; i++) { |
| 594 int digit; |
| 595 if (buf[i] >= '0' && buf[i] <= '9') { |
| 596 digit = buf[i] - '0'; |
| 597 } else if (buf[i] >= 'a' && buf[i] <= 'f') { |
| 598 digit = buf[i] - 'a' + 10; |
| 599 } else if (buf[i] >= 'A' && buf[i] <= 'F') { |
| 600 digit = buf[i] - 'A' + 10; |
| 601 } else { |
| 602 break; |
| 603 } |
| 604 ch = ch * 16 + digit; |
| 605 byte_pos++; |
| 606 if (byte_pos == 4) { |
| 607 result += ch; |
| 608 byte_pos = 0; |
| 609 ch = 0; |
| 610 } |
| 611 } |
| 612 return result; |
| 613 } |
| 614 if (buf[0] == '(') { |
| 615 } |
| 616 return result; |
| 617 } |
| 618 void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) { |
| 619 int CIDSet = 0; |
| 620 CPDF_StreamAcc stream; |
| 621 stream.LoadAllData(pStream, FALSE); |
| 622 CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); |
| 623 m_Map.EstimateSize(stream.GetSize() / 8, 1024); |
| 624 while (1) { |
| 625 CFX_ByteStringC word = parser.GetWord(); |
| 626 if (word.IsEmpty()) { |
| 627 break; |
| 628 } |
| 629 if (word == FX_BSTRC("beginbfchar")) { |
| 630 while (1) { |
| 631 word = parser.GetWord(); |
| 632 if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) { |
| 633 break; |
| 634 } |
| 635 FX_DWORD srccode = _StringToCode(word); |
| 636 word = parser.GetWord(); |
| 637 CFX_WideString destcode = _StringToWideString(word); |
| 638 int len = destcode.GetLength(); |
| 639 if (len == 0) { |
| 640 continue; |
| 641 } |
| 642 if (len == 1) { |
| 643 m_Map.SetAt(srccode, destcode.GetAt(0)); |
| 644 } else { |
| 645 m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff); |
| 646 m_MultiCharBuf.AppendChar(destcode.GetLength()); |
| 647 m_MultiCharBuf << destcode; |
| 648 } |
| 649 } |
| 650 } else if (word == FX_BSTRC("beginbfrange")) { |
| 651 while (1) { |
| 652 CFX_ByteString low, high; |
| 653 low = parser.GetWord(); |
| 654 if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) { |
| 655 break; |
| 656 } |
| 657 high = parser.GetWord(); |
| 658 FX_DWORD lowcode = _StringToCode(low); |
| 659 FX_DWORD highcode = |
| 660 (lowcode & 0xffffff00) | (_StringToCode(high) & 0xff); |
| 661 if (highcode == (FX_DWORD)-1) { |
| 662 break; |
| 663 } |
| 664 CFX_ByteString start = parser.GetWord(); |
| 665 if (start == FX_BSTRC("[")) { |
| 666 for (FX_DWORD code = lowcode; code <= highcode; code++) { |
| 667 CFX_ByteString dest = parser.GetWord(); |
| 668 CFX_WideString destcode = _StringToWideString(dest); |
| 669 int len = destcode.GetLength(); |
| 670 if (len == 0) { |
| 671 continue; |
85 } | 672 } |
86 } | 673 if (len == 1) { |
87 delete pStockFonts; | 674 m_Map.SetAt(code, destcode.GetAt(0)); |
88 } | 675 } else { |
89 m_pStockMap.RemoveKey(key); | 676 m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff); |
90 } | 677 m_MultiCharBuf.AppendChar(destcode.GetLength()); |
91 void CPDF_FontGlobals::ClearAll() | 678 m_MultiCharBuf << destcode; |
92 { | |
93 FX_POSITION pos = m_pStockMap.GetStartPosition(); | |
94 while (pos) { | |
95 void *key = NULL; | |
96 void* value = NULL; | |
97 m_pStockMap.GetNextAssoc(pos, key, value); | |
98 if (value) { | |
99 CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value; | |
100 for (int i = 0; i < 14; i ++) { | |
101 if (pStockFonts->m_pStockFonts[i]) { | |
102 CPDF_Dictionary* pFontDict = pStockFonts->m_pStockFonts[i]->
GetFontDict(); | |
103 if (pFontDict) | |
104 pFontDict->Release(); | |
105 delete pStockFonts->m_pStockFonts[i]; | |
106 } | |
107 } | 679 } |
108 delete pStockFonts; | 680 } |
109 } | 681 parser.GetWord(); |
110 m_pStockMap.RemoveKey(key); | 682 } else { |
111 } | 683 CFX_WideString destcode = _StringToWideString(start); |
112 } | 684 int len = destcode.GetLength(); |
113 CPDF_Font::CPDF_Font() | 685 FX_DWORD value = 0; |
114 { | 686 if (len == 1) { |
115 m_FontType = 0; | 687 value = _StringToCode(start); |
116 m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0; | 688 for (FX_DWORD code = lowcode; code <= highcode; code++) { |
117 m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0; | 689 m_Map.SetAt(code, value++); |
118 m_pFontFile = NULL; | 690 } |
119 m_Flags = 0; | 691 } else { |
120 m_pToUnicodeMap = NULL; | 692 for (FX_DWORD code = lowcode; code <= highcode; code++) { |
121 m_bToUnicodeLoaded = FALSE; | 693 CFX_WideString retcode; |
122 m_pCharMap = NULL; | 694 if (code == lowcode) { |
123 } | 695 retcode = destcode; |
124 FX_BOOL CPDF_Font::Initialize() | 696 } else { |
125 { | 697 retcode = _StringDataAdd(destcode); |
126 m_pCharMap = FX_NEW CPDF_FontCharMap(this); | 698 } |
| 699 m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff); |
| 700 m_MultiCharBuf.AppendChar(retcode.GetLength()); |
| 701 m_MultiCharBuf << retcode; |
| 702 destcode = retcode; |
| 703 } |
| 704 } |
| 705 } |
| 706 } |
| 707 } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) { |
| 708 CIDSet = CIDSET_KOREA1; |
| 709 } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) { |
| 710 CIDSet = CIDSET_JAPAN1; |
| 711 } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) { |
| 712 CIDSet = CIDSET_CNS1; |
| 713 } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) { |
| 714 CIDSet = CIDSET_GB1; |
| 715 } |
| 716 } |
| 717 if (CIDSet) { |
| 718 m_pBaseMap = CPDF_ModuleMgr::Get() |
| 719 ->GetPageModule() |
| 720 ->GetFontGlobals() |
| 721 ->m_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE); |
| 722 } else { |
| 723 m_pBaseMap = NULL; |
| 724 } |
| 725 } |
| 726 static FX_BOOL GetPredefinedEncoding(int& basemap, |
| 727 const CFX_ByteString& value) { |
| 728 if (value == FX_BSTRC("WinAnsiEncoding")) { |
| 729 basemap = PDFFONT_ENCODING_WINANSI; |
| 730 } else if (value == FX_BSTRC("MacRomanEncoding")) { |
| 731 basemap = PDFFONT_ENCODING_MACROMAN; |
| 732 } else if (value == FX_BSTRC("MacExpertEncoding")) { |
| 733 basemap = PDFFONT_ENCODING_MACEXPERT; |
| 734 } else if (value == FX_BSTRC("PDFDocEncoding")) { |
| 735 basemap = PDFFONT_ENCODING_PDFDOC; |
| 736 } else { |
| 737 return FALSE; |
| 738 } |
| 739 return TRUE; |
| 740 } |
| 741 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, |
| 742 int& iBaseEncoding, |
| 743 CFX_ByteString*& pCharNames, |
| 744 FX_BOOL bEmbedded, |
| 745 FX_BOOL bTrueType) { |
| 746 if (pEncoding == NULL) { |
| 747 if (m_BaseFont == FX_BSTRC("Symbol")) { |
| 748 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL |
| 749 : PDFFONT_ENCODING_ADOBE_SYMBOL; |
| 750 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { |
| 751 iBaseEncoding = PDFFONT_ENCODING_WINANSI; |
| 752 } |
| 753 return; |
| 754 } |
| 755 if (pEncoding->GetType() == PDFOBJ_NAME) { |
| 756 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || |
| 757 iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { |
| 758 return; |
| 759 } |
| 760 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) { |
| 761 if (!bTrueType) { |
| 762 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; |
| 763 } |
| 764 return; |
| 765 } |
| 766 CFX_ByteString bsEncoding = pEncoding->GetString(); |
| 767 if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) { |
| 768 bsEncoding = FX_BSTRC("WinAnsiEncoding"); |
| 769 } |
| 770 GetPredefinedEncoding(iBaseEncoding, bsEncoding); |
| 771 return; |
| 772 } |
| 773 if (pEncoding->GetType() != PDFOBJ_DICTIONARY) { |
| 774 return; |
| 775 } |
| 776 CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding; |
| 777 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && |
| 778 iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { |
| 779 CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding")); |
| 780 if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType) { |
| 781 bsEncoding = FX_BSTRC("WinAnsiEncoding"); |
| 782 } |
| 783 GetPredefinedEncoding(iBaseEncoding, bsEncoding); |
| 784 } |
| 785 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { |
| 786 iBaseEncoding = PDFFONT_ENCODING_STANDARD; |
| 787 } |
| 788 CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences")); |
| 789 if (pDiffs == NULL) { |
| 790 return; |
| 791 } |
| 792 FX_NEW_VECTOR(pCharNames, CFX_ByteString, 256); |
| 793 FX_DWORD cur_code = 0; |
| 794 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) { |
| 795 CPDF_Object* pElement = pDiffs->GetElementValue(i); |
| 796 if (pElement == NULL) { |
| 797 continue; |
| 798 } |
| 799 if (pElement->GetType() == PDFOBJ_NAME) { |
| 800 if (cur_code < 256) { |
| 801 pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString(); |
| 802 } |
| 803 cur_code++; |
| 804 } else { |
| 805 cur_code = pElement->GetInteger(); |
| 806 } |
| 807 } |
| 808 } |
| 809 FX_BOOL CPDF_Font::IsStandardFont() const { |
| 810 if (m_FontType != PDFFONT_TYPE1) { |
| 811 return FALSE; |
| 812 } |
| 813 if (m_pFontFile != NULL) { |
| 814 return FALSE; |
| 815 } |
| 816 if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) { |
| 817 return FALSE; |
| 818 } |
| 819 return TRUE; |
| 820 } |
| 821 extern FX_LPCSTR PDF_CharNameFromPredefinedCharSet(int encoding, |
| 822 FX_BYTE charcode); |
| 823 CPDF_SimpleFont::CPDF_SimpleFont() { |
| 824 FXSYS_memset8(m_CharBBox, 0xff, sizeof m_CharBBox); |
| 825 FXSYS_memset8(m_CharWidth, 0xff, sizeof m_CharWidth); |
| 826 FXSYS_memset8(m_GlyphIndex, 0xff, sizeof m_GlyphIndex); |
| 827 FXSYS_memset8(m_ExtGID, 0xff, sizeof m_ExtGID); |
| 828 m_pCharNames = NULL; |
| 829 m_BaseEncoding = PDFFONT_ENCODING_BUILTIN; |
| 830 } |
| 831 CPDF_SimpleFont::~CPDF_SimpleFont() { |
| 832 if (m_pCharNames) { |
| 833 FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256); |
| 834 } |
| 835 } |
| 836 int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) { |
| 837 if (pVertGlyph) { |
| 838 *pVertGlyph = FALSE; |
| 839 } |
| 840 if (charcode > 0xff) { |
| 841 return -1; |
| 842 } |
| 843 int index = m_GlyphIndex[(FX_BYTE)charcode]; |
| 844 if (index == 0xffff) { |
| 845 return -1; |
| 846 } |
| 847 return index; |
| 848 } |
| 849 void CPDF_SimpleFont::LoadCharMetrics(int charcode) { |
| 850 if (m_Font.m_Face == NULL) { |
| 851 return; |
| 852 } |
| 853 if (charcode < 0 || charcode > 0xff) { |
| 854 return; |
| 855 } |
| 856 int glyph_index = m_GlyphIndex[charcode]; |
| 857 if (glyph_index == 0xffff) { |
| 858 if (m_pFontFile == NULL && charcode != 32) { |
| 859 LoadCharMetrics(32); |
| 860 m_CharBBox[charcode] = m_CharBBox[32]; |
| 861 if (m_bUseFontWidth) { |
| 862 m_CharWidth[charcode] = m_CharWidth[32]; |
| 863 } |
| 864 } |
| 865 return; |
| 866 } |
| 867 int err = FXFT_Load_Glyph( |
| 868 m_Font.m_Face, |
| 869 glyph_index, |
| 870 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); |
| 871 if (err) { |
| 872 return; |
| 873 } |
| 874 m_CharBBox[charcode].Left = |
| 875 TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face), m_Font.m_Face); |
| 876 m_CharBBox[charcode].Right = |
| 877 TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face) + |
| 878 FXFT_Get_Glyph_Width(m_Font.m_Face), |
| 879 m_Font.m_Face); |
| 880 m_CharBBox[charcode].Top = |
| 881 TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face), m_Font.m_Face); |
| 882 m_CharBBox[charcode].Bottom = |
| 883 TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face) - |
| 884 FXFT_Get_Glyph_Height(m_Font.m_Face), |
| 885 m_Font.m_Face); |
| 886 if (m_bUseFontWidth) { |
| 887 int TT_Width = |
| 888 TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.m_Face); |
| 889 if (m_CharWidth[charcode] == 0xffff) { |
| 890 m_CharWidth[charcode] = TT_Width; |
| 891 } else if (TT_Width && !IsEmbedded()) { |
| 892 m_CharBBox[charcode].Right = |
| 893 m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width; |
| 894 m_CharBBox[charcode].Left = |
| 895 m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width; |
| 896 } |
| 897 } |
| 898 } |
| 899 int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) { |
| 900 if (charcode > 0xff) { |
| 901 charcode = 0; |
| 902 } |
| 903 if (m_CharWidth[charcode] == 0xffff) { |
| 904 LoadCharMetrics(charcode); |
| 905 if (m_CharWidth[charcode] == 0xffff) { |
| 906 m_CharWidth[charcode] = 0; |
| 907 } |
| 908 } |
| 909 return (FX_INT16)m_CharWidth[charcode]; |
| 910 } |
| 911 void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) { |
| 912 if (charcode > 0xff) { |
| 913 charcode = 0; |
| 914 } |
| 915 if (m_CharBBox[charcode].Left == (FX_SHORT)0xffff) { |
| 916 LoadCharMetrics(charcode); |
| 917 } |
| 918 rect.left = m_CharBBox[charcode].Left; |
| 919 rect.right = m_CharBBox[charcode].Right; |
| 920 rect.bottom = m_CharBBox[charcode].Bottom; |
| 921 rect.top = m_CharBBox[charcode].Top; |
| 922 } |
| 923 FX_LPCSTR GetAdobeCharName(int iBaseEncoding, |
| 924 const CFX_ByteString* pCharNames, |
| 925 int charcode) { |
| 926 ASSERT(charcode >= 0 && charcode < 256); |
| 927 if (charcode < 0 || charcode >= 256) { |
| 928 return NULL; |
| 929 } |
| 930 FX_LPCSTR name = NULL; |
| 931 if (pCharNames) { |
| 932 name = pCharNames[charcode]; |
| 933 } |
| 934 if ((name == NULL || name[0] == 0) && iBaseEncoding) { |
| 935 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); |
| 936 } |
| 937 if (name == NULL || name[0] == 0) { |
| 938 return NULL; |
| 939 } |
| 940 return name; |
| 941 } |
| 942 FX_BOOL CPDF_SimpleFont::LoadCommon() { |
| 943 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor")); |
| 944 if (pFontDesc) { |
| 945 LoadFontDescriptor(pFontDesc); |
| 946 } |
| 947 CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths")); |
| 948 int width_start = 0, width_end = -1; |
| 949 m_bUseFontWidth = TRUE; |
| 950 if (pWidthArray) { |
| 951 m_bUseFontWidth = FALSE; |
| 952 if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) { |
| 953 int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth")); |
| 954 for (int i = 0; i < 256; i++) { |
| 955 m_CharWidth[i] = MissingWidth; |
| 956 } |
| 957 } |
| 958 width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0); |
| 959 width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0); |
| 960 if (width_start >= 0 && width_start <= 255) { |
| 961 if (width_end <= 0 || |
| 962 width_end >= width_start + (int)pWidthArray->GetCount()) { |
| 963 width_end = width_start + pWidthArray->GetCount() - 1; |
| 964 } |
| 965 if (width_end > 255) { |
| 966 width_end = 255; |
| 967 } |
| 968 for (int i = width_start; i <= width_end; i++) { |
| 969 m_CharWidth[i] = pWidthArray->GetInteger(i - width_start); |
| 970 } |
| 971 } |
| 972 } |
| 973 if (m_pFontFile == NULL) { |
| 974 LoadSubstFont(); |
| 975 } else { |
| 976 if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { |
| 977 m_BaseFont = m_BaseFont.Mid(8); |
| 978 } |
| 979 } |
| 980 if (!(m_Flags & PDFFONT_SYMBOLIC)) { |
| 981 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; |
| 982 } |
| 983 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); |
| 984 LoadPDFEncoding(pEncoding, |
| 985 m_BaseEncoding, |
| 986 m_pCharNames, |
| 987 m_pFontFile != NULL, |
| 988 m_Font.IsTTFont()); |
| 989 LoadGlyphMap(); |
| 990 if (m_pCharNames) { |
| 991 FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256); |
| 992 m_pCharNames = NULL; |
| 993 } |
| 994 if (m_Font.m_Face == NULL) { |
127 return TRUE; | 995 return TRUE; |
128 } | 996 } |
129 CPDF_Font::~CPDF_Font() | 997 if (m_Flags & PDFFONT_ALLCAP) { |
130 { | 998 unsigned char lowercases[] = { 'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd }; |
131 if (m_pCharMap) { | 999 for (size_t range = 0; range < sizeof lowercases / 2; range++) { |
132 FX_Free(m_pCharMap); | 1000 for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) { |
133 m_pCharMap = NULL; | 1001 if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) { |
134 } | 1002 continue; |
135 if (m_pToUnicodeMap) { | 1003 } |
136 delete m_pToUnicodeMap; | 1004 m_GlyphIndex[i] = m_GlyphIndex[i - 32]; |
137 m_pToUnicodeMap = NULL; | 1005 if (m_CharWidth[i - 32]) { |
138 } | 1006 m_CharWidth[i] = m_CharWidth[i - 32]; |
139 if (m_pFontFile) { | 1007 m_CharBBox[i] = m_CharBBox[i - 32]; |
140 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc((CPDF_Stream*)m_pFo
ntFile->GetStream()); | 1008 } |
141 } | 1009 } |
142 } | 1010 } |
143 FX_BOOL CPDF_Font::IsVertWriting() const | 1011 } |
144 { | 1012 CheckFontMetrics(); |
145 FX_BOOL bVertWriting = FALSE; | 1013 return TRUE; |
146 CPDF_CIDFont* pCIDFont = GetCIDFont(); | 1014 } |
147 if (pCIDFont) { | 1015 void CPDF_SimpleFont::LoadSubstFont() { |
148 bVertWriting = pCIDFont->IsVertWriting(); | 1016 if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { |
| 1017 int width = 0, i; |
| 1018 for (i = 0; i < 256; i++) { |
| 1019 if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { |
| 1020 continue; |
| 1021 } |
| 1022 if (width == 0) { |
| 1023 width = m_CharWidth[i]; |
| 1024 } else if (width != m_CharWidth[i]) { |
| 1025 break; |
| 1026 } |
| 1027 } |
| 1028 if (i == 256 && width) { |
| 1029 m_Flags |= PDFFONT_FIXEDPITCH; |
| 1030 } |
| 1031 } |
| 1032 int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140); |
| 1033 m_Font.LoadSubst(m_BaseFont, |
| 1034 m_FontType == PDFFONT_TRUETYPE, |
| 1035 m_Flags, |
| 1036 weight, |
| 1037 m_ItalicAngle, |
| 1038 0); |
| 1039 if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) { |
| 1040 } |
| 1041 } |
| 1042 FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const { |
| 1043 return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && |
| 1044 m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && |
| 1045 m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS; |
| 1046 } |
| 1047 CPDF_Type1Font::CPDF_Type1Font() { |
| 1048 m_Base14Font = -1; |
| 1049 } |
| 1050 FX_BOOL CPDF_Type1Font::_Load() { |
| 1051 m_Base14Font = _PDF_GetStandardFontName(m_BaseFont); |
| 1052 if (m_Base14Font >= 0) { |
| 1053 CPDF_Dictionary* pFontDesc = |
| 1054 m_pFontDict->GetDict(FX_BSTRC("FontDescriptor")); |
| 1055 if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) { |
| 1056 m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags")); |
149 } else { | 1057 } else { |
150 bVertWriting = m_Font.IsVertical(); | 1058 m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC; |
151 } | 1059 } |
152 return bVertWriting; | 1060 if (m_Base14Font < 4) |
153 } | 1061 for (int i = 0; i < 256; i++) { |
154 CFX_ByteString CPDF_Font::GetFontTypeName() const | 1062 m_CharWidth[i] = 600; |
155 { | 1063 } |
156 switch (m_FontType) { | 1064 if (m_Base14Font == 12) { |
157 case PDFFONT_TYPE1: | 1065 m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; |
158 return FX_BSTRC("Type1"); | 1066 } else if (m_Base14Font == 13) { |
159 case PDFFONT_TRUETYPE: | 1067 m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; |
160 return FX_BSTRC("TrueType"); | 1068 } else if (m_Flags & PDFFONT_NONSYMBOLIC) { |
161 case PDFFONT_TYPE3: | 1069 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; |
162 return FX_BSTRC("Type3"); | 1070 } |
163 case PDFFONT_CIDFONT: | 1071 } |
164 return FX_BSTRC("Type0"); | 1072 return LoadCommon(); |
165 } | 1073 } |
166 return CFX_ByteString(); | 1074 static FX_BOOL FT_UseType1Charmap(FXFT_Face face) { |
167 } | 1075 if (FXFT_Get_Face_CharmapCount(face) == 0) { |
168 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const | 1076 return FALSE; |
169 { | 1077 } |
170 char buf[4]; | 1078 if (FXFT_Get_Face_CharmapCount(face) == 1 && |
171 int len = AppendChar(buf, charcode); | 1079 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == |
172 if (len == 1) { | 1080 FXFT_ENCODING_UNICODE) { |
173 str += buf[0]; | 1081 return FALSE; |
174 } else { | 1082 } |
175 str += CFX_ByteString(buf, len); | 1083 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == |
176 } | 1084 FXFT_ENCODING_UNICODE) { |
177 } | 1085 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); |
178 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const | 1086 } else { |
179 { | 1087 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); |
180 if (!m_bToUnicodeLoaded) { | 1088 } |
181 ((CPDF_Font*)this)->LoadUnicodeMap(); | 1089 return TRUE; |
182 } | |
183 if (m_pToUnicodeMap) { | |
184 CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode); | |
185 if (!wsRet.IsEmpty()) { | |
186 return wsRet; | |
187 } | |
188 } | |
189 FX_WCHAR unicode = _UnicodeFromCharCode(charcode); | |
190 if (unicode == 0) { | |
191 return CFX_WideString(); | |
192 } | |
193 return unicode; | |
194 } | |
195 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const | |
196 { | |
197 if (!m_bToUnicodeLoaded) { | |
198 ((CPDF_Font*)this)->LoadUnicodeMap(); | |
199 } | |
200 if (m_pToUnicodeMap) { | |
201 FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode); | |
202 if (charcode) { | |
203 return charcode; | |
204 } | |
205 } | |
206 return _CharCodeFromUnicode(unicode); | |
207 } | |
208 CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const | |
209 { | |
210 CFX_WideString result; | |
211 int src_len = str.GetLength(); | |
212 result.Reserve(src_len); | |
213 FX_LPCSTR src_buf = str; | |
214 int src_pos = 0; | |
215 while (src_pos < src_len) { | |
216 FX_DWORD charcode = GetNextChar(src_buf, src_pos); | |
217 CFX_WideString unicode = UnicodeFromCharCode(charcode); | |
218 if (!unicode.IsEmpty()) { | |
219 result += unicode; | |
220 } else { | |
221 result += (FX_WCHAR)charcode; | |
222 } | |
223 } | |
224 return result; | |
225 } | |
226 CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const | |
227 { | |
228 CFX_ByteString result; | |
229 int src_len = str.GetLength(); | |
230 FX_LPSTR dest_buf = result.GetBuffer(src_len * 2); | |
231 FX_LPCWSTR src_buf = str; | |
232 int dest_pos = 0; | |
233 for (int src_pos = 0; src_pos < src_len; src_pos ++) { | |
234 FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]); | |
235 dest_pos += AppendChar(dest_buf + dest_pos, charcode); | |
236 } | |
237 result.ReleaseBuffer(dest_pos); | |
238 return result; | |
239 } | |
240 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) | |
241 { | |
242 m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC); | |
243 int ItalicAngle = 0; | |
244 FX_BOOL bExistItalicAngle = FALSE; | |
245 if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) { | |
246 ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle")); | |
247 bExistItalicAngle = TRUE; | |
248 } | |
249 if (ItalicAngle < 0) { | |
250 m_Flags |= PDFFONT_ITALIC; | |
251 m_ItalicAngle = ItalicAngle; | |
252 } | |
253 FX_BOOL bExistStemV = FALSE; | |
254 if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) { | |
255 m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV")); | |
256 bExistStemV = TRUE; | |
257 } | |
258 FX_BOOL bExistAscent = FALSE; | |
259 if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) { | |
260 m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent")); | |
261 bExistAscent = TRUE; | |
262 } | |
263 FX_BOOL bExistDescent = FALSE; | |
264 if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) { | |
265 m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent")); | |
266 bExistDescent = TRUE; | |
267 } | |
268 FX_BOOL bExistCapHeight = FALSE; | |
269 if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) { | |
270 bExistCapHeight = TRUE; | |
271 } | |
272 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
bExistStemV) { | |
273 m_Flags |= PDFFONT_USEEXTERNATTR; | |
274 } | |
275 if (m_Descent > 10) { | |
276 m_Descent = -m_Descent; | |
277 } | |
278 CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox")); | |
279 if (pBBox) { | |
280 m_FontBBox.left = pBBox->GetInteger(0); | |
281 m_FontBBox.bottom = pBBox->GetInteger(1); | |
282 m_FontBBox.right = pBBox->GetInteger(2); | |
283 m_FontBBox.top = pBBox->GetInteger(3); | |
284 } | |
285 CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile")); | |
286 if (pFontFile == NULL) { | |
287 pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2")); | |
288 } | |
289 if (pFontFile == NULL) { | |
290 pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3")); | |
291 } | |
292 if (pFontFile) { | |
293 m_pFontFile = m_pDocument->LoadFontFile(pFontFile); | |
294 if (m_pFontFile == NULL) { | |
295 return; | |
296 } | |
297 FX_LPCBYTE pFontData = m_pFontFile->GetData(); | |
298 FX_DWORD dwFontSize = m_pFontFile->GetSize(); | |
299 m_Font.LoadEmbedded(pFontData, dwFontSize); | |
300 if (m_Font.m_Face == NULL) { | |
301 m_pFontFile = NULL; | |
302 } | |
303 } | |
304 } | |
305 short TT2PDF(int m, FXFT_Face face) | |
306 { | |
307 int upm = FXFT_Get_Face_UnitsPerEM(face); | |
308 if (upm == 0) { | |
309 return (short)m; | |
310 } | |
311 return (m * 1000 + upm / 2) / upm; | |
312 } | |
313 void CPDF_Font::CheckFontMetrics() | |
314 { | |
315 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
m_FontBBox.right == 0) { | |
316 if (m_Font.m_Face) { | |
317 m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m
_Face); | |
318 m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font
.m_Face); | |
319 m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.
m_Face); | |
320 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_
Face); | |
321 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Fa
ce); | |
322 m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_
Face); | |
323 } else { | |
324 FX_BOOL bFirst = TRUE; | |
325 for (int i = 0; i < 256; i ++) { | |
326 FX_RECT rect; | |
327 GetCharBBox(i, rect); | |
328 if (rect.left == rect.right) { | |
329 continue; | |
330 } | |
331 if (bFirst) { | |
332 m_FontBBox = rect; | |
333 bFirst = FALSE; | |
334 } else { | |
335 if (m_FontBBox.top < rect.top) { | |
336 m_FontBBox.top = rect.top; | |
337 } | |
338 if (m_FontBBox.right < rect.right) { | |
339 m_FontBBox.right = rect.right; | |
340 } | |
341 if (m_FontBBox.left > rect.left) { | |
342 m_FontBBox.left = rect.left; | |
343 } | |
344 if (m_FontBBox.bottom > rect.bottom) { | |
345 m_FontBBox.bottom = rect.bottom; | |
346 } | |
347 } | |
348 } | |
349 } | |
350 } | |
351 if (m_Ascent == 0 && m_Descent == 0) { | |
352 FX_RECT rect; | |
353 GetCharBBox('A', rect); | |
354 if (rect.bottom == rect.top) { | |
355 m_Ascent = m_FontBBox.top; | |
356 } else { | |
357 m_Ascent = rect.top; | |
358 } | |
359 GetCharBBox('g', rect); | |
360 if (rect.bottom == rect.top) { | |
361 m_Descent = m_FontBBox.bottom; | |
362 } else { | |
363 m_Descent = rect.bottom; | |
364 } | |
365 } | |
366 } | |
367 void CPDF_Font::LoadUnicodeMap() | |
368 { | |
369 m_bToUnicodeLoaded = TRUE; | |
370 CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode")); | |
371 if (pStream == NULL) { | |
372 return; | |
373 } | |
374 m_pToUnicodeMap = FX_NEW CPDF_ToUnicodeMap; | |
375 m_pToUnicodeMap->Load(pStream); | |
376 } | |
377 int CPDF_Font::GetStringWidth(FX_LPCSTR pString, int size) | |
378 { | |
379 int offset = 0; | |
380 int width = 0; | |
381 while (offset < size) { | |
382 FX_DWORD charcode = GetNextChar(pString, offset); | |
383 width += GetCharWidthF(charcode); | |
384 } | |
385 return width; | |
386 } | |
387 int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode) | |
388 { | |
389 if (m_Font.m_Face == NULL) { | |
390 return 0; | |
391 } | |
392 int glyph_index = GlyphFromCharCode(charcode); | |
393 if (glyph_index == 0xffff) { | |
394 return 0; | |
395 } | |
396 return m_Font.GetGlyphWidth(glyph_index); | |
397 } | |
398 int _PDF_GetStandardFontName(CFX_ByteString& name); | |
399 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, FX_BSTR name) | |
400 { | |
401 CFX_ByteString fontname(name); | |
402 int font_id = _PDF_GetStandardFontName(fontname); | |
403 if (font_id < 0) { | |
404 return NULL; | |
405 } | |
406 CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->Get
FontGlobals(); | |
407 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); | |
408 if (pFont) { | |
409 return pFont; | |
410 } | |
411 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
412 pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font")); | |
413 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1")); | |
414 pDict->SetAtName(FX_BSTRC("BaseFont"), fontname); | |
415 pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding")); | |
416 pFont = CPDF_Font::CreateFontF(NULL, pDict); | |
417 pFontGlobals->Set(pDoc, font_id, pFont); | |
418 return pFont; | |
419 } | |
420 const FX_BYTE ChineseFontNames[][5] = { | |
421 {0xCB, 0xCE, 0xCC, 0xE5, 0x00}, | |
422 {0xBF, 0xAC, 0xCC, 0xE5, 0x00}, | |
423 {0xBA, 0xDA, 0xCC, 0xE5, 0x00}, | |
424 {0xB7, 0xC2, 0xCB, 0xCE, 0x00}, | |
425 {0xD0, 0xC2, 0xCB, 0xCE, 0x00} | |
426 }; | |
427 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDic
t) | |
428 { | |
429 CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype")); | |
430 CPDF_Font* pFont; | |
431 if (type == FX_BSTRC("TrueType")) { | |
432 { | |
433 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM
_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || _FXM_PLATFORM_ == _FXM_PL
ATFORM_APPLE_ | |
434 CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont"))
; | |
435 CFX_ByteString tag = basefont.Left(4); | |
436 int i; | |
437 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]); | |
438 for (i = 0; i < count; ++i) { | |
439 if (tag == CFX_ByteString((FX_LPCSTR)ChineseFontNames[i])) { | |
440 break; | |
441 } | |
442 } | |
443 if (i < count) { | |
444 CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDe
scriptor")); | |
445 if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile
2"))) { | |
446 pFont = FX_NEW CPDF_CIDFont; | |
447 pFont->Initialize(); | |
448 pFont->m_FontType = PDFFONT_CIDFONT; | |
449 pFont->m_pFontDict = pFontDict; | |
450 pFont->m_pDocument = pDoc; | |
451 if (!pFont->Load()) { | |
452 delete pFont; | |
453 return NULL; | |
454 } | |
455 return pFont; | |
456 } | |
457 } | |
458 #endif | |
459 } | |
460 pFont = FX_NEW CPDF_TrueTypeFont; | |
461 pFont->Initialize(); | |
462 pFont->m_FontType = PDFFONT_TRUETYPE; | |
463 } else if (type == FX_BSTRC("Type3")) { | |
464 pFont = FX_NEW CPDF_Type3Font; | |
465 pFont->Initialize(); | |
466 pFont->m_FontType = PDFFONT_TYPE3; | |
467 } else if (type == FX_BSTRC("Type0")) { | |
468 pFont = FX_NEW CPDF_CIDFont; | |
469 pFont->Initialize(); | |
470 pFont->m_FontType = PDFFONT_CIDFONT; | |
471 } else { | |
472 pFont = FX_NEW CPDF_Type1Font; | |
473 pFont->Initialize(); | |
474 pFont->m_FontType = PDFFONT_TYPE1; | |
475 } | |
476 pFont->m_pFontDict = pFontDict; | |
477 pFont->m_pDocument = pDoc; | |
478 if (!pFont->Load()) { | |
479 delete pFont; | |
480 return NULL; | |
481 } | |
482 return pFont; | |
483 } | |
484 FX_BOOL CPDF_Font::Load() | |
485 { | |
486 if (m_pFontDict == NULL) { | |
487 return FALSE; | |
488 } | |
489 CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype")); | |
490 m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont")); | |
491 if (type == FX_BSTRC("MMType1")) { | |
492 type = FX_BSTRC("Type1"); | |
493 } | |
494 return _Load(); | |
495 } | |
496 static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, const CFX_ByteSt
ring& bytestr) | |
497 { | |
498 return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr); | |
499 } | |
500 static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, const CFX_WideSt
ring& widestr) | |
501 { | |
502 return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr); | |
503 } | |
504 CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont) | |
505 { | |
506 m_GetByteString = _FontMap_GetByteString; | |
507 m_GetWideString = _FontMap_GetWideString; | |
508 m_pFont = pFont; | |
509 } | |
510 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) | |
511 { | |
512 FX_DWORD value; | |
513 if (m_Map.Lookup(charcode, value)) { | |
514 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); | |
515 if (unicode != 0xffff) { | |
516 return unicode; | |
517 } | |
518 FX_LPCWSTR buf = m_MultiCharBuf.GetBuffer(); | |
519 FX_DWORD buf_len = m_MultiCharBuf.GetLength(); | |
520 if (buf == NULL || buf_len == 0) { | |
521 return CFX_WideString(); | |
522 } | |
523 FX_DWORD index = value >> 16; | |
524 if (index >= buf_len) { | |
525 return CFX_WideString(); | |
526 } | |
527 FX_DWORD len = buf[index]; | |
528 if (index + len < index || index + len >= buf_len) { | |
529 return CFX_WideString(); | |
530 } | |
531 return CFX_WideString(buf + index + 1, len); | |
532 } | |
533 if (m_pBaseMap) { | |
534 return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode); | |
535 } | |
536 return CFX_WideString(); | |
537 } | |
538 FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) | |
539 { | |
540 FX_POSITION pos = m_Map.GetStartPosition(); | |
541 while (pos) { | |
542 FX_DWORD key, value; | |
543 m_Map.GetNextAssoc(pos, key, value); | |
544 if ((FX_WCHAR)value == unicode) { | |
545 return key; | |
546 } | |
547 } | |
548 return 0; | |
549 } | |
550 static FX_DWORD _StringToCode(FX_BSTR str) | |
551 { | |
552 FX_LPCSTR buf = str.GetCStr(); | |
553 int len = str.GetLength(); | |
554 if (len == 0) { | |
555 return 0; | |
556 } | |
557 int result = 0; | |
558 if (buf[0] == '<') { | |
559 for (int i = 1; i < len; i ++) { | |
560 int digit; | |
561 if (buf[i] >= '0' && buf[i] <= '9') { | |
562 digit = buf[i] - '0'; | |
563 } else if (buf[i] >= 'a' && buf[i] <= 'f') { | |
564 digit = buf[i] - 'a' + 10; | |
565 } else if (buf[i] >= 'A' && buf[i] <= 'F') { | |
566 digit = buf[i] - 'A' + 10; | |
567 } else { | |
568 break; | |
569 } | |
570 result = result * 16 + digit; | |
571 } | |
572 return result; | |
573 } else { | |
574 for (int i = 0; i < len; i ++) { | |
575 if (buf[i] < '0' || buf[i] > '9') { | |
576 break; | |
577 } | |
578 result = result * 10 + buf[i] - '0'; | |
579 } | |
580 } | |
581 return result; | |
582 } | |
583 static CFX_WideString _StringDataAdd(CFX_WideString str) | |
584 { | |
585 CFX_WideString ret; | |
586 int len = str.GetLength(); | |
587 FX_WCHAR value = 1; | |
588 for (int i = len - 1; i >= 0 ; --i) { | |
589 FX_WCHAR ch = str[i] + value; | |
590 if (ch < str[i]) { | |
591 ret.Insert(0, 0); | |
592 } else { | |
593 ret.Insert(0, ch); | |
594 value = 0; | |
595 } | |
596 } | |
597 if (value) { | |
598 ret.Insert(0, value); | |
599 } | |
600 return ret; | |
601 } | |
602 static CFX_WideString _StringToWideString(FX_BSTR str) | |
603 { | |
604 FX_LPCSTR buf = str.GetCStr(); | |
605 int len = str.GetLength(); | |
606 if (len == 0) { | |
607 return CFX_WideString(); | |
608 } | |
609 CFX_WideString result; | |
610 if (buf[0] == '<') { | |
611 int byte_pos = 0; | |
612 FX_WCHAR ch = 0; | |
613 for (int i = 1; i < len; i ++) { | |
614 int digit; | |
615 if (buf[i] >= '0' && buf[i] <= '9') { | |
616 digit = buf[i] - '0'; | |
617 } else if (buf[i] >= 'a' && buf[i] <= 'f') { | |
618 digit = buf[i] - 'a' + 10; | |
619 } else if (buf[i] >= 'A' && buf[i] <= 'F') { | |
620 digit = buf[i] - 'A' + 10; | |
621 } else { | |
622 break; | |
623 } | |
624 ch = ch * 16 + digit; | |
625 byte_pos ++; | |
626 if (byte_pos == 4) { | |
627 result += ch; | |
628 byte_pos = 0; | |
629 ch = 0; | |
630 } | |
631 } | |
632 return result; | |
633 } | |
634 if (buf[0] == '(') { | |
635 } | |
636 return result; | |
637 } | |
638 void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) | |
639 { | |
640 int CIDSet = 0; | |
641 CPDF_StreamAcc stream; | |
642 stream.LoadAllData(pStream, FALSE); | |
643 CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); | |
644 m_Map.EstimateSize(stream.GetSize() / 8, 1024); | |
645 while (1) { | |
646 CFX_ByteStringC word = parser.GetWord(); | |
647 if (word.IsEmpty()) { | |
648 break; | |
649 } | |
650 if (word == FX_BSTRC("beginbfchar")) { | |
651 while (1) { | |
652 word = parser.GetWord(); | |
653 if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) { | |
654 break; | |
655 } | |
656 FX_DWORD srccode = _StringToCode(word); | |
657 word = parser.GetWord(); | |
658 CFX_WideString destcode = _StringToWideString(word); | |
659 int len = destcode.GetLength(); | |
660 if (len == 0) { | |
661 continue; | |
662 } | |
663 if (len == 1) { | |
664 m_Map.SetAt(srccode, destcode.GetAt(0)); | |
665 } else { | |
666 m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 +
0xffff); | |
667 m_MultiCharBuf.AppendChar(destcode.GetLength()); | |
668 m_MultiCharBuf << destcode; | |
669 } | |
670 } | |
671 } else if (word == FX_BSTRC("beginbfrange")) { | |
672 while (1) { | |
673 CFX_ByteString low, high; | |
674 low = parser.GetWord(); | |
675 if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) { | |
676 break; | |
677 } | |
678 high = parser.GetWord(); | |
679 FX_DWORD lowcode = _StringToCode(low); | |
680 FX_DWORD highcode = (lowcode & 0xffffff00) | (_StringToCode(high
) & 0xff); | |
681 if (highcode == (FX_DWORD) - 1) { | |
682 break; | |
683 } | |
684 CFX_ByteString start = parser.GetWord(); | |
685 if (start == FX_BSTRC("[")) { | |
686 for (FX_DWORD code = lowcode; code <= highcode; code ++) { | |
687 CFX_ByteString dest = parser.GetWord(); | |
688 CFX_WideString destcode = _StringToWideString(dest); | |
689 int len = destcode.GetLength(); | |
690 if (len == 0) { | |
691 continue; | |
692 } | |
693 if (len == 1) { | |
694 m_Map.SetAt(code, destcode.GetAt(0)); | |
695 } else { | |
696 m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x100
00 + 0xffff); | |
697 m_MultiCharBuf.AppendChar(destcode.GetLength()); | |
698 m_MultiCharBuf << destcode; | |
699 } | |
700 } | |
701 parser.GetWord(); | |
702 } else { | |
703 CFX_WideString destcode = _StringToWideString(start); | |
704 int len = destcode.GetLength(); | |
705 FX_DWORD value = 0; | |
706 if (len == 1) { | |
707 value = _StringToCode(start); | |
708 for (FX_DWORD code = lowcode; code <= highcode; code ++)
{ | |
709 m_Map.SetAt(code, value++); | |
710 } | |
711 } else { | |
712 for (FX_DWORD code = lowcode; code <= highcode; code ++)
{ | |
713 CFX_WideString retcode; | |
714 if (code == lowcode) { | |
715 retcode = destcode; | |
716 } else { | |
717 retcode = _StringDataAdd(destcode); | |
718 } | |
719 m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x100
00 + 0xffff); | |
720 m_MultiCharBuf.AppendChar(retcode.GetLength()); | |
721 m_MultiCharBuf << retcode; | |
722 destcode = retcode; | |
723 } | |
724 } | |
725 } | |
726 } | |
727 } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) { | |
728 CIDSet = CIDSET_KOREA1; | |
729 } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) { | |
730 CIDSet = CIDSET_JAPAN1; | |
731 } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) { | |
732 CIDSet = CIDSET_CNS1; | |
733 } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) { | |
734 CIDSet = CIDSET_GB1; | |
735 } | |
736 } | |
737 if (CIDSet) { | |
738 m_pBaseMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m
_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE); | |
739 } else { | |
740 m_pBaseMap = NULL; | |
741 } | |
742 } | |
743 static FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) | |
744 { | |
745 if (value == FX_BSTRC("WinAnsiEncoding")) { | |
746 basemap = PDFFONT_ENCODING_WINANSI; | |
747 } else if (value == FX_BSTRC("MacRomanEncoding")) { | |
748 basemap = PDFFONT_ENCODING_MACROMAN; | |
749 } else if (value == FX_BSTRC("MacExpertEncoding")) { | |
750 basemap = PDFFONT_ENCODING_MACEXPERT; | |
751 } else if (value == FX_BSTRC("PDFDocEncoding")) { | |
752 basemap = PDFFONT_ENCODING_PDFDOC; | |
753 } else { | |
754 return FALSE; | |
755 } | |
756 return TRUE; | |
757 } | |
758 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, int& iBaseEncoding, CFX_
ByteString*& pCharNames, | |
759 FX_BOOL bEmbedded, FX_BOOL bTrueType) | |
760 { | |
761 if (pEncoding == NULL) { | |
762 if (m_BaseFont == FX_BSTRC("Symbol")) { | |
763 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL : PDFFONT_ENC
ODING_ADOBE_SYMBOL; | |
764 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { | |
765 iBaseEncoding = PDFFONT_ENCODING_WINANSI; | |
766 } | |
767 return; | |
768 } | |
769 if (pEncoding->GetType() == PDFOBJ_NAME) { | |
770 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || iBaseEncoding == P
DFFONT_ENCODING_ZAPFDINGBATS) { | |
771 return; | |
772 } | |
773 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) { | |
774 if (!bTrueType) { | |
775 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; | |
776 } | |
777 return; | |
778 } | |
779 CFX_ByteString bsEncoding = pEncoding->GetString(); | |
780 if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) { | |
781 bsEncoding = FX_BSTRC("WinAnsiEncoding"); | |
782 } | |
783 GetPredefinedEncoding(iBaseEncoding, bsEncoding); | |
784 return; | |
785 } | |
786 if (pEncoding->GetType() != PDFOBJ_DICTIONARY) { | |
787 return; | |
788 } | |
789 CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding; | |
790 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && iBaseEncoding != PDFFO
NT_ENCODING_ZAPFDINGBATS) { | |
791 CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding")); | |
792 if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType)
{ | |
793 bsEncoding = FX_BSTRC("WinAnsiEncoding"); | |
794 } | |
795 GetPredefinedEncoding(iBaseEncoding, bsEncoding); | |
796 } | |
797 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN)
{ | |
798 iBaseEncoding = PDFFONT_ENCODING_STANDARD; | |
799 } | |
800 CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences")); | |
801 if (pDiffs == NULL) { | |
802 return; | |
803 } | |
804 FX_NEW_VECTOR(pCharNames, CFX_ByteString, 256); | |
805 FX_DWORD cur_code = 0; | |
806 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i ++) { | |
807 CPDF_Object* pElement = pDiffs->GetElementValue(i); | |
808 if (pElement == NULL) { | |
809 continue; | |
810 } | |
811 if (pElement->GetType() == PDFOBJ_NAME) { | |
812 if (cur_code < 256) { | |
813 pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString(); | |
814 } | |
815 cur_code ++; | |
816 } else { | |
817 cur_code = pElement->GetInteger(); | |
818 } | |
819 } | |
820 } | |
821 FX_BOOL CPDF_Font::IsStandardFont() const | |
822 { | |
823 if (m_FontType != PDFFONT_TYPE1) { | |
824 return FALSE; | |
825 } | |
826 if (m_pFontFile != NULL) { | |
827 return FALSE; | |
828 } | |
829 if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) { | |
830 return FALSE; | |
831 } | |
832 return TRUE; | |
833 } | |
834 extern FX_LPCSTR PDF_CharNameFromPredefinedCharSet(int encoding, FX_BYTE charcod
e); | |
835 CPDF_SimpleFont::CPDF_SimpleFont() | |
836 { | |
837 FXSYS_memset8(m_CharBBox, 0xff, sizeof m_CharBBox); | |
838 FXSYS_memset8(m_CharWidth, 0xff, sizeof m_CharWidth); | |
839 FXSYS_memset8(m_GlyphIndex, 0xff, sizeof m_GlyphIndex); | |
840 FXSYS_memset8(m_ExtGID, 0xff, sizeof m_ExtGID); | |
841 m_pCharNames = NULL; | |
842 m_BaseEncoding = PDFFONT_ENCODING_BUILTIN; | |
843 } | |
844 CPDF_SimpleFont::~CPDF_SimpleFont() | |
845 { | |
846 if (m_pCharNames) { | |
847 FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256); | |
848 } | |
849 } | |
850 int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph) | |
851 { | |
852 if (pVertGlyph) { | |
853 *pVertGlyph = FALSE; | |
854 } | |
855 if (charcode > 0xff) { | |
856 return -1; | |
857 } | |
858 int index = m_GlyphIndex[(FX_BYTE)charcode]; | |
859 if (index == 0xffff) { | |
860 return -1; | |
861 } | |
862 return index; | |
863 } | |
864 void CPDF_SimpleFont::LoadCharMetrics(int charcode) | |
865 { | |
866 if (m_Font.m_Face == NULL) { | |
867 return; | |
868 } | |
869 if (charcode < 0 || charcode > 0xff) { | |
870 return; | |
871 } | |
872 int glyph_index = m_GlyphIndex[charcode]; | |
873 if (glyph_index == 0xffff) { | |
874 if (m_pFontFile == NULL && charcode != 32) { | |
875 LoadCharMetrics(32); | |
876 m_CharBBox[charcode] = m_CharBBox[32]; | |
877 if (m_bUseFontWidth) { | |
878 m_CharWidth[charcode] = m_CharWidth[32]; | |
879 } | |
880 } | |
881 return; | |
882 } | |
883 int err = FXFT_Load_Glyph(m_Font.m_Face, glyph_index, FXFT_LOAD_NO_SCALE | F
XFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | |
884 if (err) { | |
885 return; | |
886 } | |
887 m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face
), m_Font.m_Face); | |
888 m_CharBBox[charcode].Right = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Fac
e) + FXFT_Get_Glyph_Width(m_Font.m_Face), m_Font.m_Face); | |
889 m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face)
, m_Font.m_Face); | |
890 m_CharBBox[charcode].Bottom = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Fa
ce) - FXFT_Get_Glyph_Height(m_Font.m_Face), m_Font.m_Face); | |
891 if (m_bUseFontWidth) { | |
892 int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.
m_Face); | |
893 if (m_CharWidth[charcode] == 0xffff) { | |
894 m_CharWidth[charcode] = TT_Width; | |
895 } else if (TT_Width && !IsEmbedded()) { | |
896 m_CharBBox[charcode].Right = m_CharBBox[charcode].Right * m_CharWidt
h[charcode] / TT_Width; | |
897 m_CharBBox[charcode].Left = m_CharBBox[charcode].Left * m_CharWidth[
charcode] / TT_Width; | |
898 } | |
899 } | |
900 } | |
901 int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) | |
902 { | |
903 if (charcode > 0xff) { | |
904 charcode = 0; | |
905 } | |
906 if (m_CharWidth[charcode] == 0xffff) { | |
907 LoadCharMetrics(charcode); | |
908 if (m_CharWidth[charcode] == 0xffff) { | |
909 m_CharWidth[charcode] = 0; | |
910 } | |
911 } | |
912 return (FX_INT16)m_CharWidth[charcode]; | |
913 } | |
914 void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) | |
915 { | |
916 if (charcode > 0xff) { | |
917 charcode = 0; | |
918 } | |
919 if (m_CharBBox[charcode].Left == (FX_SHORT)0xffff) { | |
920 LoadCharMetrics(charcode); | |
921 } | |
922 rect.left = m_CharBBox[charcode].Left; | |
923 rect.right = m_CharBBox[charcode].Right; | |
924 rect.bottom = m_CharBBox[charcode].Bottom; | |
925 rect.top = m_CharBBox[charcode].Top; | |
926 } | |
927 FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames,
int charcode) | |
928 { | |
929 ASSERT(charcode >= 0 && charcode < 256); | |
930 if (charcode < 0 || charcode >= 256) { | |
931 return NULL; | |
932 } | |
933 FX_LPCSTR name = NULL; | |
934 if (pCharNames) { | |
935 name = pCharNames[charcode]; | |
936 } | |
937 if ((name == NULL || name[0] == 0) && iBaseEncoding) { | |
938 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); | |
939 } | |
940 if (name == NULL || name[0] == 0) { | |
941 return NULL; | |
942 } | |
943 return name; | |
944 } | |
945 FX_BOOL CPDF_SimpleFont::LoadCommon() | |
946 { | |
947 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor")
); | |
948 if (pFontDesc) { | |
949 LoadFontDescriptor(pFontDesc); | |
950 } | |
951 CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths")); | |
952 int width_start = 0, width_end = -1; | |
953 m_bUseFontWidth = TRUE; | |
954 if (pWidthArray) { | |
955 m_bUseFontWidth = FALSE; | |
956 if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) { | |
957 int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth")); | |
958 for (int i = 0; i < 256; i ++) { | |
959 m_CharWidth[i] = MissingWidth; | |
960 } | |
961 } | |
962 width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0); | |
963 width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0); | |
964 if (width_start >= 0 && width_start <= 255) { | |
965 if (width_end <= 0 || width_end >= width_start + (int)pWidthArray->G
etCount()) { | |
966 width_end = width_start + pWidthArray->GetCount() - 1; | |
967 } | |
968 if (width_end > 255) { | |
969 width_end = 255; | |
970 } | |
971 for (int i = width_start; i <= width_end; i ++) { | |
972 m_CharWidth[i] = pWidthArray->GetInteger(i - width_start); | |
973 } | |
974 } | |
975 } | |
976 if (m_pFontFile == NULL) { | |
977 LoadSubstFont(); | |
978 } else { | |
979 if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { | |
980 m_BaseFont = m_BaseFont.Mid(8); | |
981 } | |
982 } | |
983 if (!(m_Flags & PDFFONT_SYMBOLIC)) { | |
984 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; | |
985 } | |
986 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); | |
987 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL
, m_Font.IsTTFont()); | |
988 LoadGlyphMap(); | |
989 if (m_pCharNames) { | |
990 FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256); | |
991 m_pCharNames = NULL; | |
992 } | |
993 if (m_Font.m_Face == NULL) { | |
994 return TRUE; | |
995 } | |
996 if (m_Flags & PDFFONT_ALLCAP) { | |
997 unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd}; | |
998 for (size_t range = 0; range < sizeof lowercases / 2; range ++) { | |
999 for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1];
i ++) { | |
1000 if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) { | |
1001 continue; | |
1002 } | |
1003 m_GlyphIndex[i] = m_GlyphIndex[i - 32]; | |
1004 if (m_CharWidth[i - 32]) { | |
1005 m_CharWidth[i] = m_CharWidth[i - 32]; | |
1006 m_CharBBox[i] = m_CharBBox[i - 32]; | |
1007 } | |
1008 } | |
1009 } | |
1010 } | |
1011 CheckFontMetrics(); | |
1012 return TRUE; | |
1013 } | |
1014 void CPDF_SimpleFont::LoadSubstFont() | |
1015 { | |
1016 if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { | |
1017 int width = 0, i; | |
1018 for (i = 0; i < 256; i ++) { | |
1019 if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { | |
1020 continue; | |
1021 } | |
1022 if (width == 0) { | |
1023 width = m_CharWidth[i]; | |
1024 } else if (width != m_CharWidth[i]) { | |
1025 break; | |
1026 } | |
1027 } | |
1028 if (i == 256 && width) { | |
1029 m_Flags |= PDFFONT_FIXEDPITCH; | |
1030 } | |
1031 } | |
1032 int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140); | |
1033 m_Font.LoadSubst(m_BaseFont, m_FontType == PDFFONT_TRUETYPE, m_Flags, weight
, m_ItalicAngle, 0); | |
1034 if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) { | |
1035 } | |
1036 } | |
1037 FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const | |
1038 { | |
1039 return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && m_BaseEncoding != PDFFO
NT_ENCODING_ADOBE_SYMBOL && | |
1040 m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS; | |
1041 } | |
1042 CPDF_Type1Font::CPDF_Type1Font() | |
1043 { | |
1044 m_Base14Font = -1; | |
1045 } | |
1046 FX_BOOL CPDF_Type1Font::_Load() | |
1047 { | |
1048 m_Base14Font = _PDF_GetStandardFontName(m_BaseFont); | |
1049 if (m_Base14Font >= 0) { | |
1050 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescript
or")); | |
1051 if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) { | |
1052 m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags")); | |
1053 } else { | |
1054 m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLI
C; | |
1055 } | |
1056 if (m_Base14Font < 4) | |
1057 for (int i = 0; i < 256; i ++) { | |
1058 m_CharWidth[i] = 600; | |
1059 } | |
1060 if (m_Base14Font == 12) { | |
1061 m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; | |
1062 } else if (m_Base14Font == 13) { | |
1063 m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; | |
1064 } else if (m_Flags & PDFFONT_NONSYMBOLIC) { | |
1065 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; | |
1066 } | |
1067 } | |
1068 return LoadCommon(); | |
1069 } | |
1070 static FX_BOOL FT_UseType1Charmap(FXFT_Face face) | |
1071 { | |
1072 if (FXFT_Get_Face_CharmapCount(face) == 0) { | |
1073 return FALSE; | |
1074 } | |
1075 if (FXFT_Get_Face_CharmapCount(face) == 1 && | |
1076 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_E
NCODING_UNICODE) { | |
1077 return FALSE; | |
1078 } | |
1079 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCOD
ING_UNICODE) { | |
1080 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); | |
1081 } else { | |
1082 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); | |
1083 } | |
1084 return TRUE; | |
1085 } | 1090 } |
1086 extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode); | 1091 extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode); |
1087 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1092 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1088 #include "../../fxge/apple/apple_int.h" | 1093 #include "../../fxge/apple/apple_int.h" |
1089 #endif | 1094 #endif |
1090 int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) | 1095 int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) { |
1091 { | 1096 if (charcode > 0xff) { |
1092 if (charcode > 0xff) { | 1097 return -1; |
1093 return -1; | 1098 } |
1094 } | 1099 int index = m_ExtGID[(FX_BYTE)charcode]; |
1095 int index = m_ExtGID[(FX_BYTE)charcode]; | 1100 if (index == 0xffff) { |
1096 if (index == 0xffff) { | 1101 return -1; |
1097 return -1; | 1102 } |
1098 } | 1103 return index; |
1099 return index; | 1104 } |
1100 } | 1105 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1101 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
1102 struct _GlyphNameMap { | 1106 struct _GlyphNameMap { |
1103 FX_LPCSTR m_pStrAdobe; | 1107 FX_LPCSTR m_pStrAdobe; |
1104 FX_LPCSTR m_pStrUnicode; | 1108 FX_LPCSTR m_pStrUnicode; |
1105 }; | 1109 }; |
1106 static const _GlyphNameMap g_GlyphNameSubsts[] = { | 1110 static const _GlyphNameMap g_GlyphNameSubsts[] = { { "ff", "uniFB00" }, |
1107 {"ff", "uniFB00"}, | 1111 { "fi", "uniFB01" }, |
1108 {"fi", "uniFB01"}, | 1112 { "fl", "uniFB02" }, |
1109 {"fl", "uniFB02"}, | 1113 { "ffi", "uniFB03" }, |
1110 {"ffi", "uniFB03"}, | 1114 { "ffl", "uniFB04" } }; |
1111 {"ffl", "uniFB04"} | |
1112 }; | |
1113 extern "C" { | 1115 extern "C" { |
1114 static int compareString(const void* key, const void* element) | 1116 static int compareString(const void* key, const void* element) { |
1115 { | 1117 return FXSYS_stricmp((FX_LPCSTR)key, ((_GlyphNameMap*)element)->m_pStrAdobe); |
1116 return FXSYS_stricmp((FX_LPCSTR)key, ((_GlyphNameMap*)element)->m_pStrAd
obe); | 1118 } |
1117 } | 1119 } |
1118 } | 1120 static FX_LPCSTR _GlyphNameRemap(FX_LPCSTR pStrAdobe) { |
1119 static FX_LPCSTR _GlyphNameRemap(FX_LPCSTR pStrAdobe) | 1121 _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch( |
1120 { | 1122 pStrAdobe, |
1121 _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(pStrAdobe, g_GlyphNameS
ubsts, | 1123 g_GlyphNameSubsts, |
1122 sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), siz
eof(_GlyphNameMap), | 1124 sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), |
1123 compareString); | 1125 sizeof(_GlyphNameMap), |
1124 if (found) { | 1126 compareString); |
1125 return found->m_pStrUnicode; | 1127 if (found) { |
1126 } | 1128 return found->m_pStrUnicode; |
1127 return NULL; | 1129 } |
| 1130 return NULL; |
1128 } | 1131 } |
1129 #endif | 1132 #endif |
1130 void CPDF_Type1Font::LoadGlyphMap() | 1133 void CPDF_Type1Font::LoadGlyphMap() { |
1131 { | 1134 if (m_Font.m_Face == NULL) { |
1132 if (m_Font.m_Face == NULL) { | 1135 return; |
1133 return; | 1136 } |
1134 } | 1137 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1135 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1138 FX_BOOL bCoreText = TRUE; |
1136 FX_BOOL bCoreText = TRUE; | 1139 CQuartz2D& quartz2d = |
1137 CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformD
ata())->_quartz2d; | 1140 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; |
1138 if (!m_Font.m_pPlatformFont) { | 1141 if (!m_Font.m_pPlatformFont) { |
1139 if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { | 1142 if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { |
1140 bCoreText = FALSE; | 1143 bCoreText = FALSE; |
1141 } | 1144 } |
1142 m_Font.m_pPlatformFont = quartz2d.CreateFont(m_Font.m_pFontData, m_Font.
m_dwSize); | 1145 m_Font.m_pPlatformFont = |
1143 if (NULL == m_Font.m_pPlatformFont) { | 1146 quartz2d.CreateFont(m_Font.m_pFontData, m_Font.m_dwSize); |
1144 bCoreText = FALSE; | 1147 if (NULL == m_Font.m_pPlatformFont) { |
1145 } | 1148 bCoreText = FALSE; |
1146 } | 1149 } |
| 1150 } |
1147 #endif | 1151 #endif |
1148 if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { | 1152 if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { |
1149 if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { | 1153 if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { |
1150 FX_BOOL bGotOne = FALSE; | 1154 FX_BOOL bGotOne = FALSE; |
1151 for (int charcode = 0; charcode < 256; charcode ++) { | 1155 for (int charcode = 0; charcode < 256; charcode++) { |
1152 const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; | 1156 const FX_BYTE prefix[4] = { 0x00, 0xf0, 0xf1, 0xf2 }; |
1153 for (int j = 0; j < 4; j ++) { | 1157 for (int j = 0; j < 4; j++) { |
1154 FX_WORD unicode = prefix[j] * 256 + charcode; | 1158 FX_WORD unicode = prefix[j] * 256 + charcode; |
1155 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face,
unicode); | 1159 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode); |
1156 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1160 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1157 FX_CHAR name_glyph[256]; | 1161 FX_CHAR name_glyph[256]; |
1158 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], n
ame_glyph, 256); | 1162 FXFT_Get_Glyph_Name( |
1159 name_glyph[255] = 0; | 1163 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
1160 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAll
ocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); | 1164 name_glyph[255] = 0; |
1161 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)
m_Font.m_pPlatformFont, name_ct); | 1165 CFStringRef name_ct = |
1162 if (name_ct) { | 1166 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
1163 CFRelease(name_ct); | 1167 name_glyph, |
1164 } | 1168 kCFStringEncodingASCII, |
| 1169 kCFAllocatorNull); |
| 1170 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1171 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1172 if (name_ct) { |
| 1173 CFRelease(name_ct); |
| 1174 } |
1165 #endif | 1175 #endif |
1166 if (m_GlyphIndex[charcode]) { | 1176 if (m_GlyphIndex[charcode]) { |
1167 bGotOne = TRUE; | 1177 bGotOne = TRUE; |
1168 break; | 1178 break; |
1169 } | 1179 } |
1170 } | 1180 } |
1171 } | 1181 } |
1172 if (bGotOne) { | 1182 if (bGotOne) { |
1173 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1183 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1174 if (!bCoreText) { | |
1175 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); | |
1176 } | |
1177 #endif | |
1178 return; | |
1179 } | |
1180 } | |
1181 FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE); | |
1182 if (m_BaseEncoding == 0) { | |
1183 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; | |
1184 } | |
1185 for (int charcode = 0; charcode < 256; charcode ++) { | |
1186 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, char
code); | |
1187 if (name == NULL) { | |
1188 continue; | |
1189 } | |
1190 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | |
1191 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encodi
ng.m_Unicodes[charcode]); | |
1192 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
1193 FX_CHAR name_glyph[256]; | |
1194 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyp
h, 256); | |
1195 name_glyph[255] = 0; | |
1196 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDe
fault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); | |
1197 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m
_pPlatformFont, name_ct); | |
1198 if (name_ct) { | |
1199 CFRelease(name_ct); | |
1200 } | |
1201 #endif | |
1202 if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") ==
0) { | |
1203 m_Encoding.m_Unicodes[charcode] = 0x20; | |
1204 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20
); | |
1205 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
1206 FX_CHAR name_glyph[256]; | |
1207 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_
glyph, 256); | |
1208 name_glyph[255] = 0; | |
1209 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocat
orDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); | |
1210 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Fo
nt.m_pPlatformFont, name_ct); | |
1211 if (name_ct) { | |
1212 CFRelease(name_ct); | |
1213 } | |
1214 #endif | |
1215 } | |
1216 } | |
1217 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
1218 if (!bCoreText) { | 1184 if (!bCoreText) { |
1219 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); | 1185 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); |
1220 } | 1186 } |
1221 #endif | 1187 #endif |
1222 return; | 1188 return; |
1223 } | 1189 } |
1224 FT_UseType1Charmap(m_Font.m_Face); | 1190 } |
1225 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1191 FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE); |
1226 if (bCoreText) { | 1192 if (m_BaseEncoding == 0) { |
1227 if (m_Flags & PDFFONT_SYMBOLIC) { | 1193 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; |
1228 for (int charcode = 0; charcode < 256; charcode ++) { | 1194 } |
1229 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames,
charcode); | 1195 for (int charcode = 0; charcode < 256; charcode++) { |
1230 if (name) { | 1196 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
1231 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(n
ame); | 1197 if (name == NULL) { |
1232 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face,
(char*)name); | 1198 continue; |
1233 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAll
ocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); | 1199 } |
1234 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)
m_Font.m_pPlatformFont, name_ct); | 1200 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
1235 if (name_ct) { | 1201 m_GlyphIndex[charcode] = |
1236 CFRelease(name_ct); | 1202 FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]); |
1237 } | 1203 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1238 } else { | 1204 FX_CHAR name_glyph[256]; |
1239 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face,
charcode); | 1205 FXFT_Get_Glyph_Name( |
1240 FX_WCHAR unicode = 0; | 1206 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
1241 if (m_GlyphIndex[charcode]) { | 1207 name_glyph[255] = 0; |
1242 unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDA
RD, charcode); | 1208 CFStringRef name_ct = |
1243 } | 1209 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
1244 FX_CHAR name_glyph[256]; | 1210 name_glyph, |
1245 FXSYS_memset32(name_glyph, 0, sizeof(name_glyph)); | 1211 kCFStringEncodingASCII, |
1246 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], n
ame_glyph, 256); | 1212 kCFAllocatorNull); |
1247 name_glyph[255] = 0; | 1213 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
1248 if (unicode == 0 && name_glyph[0] != 0) { | 1214 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
1249 unicode = PDF_UnicodeFromAdobeName(name_glyph); | 1215 if (name_ct) { |
1250 } | 1216 CFRelease(name_ct); |
1251 m_Encoding.m_Unicodes[charcode] = unicode; | 1217 } |
1252 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAll
ocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); | 1218 #endif |
1253 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)
m_Font.m_pPlatformFont, name_ct); | 1219 if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) { |
1254 if (name_ct) { | 1220 m_Encoding.m_Unicodes[charcode] = 0x20; |
1255 CFRelease(name_ct); | 1221 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20); |
1256 } | 1222 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1257 } | 1223 FX_CHAR name_glyph[256]; |
| 1224 FXFT_Get_Glyph_Name( |
| 1225 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
| 1226 name_glyph[255] = 0; |
| 1227 CFStringRef name_ct = |
| 1228 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
| 1229 name_glyph, |
| 1230 kCFStringEncodingASCII, |
| 1231 kCFAllocatorNull); |
| 1232 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1233 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1234 if (name_ct) { |
| 1235 CFRelease(name_ct); |
| 1236 } |
| 1237 #endif |
| 1238 } |
| 1239 } |
| 1240 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 1241 if (!bCoreText) { |
| 1242 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); |
| 1243 } |
| 1244 #endif |
| 1245 return; |
| 1246 } |
| 1247 FT_UseType1Charmap(m_Font.m_Face); |
| 1248 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 1249 if (bCoreText) { |
| 1250 if (m_Flags & PDFFONT_SYMBOLIC) { |
| 1251 for (int charcode = 0; charcode < 256; charcode++) { |
| 1252 FX_LPCSTR name = |
| 1253 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
| 1254 if (name) { |
| 1255 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
| 1256 m_GlyphIndex[charcode] = |
| 1257 FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); |
| 1258 CFStringRef name_ct = |
| 1259 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
| 1260 name, |
| 1261 kCFStringEncodingASCII, |
| 1262 kCFAllocatorNull); |
| 1263 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1264 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1265 if (name_ct) { |
| 1266 CFRelease(name_ct); |
| 1267 } |
| 1268 } else { |
| 1269 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); |
| 1270 FX_WCHAR unicode = 0; |
| 1271 if (m_GlyphIndex[charcode]) { |
| 1272 unicode = |
| 1273 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); |
| 1274 } |
| 1275 FX_CHAR name_glyph[256]; |
| 1276 FXSYS_memset32(name_glyph, 0, sizeof(name_glyph)); |
| 1277 FXFT_Get_Glyph_Name( |
| 1278 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
| 1279 name_glyph[255] = 0; |
| 1280 if (unicode == 0 && name_glyph[0] != 0) { |
| 1281 unicode = PDF_UnicodeFromAdobeName(name_glyph); |
| 1282 } |
| 1283 m_Encoding.m_Unicodes[charcode] = unicode; |
| 1284 CFStringRef name_ct = |
| 1285 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
| 1286 name_glyph, |
| 1287 kCFStringEncodingASCII, |
| 1288 kCFAllocatorNull); |
| 1289 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1290 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1291 if (name_ct) { |
| 1292 CFRelease(name_ct); |
| 1293 } |
| 1294 } |
| 1295 } |
| 1296 return; |
| 1297 } |
| 1298 FX_BOOL bUnicode = FALSE; |
| 1299 if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) { |
| 1300 bUnicode = TRUE; |
| 1301 } |
| 1302 for (int charcode = 0; charcode < 256; charcode++) { |
| 1303 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
| 1304 if (name == NULL) { |
| 1305 continue; |
| 1306 } |
| 1307 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
| 1308 FX_LPCSTR pStrUnicode = _GlyphNameRemap(name); |
| 1309 if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)) { |
| 1310 name = pStrUnicode; |
| 1311 } |
| 1312 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); |
| 1313 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( |
| 1314 kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); |
| 1315 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1316 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1317 if (name_ct) { |
| 1318 CFRelease(name_ct); |
| 1319 } |
| 1320 if (m_GlyphIndex[charcode] == 0) { |
| 1321 if (FXSYS_strcmp(name, ".notdef") != 0 && |
| 1322 FXSYS_strcmp(name, "space") != 0) { |
| 1323 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( |
| 1324 m_Font.m_Face, |
| 1325 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); |
| 1326 FX_CHAR name_glyph[256]; |
| 1327 FXFT_Get_Glyph_Name( |
| 1328 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
| 1329 name_glyph[255] = 0; |
| 1330 CFStringRef name_ct = |
| 1331 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
| 1332 name_glyph, |
| 1333 kCFStringEncodingASCII, |
| 1334 kCFAllocatorNull); |
| 1335 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1336 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1337 if (name_ct) { |
| 1338 CFRelease(name_ct); |
| 1339 } |
| 1340 } else { |
| 1341 m_Encoding.m_Unicodes[charcode] = 0x20; |
| 1342 m_GlyphIndex[charcode] = |
| 1343 bUnicode ? FXFT_Get_Char_Index(m_Font.m_Face, 0x20) : 0xffff; |
| 1344 FX_CHAR name_glyph[256]; |
| 1345 FXFT_Get_Glyph_Name( |
| 1346 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
| 1347 name_glyph[255] = 0; |
| 1348 CFStringRef name_ct = |
| 1349 CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, |
| 1350 name_glyph, |
| 1351 kCFStringEncodingASCII, |
| 1352 kCFAllocatorNull); |
| 1353 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
| 1354 (CGFontRef)m_Font.m_pPlatformFont, name_ct); |
| 1355 if (name_ct) { |
| 1356 CFRelease(name_ct); |
| 1357 } |
| 1358 } |
| 1359 } |
| 1360 } |
| 1361 return; |
| 1362 } |
| 1363 #endif |
| 1364 if (m_Flags & PDFFONT_SYMBOLIC) { |
| 1365 for (int charcode = 0; charcode < 256; charcode++) { |
| 1366 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
| 1367 if (name) { |
| 1368 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
| 1369 m_GlyphIndex[charcode] = |
| 1370 FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); |
| 1371 } else { |
| 1372 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); |
| 1373 if (m_GlyphIndex[charcode]) { |
| 1374 FX_WCHAR unicode = |
| 1375 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); |
| 1376 if (unicode == 0) { |
| 1377 FX_CHAR name_glyph[256]; |
| 1378 FXSYS_memset32(name_glyph, 0, sizeof(name_glyph)); |
| 1379 FXFT_Get_Glyph_Name( |
| 1380 m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256); |
| 1381 name_glyph[255] = 0; |
| 1382 if (name_glyph[0] != 0) { |
| 1383 unicode = PDF_UnicodeFromAdobeName(name_glyph); |
1258 } | 1384 } |
1259 return; | 1385 } |
1260 } | 1386 m_Encoding.m_Unicodes[charcode] = unicode; |
1261 FX_BOOL bUnicode = FALSE; | 1387 } |
1262 if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) { | 1388 } |
1263 bUnicode = TRUE; | 1389 } |
1264 } | 1390 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
1265 for (int charcode = 0; charcode < 256; charcode ++) { | 1391 if (!bCoreText) { |
1266 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, char
code); | 1392 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); |
1267 if (name == NULL) { | 1393 } |
1268 continue; | 1394 #endif |
1269 } | 1395 return; |
1270 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | 1396 } |
1271 FX_LPCSTR pStrUnicode = _GlyphNameRemap(name); | 1397 FX_BOOL bUnicode = FALSE; |
1272 if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)na
me)) { | 1398 if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) { |
1273 name = pStrUnicode; | 1399 bUnicode = TRUE; |
1274 } | 1400 } |
1275 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)n
ame); | 1401 for (int charcode = 0; charcode < 256; charcode++) { |
1276 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDe
fault, name, kCFStringEncodingASCII, kCFAllocatorNull); | 1402 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
1277 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m
_pPlatformFont, name_ct); | 1403 if (name == NULL) { |
1278 if (name_ct) { | 1404 continue; |
1279 CFRelease(name_ct); | 1405 } |
| 1406 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
| 1407 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); |
| 1408 if (m_GlyphIndex[charcode] == 0) { |
| 1409 if (FXSYS_strcmp(name, ".notdef") != 0 && |
| 1410 FXSYS_strcmp(name, "space") != 0) { |
| 1411 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( |
| 1412 m_Font.m_Face, |
| 1413 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); |
| 1414 } else { |
| 1415 m_Encoding.m_Unicodes[charcode] = 0x20; |
| 1416 m_GlyphIndex[charcode] = 0xffff; |
| 1417 } |
| 1418 } |
| 1419 } |
| 1420 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 1421 if (!bCoreText) { |
| 1422 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); |
| 1423 } |
| 1424 #endif |
| 1425 } |
| 1426 CPDF_FontEncoding::CPDF_FontEncoding() { |
| 1427 FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes)); |
| 1428 } |
| 1429 int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const { |
| 1430 for (int i = 0; i < 256; i++) |
| 1431 if (m_Unicodes[i] == unicode) { |
| 1432 return i; |
| 1433 } |
| 1434 return -1; |
| 1435 } |
| 1436 CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) { |
| 1437 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); |
| 1438 if (!pSrc) { |
| 1439 FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes)); |
| 1440 } else |
| 1441 for (int i = 0; i < 256; i++) { |
| 1442 m_Unicodes[i] = pSrc[i]; |
| 1443 } |
| 1444 } |
| 1445 FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const { |
| 1446 return FXSYS_memcmp32(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == |
| 1447 0; |
| 1448 } |
| 1449 CPDF_Object* CPDF_FontEncoding::Realize() { |
| 1450 int predefined = 0; |
| 1451 for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; |
| 1452 cs++) { |
| 1453 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs); |
| 1454 FX_BOOL match = TRUE; |
| 1455 for (int i = 0; i < 256; ++i) { |
| 1456 if (m_Unicodes[i] != pSrc[i]) { |
| 1457 match = FALSE; |
| 1458 break; |
| 1459 } |
| 1460 } |
| 1461 if (match) { |
| 1462 predefined = cs; |
| 1463 break; |
| 1464 } |
| 1465 } |
| 1466 if (predefined) { |
| 1467 if (predefined == PDFFONT_ENCODING_WINANSI) { |
| 1468 return CPDF_Name::Create("WinAnsiEncoding"); |
| 1469 } |
| 1470 if (predefined == PDFFONT_ENCODING_MACROMAN) { |
| 1471 return CPDF_Name::Create("MacRomanEncoding"); |
| 1472 } |
| 1473 if (predefined == PDFFONT_ENCODING_MACEXPERT) { |
| 1474 return CPDF_Name::Create("MacExpertEncoding"); |
| 1475 } |
| 1476 return NULL; |
| 1477 } |
| 1478 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 1479 pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding")); |
| 1480 const FX_WORD* pStandard = |
| 1481 PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); |
| 1482 CPDF_Array* pDiff = CPDF_Array::Create(); |
| 1483 for (int i = 0; i < 256; i++) { |
| 1484 if (pStandard[i] == m_Unicodes[i]) { |
| 1485 continue; |
| 1486 } |
| 1487 pDiff->Add(CPDF_Number::Create(i)); |
| 1488 pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); |
| 1489 } |
| 1490 pDict->SetAt(FX_BSTRC("Differences"), pDiff); |
| 1491 return pDict; |
| 1492 } |
| 1493 CPDF_TrueTypeFont::CPDF_TrueTypeFont() { |
| 1494 } |
| 1495 FX_BOOL CPDF_TrueTypeFont::_Load() { |
| 1496 return LoadCommon(); |
| 1497 } |
| 1498 extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode); |
| 1499 void CPDF_TrueTypeFont::LoadGlyphMap() { |
| 1500 if (m_Font.m_Face == NULL) { |
| 1501 return; |
| 1502 } |
| 1503 int baseEncoding = m_BaseEncoding; |
| 1504 if (m_pFontFile && m_Font.m_Face->num_charmaps > 0 && |
| 1505 (baseEncoding == PDFFONT_ENCODING_MACROMAN || |
| 1506 baseEncoding == PDFFONT_ENCODING_WINANSI) && |
| 1507 (m_Flags & PDFFONT_SYMBOLIC)) { |
| 1508 FX_BOOL bSupportWin = FALSE; |
| 1509 FX_BOOL bSupportMac = FALSE; |
| 1510 for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) { |
| 1511 int platform_id = |
| 1512 FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]); |
| 1513 if (platform_id == 0 || platform_id == 3) { |
| 1514 bSupportWin = TRUE; |
| 1515 } else if (platform_id == 0 || platform_id == 1) { |
| 1516 bSupportMac = TRUE; |
| 1517 } |
| 1518 } |
| 1519 if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { |
| 1520 baseEncoding = |
| 1521 bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; |
| 1522 } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { |
| 1523 baseEncoding = |
| 1524 bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; |
| 1525 } |
| 1526 } |
| 1527 if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || |
| 1528 baseEncoding == PDFFONT_ENCODING_WINANSI) && |
| 1529 m_pCharNames == NULL) || |
| 1530 (m_Flags & PDFFONT_NONSYMBOLIC)) { |
| 1531 if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && |
| 1532 (!m_Font.m_Face->num_charmaps || !m_Font.m_Face->charmaps)) { |
| 1533 int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar")); |
| 1534 if (nStartChar < 0 || nStartChar > 255) |
| 1535 return; |
| 1536 |
| 1537 int charcode = 0; |
| 1538 for (; charcode < nStartChar; charcode++) { |
| 1539 m_GlyphIndex[charcode] = 0; |
| 1540 } |
| 1541 FX_WORD nGlyph = charcode - nStartChar + 3; |
| 1542 for (; charcode < 256; charcode++, nGlyph++) { |
| 1543 m_GlyphIndex[charcode] = nGlyph; |
| 1544 } |
| 1545 return; |
| 1546 } |
| 1547 FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1); |
| 1548 FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE; |
| 1549 if (!bMSUnicode) { |
| 1550 if (m_Flags & PDFFONT_NONSYMBOLIC) { |
| 1551 bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0); |
| 1552 bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0); |
| 1553 } else { |
| 1554 bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0); |
| 1555 bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0); |
| 1556 } |
| 1557 } |
| 1558 FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode")); |
| 1559 for (int charcode = 0; charcode < 256; charcode++) { |
| 1560 FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode); |
| 1561 if (name == NULL) { |
| 1562 m_GlyphIndex[charcode] = |
| 1563 m_pFontFile ? FXFT_Get_Char_Index(m_Font.m_Face, charcode) : -1; |
| 1564 continue; |
| 1565 } |
| 1566 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
| 1567 if (bMSSymbol) { |
| 1568 const FX_BYTE prefix[4] = { 0x00, 0xf0, 0xf1, 0xf2 }; |
| 1569 for (int j = 0; j < 4; j++) { |
| 1570 FX_WORD unicode = prefix[j] * 256 + charcode; |
| 1571 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode); |
| 1572 if (m_GlyphIndex[charcode]) { |
| 1573 break; |
| 1574 } |
| 1575 } |
| 1576 } else if (m_Encoding.m_Unicodes[charcode]) { |
| 1577 if (bMSUnicode) { |
| 1578 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( |
| 1579 m_Font.m_Face, m_Encoding.m_Unicodes[charcode]); |
| 1580 } else if (bMacRoman) { |
| 1581 FX_DWORD maccode = FT_CharCodeFromUnicode( |
| 1582 FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); |
| 1583 if (!maccode) { |
| 1584 m_GlyphIndex[charcode] = |
| 1585 FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); |
| 1586 } else { |
| 1587 m_GlyphIndex[charcode] = |
| 1588 FXFT_Get_Char_Index(m_Font.m_Face, maccode); |
| 1589 } |
| 1590 } |
| 1591 } |
| 1592 if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && |
| 1593 name != NULL) { |
| 1594 if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { |
| 1595 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 32); |
| 1596 } else { |
| 1597 m_GlyphIndex[charcode] = |
| 1598 FXFT_Get_Name_Index(m_Font.m_Face, (char*)name); |
| 1599 if (m_GlyphIndex[charcode] == 0) { |
| 1600 if (bToUnicode) { |
| 1601 CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); |
| 1602 if (!wsUnicode.IsEmpty()) { |
| 1603 m_GlyphIndex[charcode] = |
| 1604 FXFT_Get_Char_Index(m_Font.m_Face, wsUnicode[0]); |
| 1605 m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; |
| 1606 } |
1280 } | 1607 } |
1281 if (m_GlyphIndex[charcode] == 0) { | 1608 if (m_GlyphIndex[charcode] == 0) { |
1282 if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "sp
ace") != 0) { | 1609 m_GlyphIndex[charcode] = |
1283 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face,
bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); | 1610 FXFT_Get_Char_Index(m_Font.m_Face, charcode); |
1284 FX_CHAR name_glyph[256]; | |
1285 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], n
ame_glyph, 256); | |
1286 name_glyph[255] = 0; | |
1287 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAll
ocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); | |
1288 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)
m_Font.m_pPlatformFont, name_ct); | |
1289 if (name_ct) { | |
1290 CFRelease(name_ct); | |
1291 } | |
1292 } else { | |
1293 m_Encoding.m_Unicodes[charcode] = 0x20; | |
1294 m_GlyphIndex[charcode] = bUnicode ? FXFT_Get_Char_Index(m_Fo
nt.m_Face, 0x20) : 0xffff; | |
1295 FX_CHAR name_glyph[256]; | |
1296 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], n
ame_glyph, 256); | |
1297 name_glyph[255] = 0; | |
1298 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAll
ocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull); | |
1299 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)
m_Font.m_pPlatformFont, name_ct); | |
1300 if (name_ct) { | |
1301 CFRelease(name_ct); | |
1302 } | |
1303 } | |
1304 } | 1611 } |
1305 } | 1612 } |
1306 return; | 1613 } |
1307 } | 1614 } |
1308 #endif | 1615 } |
1309 if (m_Flags & PDFFONT_SYMBOLIC) { | 1616 return; |
1310 for (int charcode = 0; charcode < 256; charcode ++) { | 1617 } |
1311 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, char
code); | 1618 if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { |
1312 if (name) { | 1619 const FX_BYTE prefix[4] = { 0x00, 0xf0, 0xf1, 0xf2 }; |
1313 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name)
; | 1620 FX_BOOL bGotOne = FALSE; |
1314 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (cha
r*)name); | 1621 for (int charcode = 0; charcode < 256; charcode++) { |
1315 } else { | 1622 for (int j = 0; j < 4; j++) { |
1316 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, char
code); | 1623 FX_WORD unicode = prefix[j] * 256 + charcode; |
1317 if (m_GlyphIndex[charcode]) { | 1624 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode); |
1318 FX_WCHAR unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_S
TANDARD, charcode); | 1625 if (m_GlyphIndex[charcode]) { |
1319 if (unicode == 0) { | 1626 bGotOne = TRUE; |
1320 FX_CHAR name_glyph[256]; | 1627 break; |
1321 FXSYS_memset32(name_glyph, 0, sizeof(name_glyph)); | 1628 } |
1322 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode
], name_glyph, 256); | 1629 } |
1323 name_glyph[255] = 0; | 1630 } |
1324 if (name_glyph[0] != 0) { | 1631 if (bGotOne) { |
1325 unicode = PDF_UnicodeFromAdobeName(name_glyph); | 1632 if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { |
1326 } | 1633 for (int charcode = 0; charcode < 256; charcode++) { |
1327 } | 1634 FX_LPCSTR name = |
1328 m_Encoding.m_Unicodes[charcode] = unicode; | 1635 GetAdobeCharName(baseEncoding, m_pCharNames, charcode); |
1329 } | 1636 if (name == NULL) { |
1330 } | |
1331 } | |
1332 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
1333 if (!bCoreText) { | |
1334 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); | |
1335 } | |
1336 #endif | |
1337 return; | |
1338 } | |
1339 FX_BOOL bUnicode = FALSE; | |
1340 if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) { | |
1341 bUnicode = TRUE; | |
1342 } | |
1343 for (int charcode = 0; charcode < 256; charcode ++) { | |
1344 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode
); | |
1345 if (name == NULL) { | |
1346 continue; | 1637 continue; |
1347 } | 1638 } |
1348 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | 1639 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
1349 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)
; | 1640 } |
1350 if (m_GlyphIndex[charcode] == 0) { | 1641 } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) { |
1351 if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space"
) != 0) { | 1642 for (int charcode = 0; charcode < 256; charcode++) { |
1352 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUni
code ? m_Encoding.m_Unicodes[charcode] : charcode); | 1643 m_Encoding.m_Unicodes[charcode] = |
1353 } else { | 1644 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); |
1354 m_Encoding.m_Unicodes[charcode] = 0x20; | 1645 } |
1355 m_GlyphIndex[charcode] = 0xffff; | 1646 } |
1356 } | 1647 return; |
1357 } | 1648 } |
1358 } | 1649 } |
1359 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 1650 if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) { |
1360 if (!bCoreText) { | 1651 FX_BOOL bGotOne = FALSE; |
1361 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256); | 1652 for (int charcode = 0; charcode < 256; charcode++) { |
1362 } | 1653 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode); |
1363 #endif | 1654 m_Encoding.m_Unicodes[charcode] = |
1364 } | 1655 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); |
1365 CPDF_FontEncoding::CPDF_FontEncoding() | 1656 if (m_GlyphIndex[charcode]) { |
1366 { | 1657 bGotOne = TRUE; |
1367 FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes)); | 1658 } |
1368 } | 1659 } |
1369 int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const | 1660 if (m_pFontFile || bGotOne) { |
1370 { | 1661 return; |
1371 for (int i = 0; i < 256; i ++) | 1662 } |
1372 if (m_Unicodes[i] == unicode) { | 1663 } |
1373 return i; | 1664 if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) { |
1374 } | 1665 FX_BOOL bGotOne = FALSE; |
1375 return -1; | 1666 const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); |
1376 } | 1667 for (int charcode = 0; charcode < 256; charcode++) { |
1377 CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) | 1668 if (m_pFontFile == NULL) { |
1378 { | 1669 FX_LPCSTR name = GetAdobeCharName(0, m_pCharNames, charcode); |
1379 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); | 1670 if (name != NULL) { |
1380 if (!pSrc) { | 1671 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
1381 FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes)); | 1672 } else if (pUnicodes) { |
1382 } else | 1673 m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; |
1383 for (int i = 0; i < 256; i++) { | 1674 } |
1384 m_Unicodes[i] = pSrc[i]; | 1675 } else { |
1385 } | 1676 m_Encoding.m_Unicodes[charcode] = charcode; |
1386 } | 1677 } |
1387 FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const | 1678 m_GlyphIndex[charcode] = |
1388 { | 1679 FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]); |
1389 return FXSYS_memcmp32(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes))
== 0; | 1680 if (m_GlyphIndex[charcode]) { |
1390 } | 1681 bGotOne = TRUE; |
1391 CPDF_Object* CPDF_FontEncoding::Realize() | 1682 } |
1392 { | 1683 } |
1393 int predefined = 0; | 1684 if (bGotOne) { |
1394 for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS;
cs ++) { | 1685 return; |
1395 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs); | 1686 } |
1396 FX_BOOL match = TRUE; | 1687 } |
1397 for (int i = 0; i < 256; ++i) { | 1688 for (int charcode = 0; charcode < 256; charcode++) { |
1398 if (m_Unicodes[i] != pSrc[i]) { | 1689 m_GlyphIndex[charcode] = charcode; |
1399 match = FALSE; | 1690 } |
1400 break; | 1691 } |
1401 } | 1692 CPDF_Type3Font::CPDF_Type3Font() { |
1402 } | 1693 m_pPageResources = NULL; |
1403 if (match) { | 1694 FXSYS_memset32(m_CharWidthL, 0, sizeof m_CharWidthL); |
1404 predefined = cs; | 1695 } |
1405 break; | 1696 CPDF_Type3Font::~CPDF_Type3Font() { |
1406 } | 1697 FX_POSITION pos = m_CacheMap.GetStartPosition(); |
1407 } | 1698 while (pos) { |
1408 if (predefined) { | 1699 FX_LPVOID key, value; |
1409 if (predefined == PDFFONT_ENCODING_WINANSI) { | 1700 m_CacheMap.GetNextAssoc(pos, key, value); |
1410 return CPDF_Name::Create("WinAnsiEncoding"); | 1701 delete (CPDF_Type3Char*)value; |
1411 } | 1702 } |
1412 if (predefined == PDFFONT_ENCODING_MACROMAN) { | 1703 m_CacheMap.RemoveAll(); |
1413 return CPDF_Name::Create("MacRomanEncoding"); | 1704 pos = m_DeletedMap.GetStartPosition(); |
1414 } | 1705 while (pos) { |
1415 if (predefined == PDFFONT_ENCODING_MACEXPERT) { | 1706 FX_LPVOID key, value; |
1416 return CPDF_Name::Create("MacExpertEncoding"); | 1707 m_DeletedMap.GetNextAssoc(pos, key, value); |
1417 } | 1708 delete (CPDF_Type3Char*)key; |
1418 return NULL; | 1709 } |
1419 } | 1710 } |
1420 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | 1711 FX_BOOL CPDF_Type3Font::_Load() { |
1421 pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding")); | 1712 m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources")); |
1422 const FX_WORD* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING
_WINANSI); | 1713 CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix")); |
1423 CPDF_Array* pDiff = CPDF_Array::Create(); | 1714 FX_FLOAT xscale = 1.0f, yscale = 1.0f; |
1424 for (int i = 0; i < 256; i ++) { | 1715 if (pMatrix) { |
1425 if (pStandard[i] == m_Unicodes[i]) { | 1716 m_FontMatrix = pMatrix->GetMatrix(); |
1426 continue; | 1717 xscale = m_FontMatrix.a; |
1427 } | 1718 yscale = m_FontMatrix.d; |
1428 pDiff->Add(CPDF_Number::Create(i)); | 1719 } |
1429 pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); | 1720 CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox")); |
1430 } | 1721 if (pBBox) { |
1431 pDict->SetAt(FX_BSTRC("Differences"), pDiff); | 1722 m_FontBBox.left = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000); |
1432 return pDict; | 1723 m_FontBBox.bottom = |
1433 } | 1724 (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000); |
1434 CPDF_TrueTypeFont::CPDF_TrueTypeFont() | 1725 m_FontBBox.right = |
1435 { | 1726 (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000); |
1436 } | 1727 m_FontBBox.top = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000); |
1437 FX_BOOL CPDF_TrueTypeFont::_Load() | 1728 } |
1438 { | 1729 int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar")); |
1439 return LoadCommon(); | 1730 CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths")); |
1440 } | 1731 if (pWidthArray && (StartChar >= 0 && StartChar < 256)) { |
1441 extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode); | 1732 FX_DWORD count = pWidthArray->GetCount(); |
1442 void CPDF_TrueTypeFont::LoadGlyphMap() | 1733 if (count > 256) { |
1443 { | 1734 count = 256; |
1444 if (m_Font.m_Face == NULL) { | 1735 } |
1445 return; | 1736 if (StartChar + count > 256) { |
1446 } | 1737 count = 256 - StartChar; |
1447 int baseEncoding = m_BaseEncoding; | 1738 } |
1448 if (m_pFontFile && m_Font.m_Face->num_charmaps > 0 | 1739 for (FX_DWORD i = 0; i < count; i++) { |
1449 && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDF
FONT_ENCODING_WINANSI) | 1740 m_CharWidthL[StartChar + i] = |
1450 && (m_Flags & PDFFONT_SYMBOLIC)) { | 1741 FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000); |
1451 FX_BOOL bSupportWin = FALSE; | 1742 } |
1452 FX_BOOL bSupportMac = FALSE; | 1743 } |
1453 for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) { | 1744 m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs")); |
1454 int platform_id = FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps
(m_Font.m_Face)[i]); | 1745 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); |
1455 if (platform_id == 0 || platform_id == 3) { | 1746 if (pEncoding) { |
1456 bSupportWin = TRUE; | 1747 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE); |
1457 } else if (platform_id == 0 || platform_id == 1) { | 1748 if (m_pCharNames) { |
1458 bSupportMac = TRUE; | 1749 for (int i = 0; i < 256; i++) { |
1459 } | 1750 m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]); |
1460 } | 1751 if (m_Encoding.m_Unicodes[i] == 0) { |
1461 if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { | 1752 m_Encoding.m_Unicodes[i] = i; |
1462 baseEncoding = bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENC
ODING_BUILTIN; | 1753 } |
1463 } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { | 1754 } |
1464 baseEncoding = bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCO
DING_BUILTIN; | 1755 } |
1465 } | 1756 } |
1466 } | 1757 return TRUE; |
1467 if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_E
NCODING_WINANSI) | 1758 } |
1468 && m_pCharNames == NULL) || (m_Flags & PDFFONT_NONSYMBOLIC)) { | 1759 void CPDF_Type3Font::CheckType3FontMetrics() { |
1469 if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && (!m_Font.m_Face->num_charmap
s || !m_Font.m_Face->charmaps)) { | 1760 CheckFontMetrics(); |
1470 int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar")); | 1761 } |
1471 if(nStartChar < 0 || nStartChar > 255) | 1762 CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) { |
1472 return; | 1763 if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) { |
1473 | 1764 return NULL; |
1474 int charcode = 0; | 1765 } |
1475 for (; charcode < nStartChar; charcode ++) { | 1766 CPDF_Type3Char* pChar = NULL; |
1476 m_GlyphIndex[charcode] = 0; | 1767 if (m_CacheMap.Lookup((FX_LPVOID)(FX_UINTPTR) charcode, (FX_LPVOID&)pChar)) { |
1477 } | 1768 if (pChar->m_bPageRequired && m_pPageResources) { |
1478 FX_WORD nGlyph = charcode - nStartChar + 3; | 1769 delete pChar; |
1479 for (; charcode < 256; charcode ++, nGlyph ++) { | 1770 m_CacheMap.RemoveKey((FX_LPVOID)(FX_UINTPTR) charcode); |
1480 m_GlyphIndex[charcode] = nGlyph; | 1771 return LoadChar(charcode, level + 1); |
1481 } | |
1482 return; | |
1483 } | |
1484 FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1); | |
1485 FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE; | |
1486 if (!bMSUnicode) { | |
1487 if (m_Flags & PDFFONT_NONSYMBOLIC) { | |
1488 bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0); | |
1489 bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0); | |
1490 } else { | |
1491 bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0); | |
1492 bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0); | |
1493 } | |
1494 } | |
1495 FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode")); | |
1496 for (int charcode = 0; charcode < 256; charcode ++) { | |
1497 FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charco
de); | |
1498 if (name == NULL) { | |
1499 m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Fon
t.m_Face, charcode) : -1; | |
1500 continue; | |
1501 } | |
1502 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); | |
1503 if (bMSSymbol) { | |
1504 const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; | |
1505 for (int j = 0; j < 4; j ++) { | |
1506 FX_WORD unicode = prefix[j] * 256 + charcode; | |
1507 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face,
unicode); | |
1508 if (m_GlyphIndex[charcode]) { | |
1509 break; | |
1510 } | |
1511 } | |
1512 } else if (m_Encoding.m_Unicodes[charcode]) { | |
1513 if (bMSUnicode) { | |
1514 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face,
m_Encoding.m_Unicodes[charcode]); | |
1515 } else if (bMacRoman) { | |
1516 FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPL
E_ROMAN, m_Encoding.m_Unicodes[charcode]); | |
1517 if (!maccode) { | |
1518 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Fa
ce, (char *)name); | |
1519 } else { | |
1520 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Fa
ce, maccode); | |
1521 } | |
1522 } | |
1523 } | |
1524 if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff
) && name != NULL) { | |
1525 if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { | |
1526 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face,
32); | |
1527 } else { | |
1528 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face,
(char*)name); | |
1529 if (m_GlyphIndex[charcode] == 0) { | |
1530 if (bToUnicode) { | |
1531 CFX_WideString wsUnicode = UnicodeFromCharCode(charc
ode); | |
1532 if (!wsUnicode.IsEmpty()) { | |
1533 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_F
ont.m_Face, wsUnicode[0]); | |
1534 m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; | |
1535 } | |
1536 } | |
1537 if (m_GlyphIndex[charcode] == 0) { | |
1538 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.
m_Face, charcode); | |
1539 } | |
1540 } | |
1541 } | |
1542 } | |
1543 } | |
1544 return; | |
1545 } | |
1546 if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { | |
1547 const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; | |
1548 FX_BOOL bGotOne = FALSE; | |
1549 for (int charcode = 0; charcode < 256; charcode ++) { | |
1550 for (int j = 0; j < 4; j ++) { | |
1551 FX_WORD unicode = prefix[j] * 256 + charcode; | |
1552 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unic
ode); | |
1553 if (m_GlyphIndex[charcode]) { | |
1554 bGotOne = TRUE; | |
1555 break; | |
1556 } | |
1557 } | |
1558 } | |
1559 if (bGotOne) { | |
1560 if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { | |
1561 for (int charcode = 0; charcode < 256; charcode ++) { | |
1562 FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames
, charcode); | |
1563 if (name == NULL) { | |
1564 continue; | |
1565 } | |
1566 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(n
ame); | |
1567 } | |
1568 } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) { | |
1569 for (int charcode = 0; charcode < 256; charcode ++) { | |
1570 m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXF
T_ENCODING_APPLE_ROMAN, charcode); | |
1571 } | |
1572 } | |
1573 return; | |
1574 } | |
1575 } | |
1576 if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) { | |
1577 FX_BOOL bGotOne = FALSE; | |
1578 for (int charcode = 0; charcode < 256; charcode ++) { | |
1579 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode
); | |
1580 m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODI
NG_APPLE_ROMAN, charcode); | |
1581 if (m_GlyphIndex[charcode]) { | |
1582 bGotOne = TRUE; | |
1583 } | |
1584 } | |
1585 if (m_pFontFile || bGotOne) { | |
1586 return; | |
1587 } | |
1588 } | |
1589 if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) { | |
1590 FX_BOOL bGotOne = FALSE; | |
1591 const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding
); | |
1592 for (int charcode = 0; charcode < 256; charcode ++) { | |
1593 if (m_pFontFile == NULL) { | |
1594 FX_LPCSTR name = GetAdobeCharName(0, m_pCharNames, charcode); | |
1595 if (name != NULL) { | |
1596 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(n
ame); | |
1597 } else if (pUnicodes) { | |
1598 m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; | |
1599 } | |
1600 } else { | |
1601 m_Encoding.m_Unicodes[charcode] = charcode; | |
1602 } | |
1603 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encodi
ng.m_Unicodes[charcode]); | |
1604 if (m_GlyphIndex[charcode]) { | |
1605 bGotOne = TRUE; | |
1606 } | |
1607 } | |
1608 if (bGotOne) { | |
1609 return; | |
1610 } | |
1611 } | |
1612 for (int charcode = 0; charcode < 256; charcode ++) { | |
1613 m_GlyphIndex[charcode] = charcode; | |
1614 } | |
1615 } | |
1616 CPDF_Type3Font::CPDF_Type3Font() | |
1617 { | |
1618 m_pPageResources = NULL; | |
1619 FXSYS_memset32(m_CharWidthL, 0, sizeof m_CharWidthL); | |
1620 } | |
1621 CPDF_Type3Font::~CPDF_Type3Font() | |
1622 { | |
1623 FX_POSITION pos = m_CacheMap.GetStartPosition(); | |
1624 while (pos) { | |
1625 FX_LPVOID key, value; | |
1626 m_CacheMap.GetNextAssoc(pos, key, value); | |
1627 delete (CPDF_Type3Char*)value; | |
1628 } | |
1629 m_CacheMap.RemoveAll(); | |
1630 pos = m_DeletedMap.GetStartPosition(); | |
1631 while (pos) { | |
1632 FX_LPVOID key, value; | |
1633 m_DeletedMap.GetNextAssoc(pos, key, value); | |
1634 delete (CPDF_Type3Char*)key; | |
1635 } | |
1636 } | |
1637 FX_BOOL CPDF_Type3Font::_Load() | |
1638 { | |
1639 m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources")); | |
1640 CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix")); | |
1641 FX_FLOAT xscale = 1.0f, yscale = 1.0f; | |
1642 if (pMatrix) { | |
1643 m_FontMatrix = pMatrix->GetMatrix(); | |
1644 xscale = m_FontMatrix.a; | |
1645 yscale = m_FontMatrix.d; | |
1646 } | |
1647 CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox")); | |
1648 if (pBBox) { | |
1649 m_FontBBox.left = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 10
00); | |
1650 m_FontBBox.bottom = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(1), yscale) *
1000); | |
1651 m_FontBBox.right = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1
000); | |
1652 m_FontBBox.top = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 100
0); | |
1653 } | |
1654 int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar")); | |
1655 CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths")); | |
1656 if (pWidthArray && (StartChar >= 0 && StartChar < 256)) { | |
1657 FX_DWORD count = pWidthArray->GetCount(); | |
1658 if (count > 256) { | |
1659 count = 256; | |
1660 } | |
1661 if (StartChar + count > 256) { | |
1662 count = 256 - StartChar; | |
1663 } | |
1664 for (FX_DWORD i = 0; i < count; i ++) { | |
1665 m_CharWidthL[StartChar + i] = FXSYS_round(FXSYS_Mul(pWidthArray->Get
Number(i), xscale) * 1000); | |
1666 } | |
1667 } | |
1668 m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs")); | |
1669 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding")); | |
1670 if (pEncoding) { | |
1671 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE); | |
1672 if (m_pCharNames) { | |
1673 for (int i = 0; i < 256; i ++) { | |
1674 m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames
[i]); | |
1675 if (m_Encoding.m_Unicodes[i] == 0) { | |
1676 m_Encoding.m_Unicodes[i] = i; | |
1677 } | |
1678 } | |
1679 } | |
1680 } | |
1681 return TRUE; | |
1682 } | |
1683 void CPDF_Type3Font::CheckType3FontMetrics() | |
1684 { | |
1685 CheckFontMetrics(); | |
1686 } | |
1687 CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) | |
1688 { | |
1689 if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) { | |
1690 return NULL; | |
1691 } | |
1692 CPDF_Type3Char* pChar = NULL; | |
1693 if (m_CacheMap.Lookup((FX_LPVOID)(FX_UINTPTR)charcode, (FX_LPVOID&)pChar)) { | |
1694 if (pChar->m_bPageRequired && m_pPageResources) { | |
1695 delete pChar; | |
1696 m_CacheMap.RemoveKey((FX_LPVOID)(FX_UINTPTR)charcode); | |
1697 return LoadChar(charcode, level + 1); | |
1698 } | |
1699 return pChar; | |
1700 } | |
1701 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); | |
1702 if (name == NULL) { | |
1703 return NULL; | |
1704 } | |
1705 CPDF_Stream* pStream = (CPDF_Stream*)(m_pCharProcs ? m_pCharProcs->GetElemen
tValue(name) : NULL); | |
1706 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { | |
1707 return NULL; | |
1708 } | |
1709 pChar = FX_NEW CPDF_Type3Char; | |
1710 pChar->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pFontResources ? m_pFontRes
ources : m_pPageResources, pStream, NULL); | |
1711 pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1); | |
1712 FX_FLOAT scale = m_FontMatrix.GetXUnit(); | |
1713 pChar->m_Width = (FX_INT32)(pChar->m_Width * scale + 0.5f); | |
1714 FX_RECT &rcBBox = pChar->m_BBox; | |
1715 CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bo
ttom / 1000.0f, | |
1716 (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.t
op / 1000.0f); | |
1717 if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) { | |
1718 char_rect = pChar->m_pForm->CalcBoundingBox(); | |
1719 } | |
1720 char_rect.Transform(&m_FontMatrix); | |
1721 rcBBox.left = FXSYS_round(char_rect.left * 1000); | |
1722 rcBBox.right = FXSYS_round(char_rect.right * 1000); | |
1723 rcBBox.top = FXSYS_round(char_rect.top * 1000); | |
1724 rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000); | |
1725 m_CacheMap.SetAt((FX_LPVOID)(FX_UINTPTR)charcode, pChar); | |
1726 if (pChar->m_pForm->CountObjects() == 0) { | |
1727 delete pChar->m_pForm; | |
1728 pChar->m_pForm = NULL; | |
1729 } | 1772 } |
1730 return pChar; | 1773 return pChar; |
1731 } | 1774 } |
1732 int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) | 1775 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
1733 { | 1776 if (name == NULL) { |
1734 if (charcode > 0xff) { | 1777 return NULL; |
1735 charcode = 0; | 1778 } |
1736 } | 1779 CPDF_Stream* pStream = |
1737 if (m_CharWidthL[charcode]) { | 1780 (CPDF_Stream*)(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : NULL); |
1738 return m_CharWidthL[charcode]; | 1781 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) { |
1739 } | 1782 return NULL; |
1740 CPDF_Type3Char* pChar = LoadChar(charcode, level); | 1783 } |
1741 if (pChar == NULL) { | 1784 pChar = FX_NEW CPDF_Type3Char; |
1742 return 0; | 1785 pChar->m_pForm = |
1743 } | 1786 FX_NEW CPDF_Form(m_pDocument, |
1744 return pChar->m_Width; | 1787 m_pFontResources ? m_pFontResources : m_pPageResources, |
1745 } | 1788 pStream, |
1746 void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) | 1789 NULL); |
1747 { | 1790 pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1); |
1748 CPDF_Type3Char* pChar = LoadChar(charcode, level); | 1791 FX_FLOAT scale = m_FontMatrix.GetXUnit(); |
1749 if (pChar == NULL) { | 1792 pChar->m_Width = (FX_INT32)(pChar->m_Width * scale + 0.5f); |
1750 rect.left = rect.right = rect.top = rect.bottom = 0; | 1793 FX_RECT& rcBBox = pChar->m_BBox; |
1751 return; | 1794 CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, |
1752 } | 1795 (FX_FLOAT)rcBBox.bottom / 1000.0f, |
1753 rect = pChar->m_BBox; | 1796 (FX_FLOAT)rcBBox.right / 1000.0f, |
1754 } | 1797 (FX_FLOAT)rcBBox.top / 1000.0f); |
1755 CPDF_Type3Char::CPDF_Type3Char() | 1798 if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) { |
1756 { | 1799 char_rect = pChar->m_pForm->CalcBoundingBox(); |
1757 m_pForm = NULL; | 1800 } |
1758 m_pBitmap = NULL; | 1801 char_rect.Transform(&m_FontMatrix); |
1759 m_bPageRequired = FALSE; | 1802 rcBBox.left = FXSYS_round(char_rect.left * 1000); |
1760 m_bColored = FALSE; | 1803 rcBBox.right = FXSYS_round(char_rect.right * 1000); |
1761 } | 1804 rcBBox.top = FXSYS_round(char_rect.top * 1000); |
1762 CPDF_Type3Char::~CPDF_Type3Char() | 1805 rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000); |
1763 { | 1806 m_CacheMap.SetAt((FX_LPVOID)(FX_UINTPTR) charcode, pChar); |
1764 if (m_pForm) { | 1807 if (pChar->m_pForm->CountObjects() == 0) { |
1765 delete m_pForm; | 1808 delete pChar->m_pForm; |
1766 } | 1809 pChar->m_pForm = NULL; |
1767 if (m_pBitmap) { | 1810 } |
1768 delete m_pBitmap; | 1811 return pChar; |
1769 } | 1812 } |
1770 } | 1813 int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) { |
| 1814 if (charcode > 0xff) { |
| 1815 charcode = 0; |
| 1816 } |
| 1817 if (m_CharWidthL[charcode]) { |
| 1818 return m_CharWidthL[charcode]; |
| 1819 } |
| 1820 CPDF_Type3Char* pChar = LoadChar(charcode, level); |
| 1821 if (pChar == NULL) { |
| 1822 return 0; |
| 1823 } |
| 1824 return pChar->m_Width; |
| 1825 } |
| 1826 void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) { |
| 1827 CPDF_Type3Char* pChar = LoadChar(charcode, level); |
| 1828 if (pChar == NULL) { |
| 1829 rect.left = rect.right = rect.top = rect.bottom = 0; |
| 1830 return; |
| 1831 } |
| 1832 rect = pChar->m_BBox; |
| 1833 } |
| 1834 CPDF_Type3Char::CPDF_Type3Char() { |
| 1835 m_pForm = NULL; |
| 1836 m_pBitmap = NULL; |
| 1837 m_bPageRequired = FALSE; |
| 1838 m_bColored = FALSE; |
| 1839 } |
| 1840 CPDF_Type3Char::~CPDF_Type3Char() { |
| 1841 if (m_pForm) { |
| 1842 delete m_pForm; |
| 1843 } |
| 1844 if (m_pBitmap) { |
| 1845 delete m_pBitmap; |
| 1846 } |
| 1847 } |
OLD | NEW |