// Copyright 2014 PDFium Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
#include "../../../include/fxge/fx_ge.h" | |
#include "../agg/include/fx_agg_driver.h" | |
#include "text_int.h" | |
#if !defined(_FPDFAPI_MINI_) && _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ | |
#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_))) | |
void CFX_AggDeviceDriver::InitPlatform() | |
{ | |
} | |
void CFX_AggDeviceDriver::DestroyPlatform() | |
{ | |
} | |
void CFX_FaceCache::InitPlatform() | |
{ | |
} | |
FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, | |
CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, | |
FX_FLOAT font_size, FX_DWORD argb) | |
{ | |
return FALSE; | |
} | |
CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font* pFont, FX_DWORD glyph_index, const CFX_AffineMatrix* pMatrix, | |
int dest_width, int anti_alias) | |
{ | |
return NULL; | |
} | |
void CFX_Font::ReleasePlatformResource() | |
{ | |
} | |
#endif | |
static const struct { | |
FX_LPCSTR m_pName; | |
FX_LPCSTR m_pSubstName; | |
} | |
Base14Substs[] = { | |
{"Courier", "Courier New"}, | |
{"Courier-Bold", "Courier New Bold"}, | |
{"Courier-BoldOblique", "Courier New Bold Italic"}, | |
{"Courier-Oblique", "Courier New Italic"}, | |
{"Helvetica", "Arial"}, | |
{"Helvetica-Bold", "Arial Bold"}, | |
{"Helvetica-BoldOblique", "Arial Bold Italic"}, | |
{"Helvetica-Oblique", "Arial Italic"}, | |
{"Times-Roman", "Times New Roman"}, | |
{"Times-Bold", "Times New Roman Bold"}, | |
{"Times-BoldItalic", "Times New Roman Bold Italic"}, | |
{"Times-Italic", "Times New Roman Italic"}, | |
}; | |
class CFX_LinuxFontInfo : public CFX_FolderFontInfo | |
{ | |
public: | |
virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact); | |
FX_BOOL ParseFontCfg(); | |
void* FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName); | |
}; | |
#define LINUX_GPNAMESIZE 6 | |
static const struct { | |
FX_LPCSTR NameArr[LINUX_GPNAMESIZE]; | |
} | |
LinuxGpFontList[] = { | |
{{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", "VL Gothic regular"}}, | |
{{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, "VL Gothic regular"}}, | |
{{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}}, | |
{{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}}, | |
}; | |
static const FX_LPCSTR g_LinuxGbFontList[] = { | |
"AR PL UMing CN Light", | |
"WenQuanYi Micro Hei", | |
"AR PL UKai CN", | |
}; | |
static const FX_LPCSTR g_LinuxB5FontList[] = { | |
"AR PL UMing TW Light", | |
"WenQuanYi Micro Hei", | |
"AR PL UKai TW", | |
}; | |
static const FX_LPCSTR g_LinuxHGFontList[] = { | |
"UnDotum", | |
}; | |
static FX_INT32 GetJapanesePreference(FX_LPCSTR facearr, int weight, int picth_family) | |
{ | |
CFX_ByteString face = facearr; | |
if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { | |
if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { | |
return 0; | |
} else { | |
return 1; | |
} | |
} else if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { | |
if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { | |
return 2; | |
} else { | |
return 3; | |
} | |
} | |
if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { | |
return 0; | |
} | |
return 2; | |
} | |
void* CFX_LinuxFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact) | |
{ | |
CFX_ByteString face = cstr_face; | |
int iBaseFont; | |
for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) | |
if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { | |
face = Base14Substs[iBaseFont].m_pSubstName; | |
bExact = TRUE; | |
break; | |
} | |
if (iBaseFont < 12) { | |
return GetFont(face); | |
} | |
FX_LPVOID p = NULL; | |
FX_BOOL bCJK = TRUE; | |
switch (charset) { | |
case FXFONT_SHIFTJIS_CHARSET: { | |
FX_INT32 index = GetJapanesePreference(cstr_face, weight, pitch_family); | |
if (index < 0) { | |
break; | |
} | |
for (FX_INT32 i = 0; i < LINUX_GPNAMESIZE; i++) | |
if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) { | |
return p; | |
} | |
} | |
break; | |
case FXFONT_GB2312_CHARSET: { | |
static FX_INT32 s_gbCount = sizeof(g_LinuxGbFontList) / sizeof(FX_LPCSTR); | |
for (FX_INT32 i = 0; i < s_gbCount; i++) | |
if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) { | |
return p; | |
} | |
} | |
break; | |
case FXFONT_CHINESEBIG5_CHARSET: { | |
static FX_INT32 s_b5Count = sizeof(g_LinuxB5FontList) / sizeof(FX_LPCSTR); | |
for (FX_INT32 i = 0; i < s_b5Count; i++) | |
if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) { | |
return p; | |
} | |
} | |
break; | |
case FXFONT_HANGEUL_CHARSET: { | |
static FX_INT32 s_hgCount = sizeof(g_LinuxHGFontList) / sizeof(FX_LPCSTR); | |
for (FX_INT32 i = 0; i < s_hgCount; i++) | |
if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) { | |
return p; | |
} | |
} | |
break; | |
default: | |
bCJK = FALSE; | |
break; | |
} | |
if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { | |
return GetFont("Courier New"); | |
} | |
return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK); | |
} | |
static FX_DWORD _LinuxGetCharset(int charset) | |
{ | |
switch(charset) { | |
case FXFONT_SHIFTJIS_CHARSET: | |
return CHARSET_FLAG_SHIFTJIS; | |
case FXFONT_GB2312_CHARSET: | |
return CHARSET_FLAG_GB; | |
case FXFONT_CHINESEBIG5_CHARSET: | |
return CHARSET_FLAG_BIG5; | |
case FXFONT_HANGEUL_CHARSET: | |
return CHARSET_FLAG_KOREAN; | |
case FXFONT_SYMBOL_CHARSET: | |
return CHARSET_FLAG_SYMBOL; | |
case FXFONT_ANSI_CHARSET: | |
return CHARSET_FLAG_ANSI; | |
default: | |
break; | |
} | |
return 0; | |
} | |
static FX_INT32 _LinuxGetSimilarValue(int weight, FX_BOOL bItalic, int pitch_family, FX_DWORD style) | |
{ | |
FX_INT32 iSimilarValue = 0; | |
if ((style & FXFONT_BOLD) == (weight > 400)) { | |
iSimilarValue += 16; | |
} | |
if ((style & FXFONT_ITALIC) == bItalic) { | |
iSimilarValue += 16; | |
} | |
if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { | |
iSimilarValue += 16; | |
} | |
if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { | |
iSimilarValue += 8; | |
} | |
if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { | |
iSimilarValue += 8; | |
} | |
return iSimilarValue; | |
} | |
void* CFX_LinuxFontInfo::FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName) | |
{ | |
CFontFaceInfo* pFind = NULL; | |
FX_DWORD charset_flag = _LinuxGetCharset(charset); | |
FX_INT32 iBestSimilar = 0; | |
FX_POSITION pos = m_FontList.GetStartPosition(); | |
while (pos) { | |
CFX_ByteString bsName; | |
CFontFaceInfo* pFont = NULL; | |
m_FontList.GetNextAssoc(pos, bsName, (FX_LPVOID&)pFont); | |
if (!(pFont->m_Charsets & charset_flag) && charset != FXFONT_DEFAULT_CHARSET) { | |
continue; | |
} | |
FX_INT32 iSimilarValue = 0; | |
FX_INT32 index = bsName.Find(family); | |
if (bMatchName && index < 0) { | |
continue; | |
} | |
if (!bMatchName && index > 0) { | |
iSimilarValue += 64; | |
} | |
iSimilarValue = _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); | |
if (iSimilarValue > iBestSimilar) { | |
iBestSimilar = iSimilarValue; | |
pFind = pFont; | |
} | |
} | |
return pFind; | |
} | |
IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() | |
{ | |
CFX_LinuxFontInfo* pInfo = FX_NEW CFX_LinuxFontInfo; | |
if (!pInfo) { | |
return NULL; | |
} | |
if (!pInfo->ParseFontCfg()) { | |
pInfo->AddPath("/usr/share/fonts"); | |
pInfo->AddPath("/usr/share/X11/fonts/Type1"); | |
pInfo->AddPath("/usr/share/X11/fonts/TTF"); | |
pInfo->AddPath("/usr/local/share/fonts"); | |
} | |
return pInfo; | |
} | |
FX_BOOL CFX_LinuxFontInfo::ParseFontCfg() | |
{ | |
return FALSE; | |
} | |
void CFX_GEModule::InitPlatform() | |
{ | |
m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); | |
} | |
void CFX_GEModule::DestroyPlatform() | |
{ | |
} | |
#endif |