| 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 |