blob: c656f0c15edf65649d9414204d2ef87f4ec3e8ce [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "../../include/pdfwindow/PDFWindow.h"
8#include "../../include/pdfwindow/PWL_Wnd.h"
9#include "../../include/pdfwindow/PWL_FontMap.h"
10
11#define DEFAULT_FONT_NAME "Helvetica"
12
13/* ------------------------------ CPWL_FontMap ------------------------------ */
14
15CPWL_FontMap::CPWL_FontMap(IFX_SystemHandler* pSystemHandler) :
16 m_pPDFDoc(NULL),
17 m_pSystemHandler(pSystemHandler)
18{
19 ASSERT(m_pSystemHandler != NULL);
20}
21
22CPWL_FontMap::~CPWL_FontMap()
23{
24 if (m_pPDFDoc)
25 {
26 delete m_pPDFDoc;
27 m_pPDFDoc = NULL;
28 }
29
30 Empty();
31}
32
33void CPWL_FontMap::SetSystemHandler(IFX_SystemHandler* pSystemHandler)
34{
35 m_pSystemHandler = pSystemHandler;
36}
37
38CPDF_Document* CPWL_FontMap::GetDocument()
39{
40 if (!m_pPDFDoc)
41 {
42 if (CPDF_ModuleMgr::Get())
43 {
44 m_pPDFDoc = FX_NEW CPDF_Document;
45 m_pPDFDoc->CreateNewDoc();
46 }
47 }
48
49 return m_pPDFDoc;
50}
51
52CPDF_Font* CPWL_FontMap::GetPDFFont(FX_INT32 nFontIndex)
53{
54 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize())
55 {
56 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex))
57 {
58 return pData->pFont;
59 }
60 }
61
62 return NULL;
63}
64
65CFX_ByteString CPWL_FontMap::GetPDFFontAlias(FX_INT32 nFontIndex)
66{
67 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize())
68 {
69 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex))
70 {
71 return pData->sFontName;
72 }
73 }
74
75 return "";
76}
77
78FX_BOOL CPWL_FontMap::KnowWord(FX_INT32 nFontIndex, FX_WORD word)
79{
80 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize())
81 {
82 if (m_aData.GetAt(nFontIndex))
83 {
84 return CharCodeFromUnicode(nFontIndex, word) >= 0;
85 }
86 }
87
88 return FALSE;
89}
90
91FX_INT32 CPWL_FontMap::GetWordFontIndex(FX_WORD word, FX_INT32 nCharset, FX_INT32 nFontIndex)
92{
93 if (nFontIndex > 0)
94 {
95 if (KnowWord(nFontIndex, word))
96 return nFontIndex;
97 }
98 else
99 {
100 if (const CPWL_FontMap_Data* pData = GetFontMapData(0))
101 {
102 if (nCharset == DEFAULT_CHARSET ||
103 pData->nCharset == SYMBOL_CHARSET ||
104 nCharset == pData->nCharset)
105 {
106 if (KnowWord(0, word))
107 {
108 return 0;
109 }
110 }
111 }
112 }
113
114 FX_INT32 nNewFontIndex = -1;
115
116 nNewFontIndex = this->GetFontIndex(GetNativeFontName(nCharset), nCharset, TRUE);
117 if (nNewFontIndex >= 0)
118 {
119 if (KnowWord(nNewFontIndex, word))
120 return nNewFontIndex;
121 }
122
123 nNewFontIndex = this->GetFontIndex("Arial Unicode MS", DEFAULT_CHARSET, FALSE);
124 if (nNewFontIndex >= 0)
125 {
126 if (KnowWord(nNewFontIndex, word))
127 return nNewFontIndex;
128 }
129
130 return -1;
131}
132
133FX_INT32 CPWL_FontMap::CharCodeFromUnicode(FX_INT32 nFontIndex, FX_WORD word)
134{
135 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex))
136 {
137 if (pData->pFont)
138 {
139 if (pData->pFont->IsUnicodeCompatible())
140 {
141 int nCharCode = pData->pFont->CharCodeFromUnicode(word);
142 pData->pFont->GlyphFromCharCode(nCharCode);
143 return nCharCode;
144 }
145 else
146 {
147 if (word < 0xFF)
148 return word;
149 }
150 }
151 }
152
153 return -1;
154}
155
156CFX_ByteString CPWL_FontMap::GetNativeFontName(FX_INT32 nCharset)
157{
158 //searching native font is slow, so we must save time
159 for (FX_INT32 i=0,sz=m_aNativeFont.GetSize(); i<sz; i++)
160 {
161 if (CPWL_FontMap_Native* pData = m_aNativeFont.GetAt(i))
162 {
163 if (pData->nCharset == nCharset)
164 return pData->sFontName;
165 }
166 }
167
168 CFX_ByteString sNew = GetNativeFont(nCharset);
169
170 if (!sNew.IsEmpty())
171 {
172 CPWL_FontMap_Native* pNewData = new CPWL_FontMap_Native;
173 pNewData->nCharset = nCharset;
174 pNewData->sFontName = sNew;
175
176 m_aNativeFont.Add(pNewData);
177 }
178
179 return sNew;
180}
181
182void CPWL_FontMap::Empty()
183{
184 {
185 for (FX_INT32 i=0, sz=m_aData.GetSize(); i<sz; i++)
186 delete m_aData.GetAt(i);
187
188 m_aData.RemoveAll();
189 }
190 {
191 for (FX_INT32 i=0, sz=m_aNativeFont.GetSize(); i<sz; i++)
192 delete m_aNativeFont.GetAt(i);
193
194 m_aNativeFont.RemoveAll();
195 }
196}
197
198void CPWL_FontMap::Initial(FX_LPCSTR fontname)
199{
200 CFX_ByteString sFontName = fontname;
201
202 if (sFontName.IsEmpty())
203 sFontName = DEFAULT_FONT_NAME;
204
205 GetFontIndex(sFontName, ANSI_CHARSET, FALSE);
206
207 //GetFontIndex(this->GetNativeFontName(nCharset), nCharset);
208}
209
210
211/*
212List of currently supported standard fonts:
213Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique
214Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique
215Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic
216Symbol, ZapfDingbats
217*/
218
219const char* g_sDEStandardFontName[] = {"Courier", "Courier-Bold", "Courier-BoldOblique", "Courier-Oblique",
220 "Helvetica", "Helvetica-Bold", "Helvetica-BoldOblique", "Helvetica-Oblique",
221 "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
222 "Symbol", "ZapfDingbats"};
223
224FX_BOOL CPWL_FontMap::IsStandardFont(const CFX_ByteString& sFontName)
225{
226 for (FX_INT32 i=0; i<14; i++)
227 {
228 if (sFontName == g_sDEStandardFontName[i])
229 return TRUE;
230 }
231
232 return FALSE;
233}
234
235FX_INT32 CPWL_FontMap::FindFont(const CFX_ByteString& sFontName, FX_INT32 nCharset)
236{
237 for (FX_INT32 i=0,sz=m_aData.GetSize(); i<sz; i++)
238 {
239 if (CPWL_FontMap_Data* pData = m_aData.GetAt(i))
240 {
241 if (nCharset == DEFAULT_CHARSET || nCharset == pData->nCharset)
242 {
243 if (sFontName.IsEmpty() || pData->sFontName == sFontName)
244 return i;
245 }
246 }
247 }
248
249 return -1;
250}
251
252FX_INT32 CPWL_FontMap::GetFontIndex(const CFX_ByteString& sFontName, FX_INT32 nCharset, FX_BOOL bFind)
253{
254 FX_INT32 nFontIndex = FindFont(EncodeFontAlias(sFontName, nCharset), nCharset);
255 if (nFontIndex >= 0) return nFontIndex;
256
257// nFontIndex = FindFont("", nCharset);
258// if (nFontIndex >= 0) return nFontIndex;
259
260 CFX_ByteString sAlias;
261 CPDF_Font* pFont = NULL;
262
263 if (bFind)
264 pFont = FindFontSameCharset(sAlias, nCharset);
265
266 if (!pFont)
267 {
268 CFX_ByteString sTemp = sFontName;
269 pFont = AddFontToDocument(GetDocument(), sTemp, nCharset);
270
271 /*
272 if (FindFont(sAlias))
273 {
274 sAlias = EncodeFontAlias(sTemp, nCharset);
275 }
276 else
277 */
278 {
279 sAlias = EncodeFontAlias(sTemp, nCharset);
280 }
281 }
282
283 AddedFont(pFont, sAlias);
284
285 return AddFontData(pFont, sAlias, nCharset);
286}
287
288FX_INT32 CPWL_FontMap::GetPWLFontIndex(FX_WORD word, FX_INT32 nCharset)
289{
290 FX_INT32 nFind = -1;
291
292 for (FX_INT32 i=0,sz=m_aData.GetSize(); i<sz; i++)
293 {
294 if (CPWL_FontMap_Data* pData = m_aData.GetAt(i))
295 {
296 if (pData->nCharset == nCharset)
297 {
298 nFind = i;
299 break;
300 }
301 }
302 }
303
304 CPDF_Font* pNewFont = GetPDFFont(nFind);
305
306 if (!pNewFont) return -1;
307
308 /*
309 if (CPDF_Font* pFont = GetPDFFont(nFind))
310 {
311 PWLFont.AddWordToFontDict(pFontDict, word);
312 }
313 */
314
315#ifdef FOXIT_CHROME_BUILD
316 CFX_ByteString sAlias = EncodeFontAlias("Arial_Chrome", nCharset);
317#else
318 CFX_ByteString sAlias = EncodeFontAlias("Arial_Foxit", nCharset);
319#endif
320 AddedFont(pNewFont, sAlias);
321
322 return AddFontData(pNewFont, sAlias, nCharset);
323}
324
325CPDF_Font* CPWL_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset)
326{
327 return NULL;
328}
329
330FX_INT32 CPWL_FontMap::AddFontData(CPDF_Font* pFont, const CFX_ByteString& sFontAlias, FX_INT32 nCharset)
331{
332 CPWL_FontMap_Data* pNewData = new CPWL_FontMap_Data;
333 pNewData->pFont = pFont;
334 pNewData->sFontName = sFontAlias;
335 pNewData->nCharset = nCharset;
336
337 m_aData.Add(pNewData);
338
339 return m_aData.GetSize() -1;
340}
341
342void CPWL_FontMap::AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias)
343{
344}
345
346CFX_ByteString CPWL_FontMap::GetFontName(FX_INT32 nFontIndex)
347{
348 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize())
349 {
350 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex))
351 {
352 return pData->sFontName;
353 }
354 }
355
356 return "";
357}
358
359CFX_ByteString CPWL_FontMap::GetNativeFont(FX_INT32 nCharset)
360{
361 CFX_ByteString sFontName;
362
363 if (nCharset == DEFAULT_CHARSET)
364 nCharset = GetNativeCharset();
365
366 sFontName = GetDefaultFontByCharset(nCharset);
367
368 if (m_pSystemHandler)
369 {
370 if (m_pSystemHandler->FindNativeTrueTypeFont(nCharset, sFontName))
371 return sFontName;
372
373 sFontName = m_pSystemHandler->GetNativeTrueTypeFont(nCharset);
374 }
375
376 return sFontName;
377}
378
379CPDF_Font* CPWL_FontMap::AddFontToDocument(CPDF_Document* pDoc, CFX_ByteString& sFontName, FX_BYTE nCharset)
380{
381 if (IsStandardFont(sFontName))
382 return AddStandardFont(pDoc, sFontName);
383 else
384 return AddSystemFont(pDoc, sFontName, nCharset);
385}
386
387CPDF_Font* CPWL_FontMap::AddStandardFont(CPDF_Document* pDoc, CFX_ByteString& sFontName)
388{
389 if (!pDoc) return NULL;
390
391 CPDF_Font* pFont = NULL;
392
393 if (sFontName == "ZapfDingbats")
394 pFont = pDoc->AddStandardFont(sFontName, NULL);
395 else
396 {
397 CPDF_FontEncoding fe(PDFFONT_ENCODING_WINANSI);
398 pFont = pDoc->AddStandardFont(sFontName, &fe);
399 }
400
401 return pFont;
402}
403
404CPDF_Font* CPWL_FontMap::AddSystemFont(CPDF_Document* pDoc, CFX_ByteString& sFontName, FX_BYTE nCharset)
405{
406 if (!pDoc) return NULL;
407
408 if (sFontName.IsEmpty()) sFontName = GetNativeFont(nCharset);
409 if (nCharset == DEFAULT_CHARSET) nCharset = GetNativeCharset();
410
411 if (m_pSystemHandler)
412 return m_pSystemHandler->AddNativeTrueTypeFontToPDF(pDoc, sFontName, nCharset);
413
414 return NULL;
415}
416
417CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName, FX_INT32 nCharset)
418{
419 CFX_ByteString sPostfix;
420 sPostfix.Format("_%02X", nCharset);
421 return EncodeFontAlias(sFontName) + sPostfix;
422}
423
424CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName)
425{
426 CFX_ByteString sRet = sFontName;
427 sRet.Remove(' ');
428 return sRet;
429}
430
431FX_INT32 CPWL_FontMap::GetFontMapCount() const
432{
433 return m_aData.GetSize();
434}
435
436const CPWL_FontMap_Data* CPWL_FontMap::GetFontMapData(FX_INT32 nIndex) const
437{
438 if (nIndex >=0 && nIndex < m_aData.GetSize())
439 {
440 return m_aData.GetAt(nIndex);
441 }
442
443 return NULL;
444}
445
446FX_INT32 CPWL_FontMap::GetNativeCharset()
447{
448 FX_BYTE nCharset = ANSI_CHARSET;
449 FX_INT32 iCodePage = FXSYS_GetACP();
450 switch (iCodePage)
451 {
452 case 932://Japan
453 nCharset = SHIFTJIS_CHARSET;
454 break;
455 case 936://Chinese (PRC, Singapore)
456 nCharset = GB2312_CHARSET;
457 break;
458 case 950://Chinese (Taiwan; Hong Kong SAR, PRC)
459 nCharset = GB2312_CHARSET;
460 break;
461 case 1252://Windows 3.1 Latin 1 (US, Western Europe)
462 nCharset = ANSI_CHARSET;
463 break;
464 case 874://Thai
465 nCharset = THAI_CHARSET;
466 break;
467 case 949://Korean
468 nCharset = HANGUL_CHARSET;
469 break;
470 case 1200://Unicode (BMP of ISO 10646)
471 nCharset = ANSI_CHARSET;
472 break;
473 case 1250://Windows 3.1 Eastern European
474 nCharset = EASTEUROPE_CHARSET;
475 break;
476 case 1251://Windows 3.1 Cyrillic
477 nCharset = RUSSIAN_CHARSET;
478 break;
479 case 1253://Windows 3.1 Greek
480 nCharset = GREEK_CHARSET;
481 break;
482 case 1254://Windows 3.1 Turkish
483 nCharset = TURKISH_CHARSET;
484 break;
485 case 1255://Hebrew
486 nCharset = HEBREW_CHARSET;
487 break;
488 case 1256://Arabic
489 nCharset = ARABIC_CHARSET;
490 break;
491 case 1257://Baltic
492 nCharset = BALTIC_CHARSET;
493 break;
494 case 1258://Vietnamese
495 nCharset = VIETNAMESE_CHARSET;
496 break;
497 case 1361://Korean(Johab)
498 nCharset = JOHAB_CHARSET;
499 break;
500 }
501 return nCharset;
502}
503
504const CPWL_FontMap::CharsetFontMap CPWL_FontMap::defaultTTFMap[] = {
505 { ANSI_CHARSET, "Helvetica" },
506 { GB2312_CHARSET, "SimSun" },
507 { CHINESEBIG5_CHARSET, "MingLiU" },
508 { SHIFTJIS_CHARSET, "MS Gothic" },
509 { HANGUL_CHARSET, "Batang" },
510 { RUSSIAN_CHARSET, "Arial" },
511 { EASTEUROPE_CHARSET, "Tahoma" },
512 { ARABIC_CHARSET, "Arial" },
513 { -1, NULL }
514};
515
516CFX_ByteString CPWL_FontMap::GetDefaultFontByCharset(FX_INT32 nCharset)
517{
518 int i = 0;
519 while (defaultTTFMap[i].charset != -1) {
520 if (nCharset == defaultTTFMap[i].charset)
521 return defaultTTFMap[i].fontname;
522 ++i;
523 }
524 return "";
525}
526
527FX_INT32 CPWL_FontMap::CharSetFromUnicode(FX_WORD word, FX_INT32 nOldCharset)
528{
529 if(m_pSystemHandler && (-1 != m_pSystemHandler->GetCharSet()))
530 return m_pSystemHandler->GetCharSet();
531 //to avoid CJK Font to show ASCII
532 if (word < 0x7F) return ANSI_CHARSET;
533 //follow the old charset
534 if (nOldCharset != DEFAULT_CHARSET) return nOldCharset;
535
536 //find new charset
537 if ((word >= 0x4E00 && word <= 0x9FA5) ||
538 (word >= 0xE7C7 && word <= 0xE7F3) ||
539 (word >= 0x3000 && word <= 0x303F) || //£©"¡¶" "¡·" "¡£" "¡¢"
540 (word >= 0x2000 && word <= 0x206F))
541 {
542 return GB2312_CHARSET;
543 }
544
545 if (((word >= 0x3040) && (word <= 0x309F)) ||
546 ((word >= 0x30A0) && (word <= 0x30FF)) ||
547 ((word >= 0x31F0) && (word <= 0x31FF)) ||
548 ((word >= 0xFF00) && (word <= 0xFFEF)) )
549 {
550 return SHIFTJIS_CHARSET;
551 }
552
553 if (((word >= 0xAC00) && (word <= 0xD7AF)) ||
554 ((word >= 0x1100) && (word <= 0x11FF)) ||
555 ((word >= 0x3130) && (word <= 0x318F)))
556 {
557 return HANGUL_CHARSET;
558 }
559
560 if (word >= 0x0E00 && word <= 0x0E7F)
561 return THAI_CHARSET;
562
563 if ((word >= 0x0370 && word <= 0x03FF) ||
564 (word >= 0x1F00 && word <= 0x1FFF))
565 return GREEK_CHARSET;
566
567 if ((word >= 0x0600 && word <= 0x06FF) ||
568 (word >= 0xFB50 && word <= 0xFEFC))
569 return ARABIC_CHARSET;
570
571 if (word >= 0x0590 && word <= 0x05FF)
572 return HEBREW_CHARSET;
573
574 if (word >= 0x0400 && word <= 0x04FF)
575 return RUSSIAN_CHARSET;
576
577 if (word >= 0x0100 && word <= 0x024F)
578 return EASTEUROPE_CHARSET;
579
580 if (word >= 0x1E00 && word <= 0x1EFF)
581 return VIETNAMESE_CHARSET;
582
583 return ANSI_CHARSET;
584}
585
586/* ------------------------ CPWL_DocFontMap ------------------------ */
587
588CPWL_DocFontMap::CPWL_DocFontMap(IFX_SystemHandler* pSystemHandler, CPDF_Document* pAttachedDoc)
589 : CPWL_FontMap(pSystemHandler),
590 m_pAttachedDoc(pAttachedDoc)
591{
592}
593
594CPWL_DocFontMap::~CPWL_DocFontMap()
595{
596}
597
598CPDF_Document* CPWL_DocFontMap::GetDocument()
599{
600 return m_pAttachedDoc;
601}