Home | History | Annotate | Download | only in ge
      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 <memory>
      8 
      9 #include "core/fxge/cfx_gemodule.h"
     10 #include "core/fxge/ge/cfx_folderfontinfo.h"
     11 #include "core/fxge/ifx_systemfontinfo.h"
     12 
     13 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
     14 namespace {
     15 
     16 const size_t kLinuxGpNameSize = 6;
     17 
     18 const FX_CHAR* const g_LinuxGpFontList[][kLinuxGpNameSize] = {
     19     {"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic",
     20      "VL Gothic regular"},
     21     {"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", nullptr,
     22      "VL Gothic regular"},
     23     {"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", nullptr,
     24      "VL Gothic regular"},
     25     {"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", nullptr,
     26      "VL Gothic regular"},
     27 };
     28 
     29 const FX_CHAR* const g_LinuxGbFontList[] = {
     30     "AR PL UMing CN Light", "WenQuanYi Micro Hei", "AR PL UKai CN",
     31 };
     32 
     33 const FX_CHAR* const g_LinuxB5FontList[] = {
     34     "AR PL UMing TW Light", "WenQuanYi Micro Hei", "AR PL UKai TW",
     35 };
     36 
     37 const FX_CHAR* const g_LinuxHGFontList[] = {
     38     "UnDotum",
     39 };
     40 
     41 size_t GetJapanesePreference(const FX_CHAR* facearr,
     42                              int weight,
     43                              int pitch_family) {
     44   CFX_ByteString face = facearr;
     45   if (face.Find("Gothic") >= 0 ||
     46       face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
     47     if (face.Find("PGothic") >= 0 ||
     48         face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
     49       return 0;
     50     }
     51     return 1;
     52   }
     53   if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
     54     if (face.Find("PMincho") >= 0 ||
     55         face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
     56       return 2;
     57     }
     58     return 3;
     59   }
     60   if (!(pitch_family & FXFONT_FF_ROMAN) && weight > 400)
     61     return 0;
     62 
     63   return 2;
     64 }
     65 
     66 class CFX_LinuxFontInfo : public CFX_FolderFontInfo {
     67  public:
     68   CFX_LinuxFontInfo() {}
     69   ~CFX_LinuxFontInfo() override {}
     70 
     71   void* MapFont(int weight,
     72                 bool bItalic,
     73                 int charset,
     74                 int pitch_family,
     75                 const FX_CHAR* family,
     76                 int& iExact) override;
     77   bool ParseFontCfg(const char** pUserPaths);
     78 };
     79 
     80 void* CFX_LinuxFontInfo::MapFont(int weight,
     81                                  bool bItalic,
     82                                  int charset,
     83                                  int pitch_family,
     84                                  const FX_CHAR* cstr_face,
     85                                  int& iExact) {
     86   void* font = GetSubstFont(cstr_face);
     87   if (font) {
     88     iExact = 1;
     89     return font;
     90   }
     91   bool bCJK = true;
     92   switch (charset) {
     93     case FXFONT_SHIFTJIS_CHARSET: {
     94       size_t index = GetJapanesePreference(cstr_face, weight, pitch_family);
     95       ASSERT(index < FX_ArraySize(g_LinuxGpFontList));
     96       for (size_t i = 0; i < kLinuxGpNameSize; i++) {
     97         auto it = m_FontList.find(g_LinuxGpFontList[index][i]);
     98         if (it != m_FontList.end())
     99           return it->second;
    100       }
    101       break;
    102     }
    103     case FXFONT_GB2312_CHARSET: {
    104       for (size_t i = 0; i < FX_ArraySize(g_LinuxGbFontList); ++i) {
    105         auto it = m_FontList.find(g_LinuxGbFontList[i]);
    106         if (it != m_FontList.end())
    107           return it->second;
    108       }
    109       break;
    110     }
    111     case FXFONT_CHINESEBIG5_CHARSET: {
    112       for (size_t i = 0; i < FX_ArraySize(g_LinuxB5FontList); ++i) {
    113         auto it = m_FontList.find(g_LinuxB5FontList[i]);
    114         if (it != m_FontList.end())
    115           return it->second;
    116       }
    117       break;
    118     }
    119     case FXFONT_HANGUL_CHARSET: {
    120       for (size_t i = 0; i < FX_ArraySize(g_LinuxHGFontList); ++i) {
    121         auto it = m_FontList.find(g_LinuxHGFontList[i]);
    122         if (it != m_FontList.end())
    123           return it->second;
    124       }
    125       break;
    126     }
    127     default:
    128       bCJK = false;
    129       break;
    130   }
    131   return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK);
    132 }
    133 
    134 bool CFX_LinuxFontInfo::ParseFontCfg(const char** pUserPaths) {
    135   if (!pUserPaths)
    136     return false;
    137 
    138   for (const char** pPath = pUserPaths; *pPath; ++pPath)
    139     AddPath(*pPath);
    140   return true;
    141 }
    142 
    143 }  // namespace
    144 
    145 std::unique_ptr<IFX_SystemFontInfo> IFX_SystemFontInfo::CreateDefault(
    146     const char** pUserPaths) {
    147   CFX_LinuxFontInfo* pInfo = new CFX_LinuxFontInfo;
    148   if (!pInfo->ParseFontCfg(pUserPaths)) {
    149     pInfo->AddPath("/usr/share/fonts");
    150     pInfo->AddPath("/usr/share/X11/fonts/Type1");
    151     pInfo->AddPath("/usr/share/X11/fonts/TTF");
    152     pInfo->AddPath("/usr/local/share/fonts");
    153   }
    154   return std::unique_ptr<IFX_SystemFontInfo>(pInfo);
    155 }
    156 
    157 void CFX_GEModule::InitPlatform() {
    158   m_pFontMgr->SetSystemFontInfo(
    159       IFX_SystemFontInfo::CreateDefault(m_pUserFontPaths));
    160 }
    161 
    162 void CFX_GEModule::DestroyPlatform() {}
    163 #endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
    164