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/fxge/fx_ge.h" 8#include "../agg/include/fx_agg_driver.h" 9#include "text_int.h" 10#if !defined(_FPDFAPI_MINI_) && _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ 11#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_))) 12void CFX_AggDeviceDriver::InitPlatform() 13{ 14} 15void CFX_AggDeviceDriver::DestroyPlatform() 16{ 17} 18void CFX_FaceCache::InitPlatform() 19{ 20} 21FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont, 22 CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, 23 FX_FLOAT font_size, FX_DWORD argb) 24{ 25 return FALSE; 26} 27CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font* pFont, FX_DWORD glyph_index, const CFX_AffineMatrix* pMatrix, 28 int dest_width, int anti_alias) 29{ 30 return NULL; 31} 32void CFX_Font::ReleasePlatformResource() 33{ 34} 35#endif 36static const struct { 37 FX_LPCSTR m_pName; 38 FX_LPCSTR m_pSubstName; 39} 40Base14Substs[] = { 41 {"Courier", "Courier New"}, 42 {"Courier-Bold", "Courier New Bold"}, 43 {"Courier-BoldOblique", "Courier New Bold Italic"}, 44 {"Courier-Oblique", "Courier New Italic"}, 45 {"Helvetica", "Arial"}, 46 {"Helvetica-Bold", "Arial Bold"}, 47 {"Helvetica-BoldOblique", "Arial Bold Italic"}, 48 {"Helvetica-Oblique", "Arial Italic"}, 49 {"Times-Roman", "Times New Roman"}, 50 {"Times-Bold", "Times New Roman Bold"}, 51 {"Times-BoldItalic", "Times New Roman Bold Italic"}, 52 {"Times-Italic", "Times New Roman Italic"}, 53}; 54class CFX_LinuxFontInfo : public CFX_FolderFontInfo 55{ 56public: 57 virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact); 58 FX_BOOL ParseFontCfg(); 59 void* FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName); 60}; 61#define LINUX_GPNAMESIZE 6 62static const struct { 63 FX_LPCSTR NameArr[LINUX_GPNAMESIZE]; 64} 65LinuxGpFontList[] = { 66 {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", "VL Gothic regular"}}, 67 {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, "VL Gothic regular"}}, 68 {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}}, 69 {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}}, 70}; 71static const FX_LPCSTR g_LinuxGbFontList[] = { 72 "AR PL UMing CN Light", 73 "WenQuanYi Micro Hei", 74 "AR PL UKai CN", 75}; 76static const FX_LPCSTR g_LinuxB5FontList[] = { 77 "AR PL UMing TW Light", 78 "WenQuanYi Micro Hei", 79 "AR PL UKai TW", 80}; 81static const FX_LPCSTR g_LinuxHGFontList[] = { 82 "UnDotum", 83}; 84static FX_INT32 GetJapanesePreference(FX_LPCSTR facearr, int weight, int picth_family) 85{ 86 CFX_ByteString face = facearr; 87 if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { 88 if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) { 89 return 0; 90 } else { 91 return 1; 92 } 93 } else if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) { 94 if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) { 95 return 2; 96 } else { 97 return 3; 98 } 99 } 100 if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) { 101 return 0; 102 } 103 return 2; 104} 105void* CFX_LinuxFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact) 106{ 107 CFX_ByteString face = cstr_face; 108 int iBaseFont; 109 for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) 110 if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { 111 face = Base14Substs[iBaseFont].m_pSubstName; 112 bExact = TRUE; 113 break; 114 } 115 if (iBaseFont < 12) { 116 return GetFont(face); 117 } 118 FX_LPVOID p = NULL; 119 FX_BOOL bCJK = TRUE; 120 switch (charset) { 121 case FXFONT_SHIFTJIS_CHARSET: { 122 FX_INT32 index = GetJapanesePreference(cstr_face, weight, pitch_family); 123 if (index < 0) { 124 break; 125 } 126 for (FX_INT32 i = 0; i < LINUX_GPNAMESIZE; i++) 127 if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) { 128 return p; 129 } 130 } 131 break; 132 case FXFONT_GB2312_CHARSET: { 133 static FX_INT32 s_gbCount = sizeof(g_LinuxGbFontList) / sizeof(FX_LPCSTR); 134 for (FX_INT32 i = 0; i < s_gbCount; i++) 135 if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) { 136 return p; 137 } 138 } 139 break; 140 case FXFONT_CHINESEBIG5_CHARSET: { 141 static FX_INT32 s_b5Count = sizeof(g_LinuxB5FontList) / sizeof(FX_LPCSTR); 142 for (FX_INT32 i = 0; i < s_b5Count; i++) 143 if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) { 144 return p; 145 } 146 } 147 break; 148 case FXFONT_HANGEUL_CHARSET: { 149 static FX_INT32 s_hgCount = sizeof(g_LinuxHGFontList) / sizeof(FX_LPCSTR); 150 for (FX_INT32 i = 0; i < s_hgCount; i++) 151 if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) { 152 return p; 153 } 154 } 155 break; 156 default: 157 bCJK = FALSE; 158 break; 159 } 160 if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) { 161 return GetFont("Courier New"); 162 } 163 return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK); 164} 165static FX_DWORD _LinuxGetCharset(int charset) 166{ 167 switch(charset) { 168 case FXFONT_SHIFTJIS_CHARSET: 169 return CHARSET_FLAG_SHIFTJIS; 170 case FXFONT_GB2312_CHARSET: 171 return CHARSET_FLAG_GB; 172 case FXFONT_CHINESEBIG5_CHARSET: 173 return CHARSET_FLAG_BIG5; 174 case FXFONT_HANGEUL_CHARSET: 175 return CHARSET_FLAG_KOREAN; 176 case FXFONT_SYMBOL_CHARSET: 177 return CHARSET_FLAG_SYMBOL; 178 case FXFONT_ANSI_CHARSET: 179 return CHARSET_FLAG_ANSI; 180 default: 181 break; 182 } 183 return 0; 184} 185static FX_INT32 _LinuxGetSimilarValue(int weight, FX_BOOL bItalic, int pitch_family, FX_DWORD style) 186{ 187 FX_INT32 iSimilarValue = 0; 188 if ((style & FXFONT_BOLD) == (weight > 400)) { 189 iSimilarValue += 16; 190 } 191 if ((style & FXFONT_ITALIC) == bItalic) { 192 iSimilarValue += 16; 193 } 194 if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) { 195 iSimilarValue += 16; 196 } 197 if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) { 198 iSimilarValue += 8; 199 } 200 if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) { 201 iSimilarValue += 8; 202 } 203 return iSimilarValue; 204} 205void* CFX_LinuxFontInfo::FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName) 206{ 207 CFontFaceInfo* pFind = NULL; 208 FX_DWORD charset_flag = _LinuxGetCharset(charset); 209 FX_INT32 iBestSimilar = 0; 210 FX_POSITION pos = m_FontList.GetStartPosition(); 211 while (pos) { 212 CFX_ByteString bsName; 213 CFontFaceInfo* pFont = NULL; 214 m_FontList.GetNextAssoc(pos, bsName, (FX_LPVOID&)pFont); 215 if (!(pFont->m_Charsets & charset_flag) && charset != FXFONT_DEFAULT_CHARSET) { 216 continue; 217 } 218 FX_INT32 iSimilarValue = 0; 219 FX_INT32 index = bsName.Find(family); 220 if (bMatchName && index < 0) { 221 continue; 222 } 223 if (!bMatchName && index > 0) { 224 iSimilarValue += 64; 225 } 226 iSimilarValue = _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles); 227 if (iSimilarValue > iBestSimilar) { 228 iBestSimilar = iSimilarValue; 229 pFind = pFont; 230 } 231 } 232 return pFind; 233} 234IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() 235{ 236 CFX_LinuxFontInfo* pInfo = FX_NEW CFX_LinuxFontInfo; 237 if (!pInfo) { 238 return NULL; 239 } 240 if (!pInfo->ParseFontCfg()) { 241 pInfo->AddPath("/usr/share/fonts"); 242 pInfo->AddPath("/usr/share/X11/fonts/Type1"); 243 pInfo->AddPath("/usr/share/X11/fonts/TTF"); 244 pInfo->AddPath("/usr/local/share/fonts"); 245 } 246 return pInfo; 247} 248FX_BOOL CFX_LinuxFontInfo::ParseFontCfg() 249{ 250 return FALSE; 251} 252void CFX_GEModule::InitPlatform() 253{ 254 m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); 255} 256void CFX_GEModule::DestroyPlatform() 257{ 258} 259#endif 260