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