• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
CPWL_FontMap(IFX_SystemHandler * pSystemHandler)15 CPWL_FontMap::CPWL_FontMap(IFX_SystemHandler* pSystemHandler) :
16 	m_pPDFDoc(NULL),
17 	m_pSystemHandler(pSystemHandler)
18 {
19 	ASSERT(m_pSystemHandler != NULL);
20 }
21 
~CPWL_FontMap()22 CPWL_FontMap::~CPWL_FontMap()
23 {
24 	if (m_pPDFDoc)
25 	{
26 		delete m_pPDFDoc;
27 		m_pPDFDoc = NULL;
28 	}
29 
30 	Empty();
31 }
32 
SetSystemHandler(IFX_SystemHandler * pSystemHandler)33 void CPWL_FontMap::SetSystemHandler(IFX_SystemHandler* pSystemHandler)
34 {
35 	m_pSystemHandler = pSystemHandler;
36 }
37 
GetDocument()38 CPDF_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 
GetPDFFont(FX_INT32 nFontIndex)52 CPDF_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 
GetPDFFontAlias(FX_INT32 nFontIndex)65 CFX_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 
KnowWord(FX_INT32 nFontIndex,FX_WORD word)78 FX_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 
GetWordFontIndex(FX_WORD word,FX_INT32 nCharset,FX_INT32 nFontIndex)91 FX_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 
CharCodeFromUnicode(FX_INT32 nFontIndex,FX_WORD word)133 FX_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 
GetNativeFontName(FX_INT32 nCharset)156 CFX_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 
Empty()182 void 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 
Initial(FX_LPCSTR fontname)198 void 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 /*
212 List of currently supported standard fonts:
213 Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique
214 Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique
215 Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic
216 Symbol, ZapfDingbats
217 */
218 
219 const 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 
IsStandardFont(const CFX_ByteString & sFontName)224 FX_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 
FindFont(const CFX_ByteString & sFontName,FX_INT32 nCharset)235 FX_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 
GetFontIndex(const CFX_ByteString & sFontName,FX_INT32 nCharset,FX_BOOL bFind)252 FX_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 
GetPWLFontIndex(FX_WORD word,FX_INT32 nCharset)288 FX_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 
FindFontSameCharset(CFX_ByteString & sFontAlias,FX_INT32 nCharset)325 CPDF_Font* CPWL_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset)
326 {
327 	return NULL;
328 }
329 
AddFontData(CPDF_Font * pFont,const CFX_ByteString & sFontAlias,FX_INT32 nCharset)330 FX_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 
AddedFont(CPDF_Font * pFont,const CFX_ByteString & sFontAlias)342 void CPWL_FontMap::AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias)
343 {
344 }
345 
GetFontName(FX_INT32 nFontIndex)346 CFX_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 
GetNativeFont(FX_INT32 nCharset)359 CFX_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 
AddFontToDocument(CPDF_Document * pDoc,CFX_ByteString & sFontName,FX_BYTE nCharset)379 CPDF_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 
AddStandardFont(CPDF_Document * pDoc,CFX_ByteString & sFontName)387 CPDF_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 
AddSystemFont(CPDF_Document * pDoc,CFX_ByteString & sFontName,FX_BYTE nCharset)404 CPDF_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 
EncodeFontAlias(const CFX_ByteString & sFontName,FX_INT32 nCharset)417 CFX_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 
EncodeFontAlias(const CFX_ByteString & sFontName)424 CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName)
425 {
426 	CFX_ByteString sRet = sFontName;
427 	sRet.Remove(' ');
428 	return sRet;
429 }
430 
GetFontMapCount() const431 FX_INT32 CPWL_FontMap::GetFontMapCount() const
432 {
433 	return m_aData.GetSize();
434 }
435 
GetFontMapData(FX_INT32 nIndex) const436 const 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 
GetNativeCharset()446 FX_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 
504 const 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 
GetDefaultFontByCharset(FX_INT32 nCharset)516 CFX_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 
CharSetFromUnicode(FX_WORD word,FX_INT32 nOldCharset)527 FX_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 
CPWL_DocFontMap(IFX_SystemHandler * pSystemHandler,CPDF_Document * pAttachedDoc)588 CPWL_DocFontMap::CPWL_DocFontMap(IFX_SystemHandler* pSystemHandler, CPDF_Document* pAttachedDoc)
589 	: CPWL_FontMap(pSystemHandler),
590 	m_pAttachedDoc(pAttachedDoc)
591 {
592 }
593 
~CPWL_DocFontMap()594 CPWL_DocFontMap::~CPWL_DocFontMap()
595 {
596 }
597 
GetDocument()598 CPDF_Document* CPWL_DocFontMap::GetDocument()
599 {
600 	return m_pAttachedDoc;
601 }
602