Home | History | Annotate | Download | only in fxge
      1 // Copyright 2016 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 "core/fxge/cfx_unicodeencodingex.h"
      8 
      9 #include <memory>
     10 
     11 #include "core/fpdfapi/font/cpdf_font.h"
     12 #include "core/fxge/fx_font.h"
     13 #include "core/fxge/fx_freetype.h"
     14 #include "third_party/base/ptr_util.h"
     15 
     16 namespace {
     17 
     18 const uint32_t g_EncodingID[] = {
     19     FXFM_ENCODING_MS_SYMBOL,     FXFM_ENCODING_UNICODE,
     20     FXFM_ENCODING_MS_SJIS,       FXFM_ENCODING_MS_GB2312,
     21     FXFM_ENCODING_MS_BIG5,       FXFM_ENCODING_MS_WANSUNG,
     22     FXFM_ENCODING_MS_JOHAB,      FXFM_ENCODING_ADOBE_STANDARD,
     23     FXFM_ENCODING_ADOBE_EXPERT,  FXFM_ENCODING_ADOBE_CUSTOM,
     24     FXFM_ENCODING_ADOBE_LATIN_1, FXFM_ENCODING_OLD_LATIN_2,
     25     FXFM_ENCODING_APPLE_ROMAN,
     26 };
     27 
     28 std::unique_ptr<CFX_UnicodeEncodingEx> FXFM_CreateFontEncoding(
     29     CFX_Font* pFont,
     30     uint32_t nEncodingID) {
     31   if (FXFT_Select_Charmap(pFont->GetFace(), nEncodingID))
     32     return nullptr;
     33   return pdfium::MakeUnique<CFX_UnicodeEncodingEx>(pFont, nEncodingID);
     34 }
     35 
     36 }  // namespace
     37 
     38 CFX_UnicodeEncodingEx::CFX_UnicodeEncodingEx(CFX_Font* pFont,
     39                                              uint32_t EncodingID)
     40     : CFX_UnicodeEncoding(pFont), m_nEncodingID(EncodingID) {}
     41 
     42 CFX_UnicodeEncodingEx::~CFX_UnicodeEncodingEx() {}
     43 
     44 uint32_t CFX_UnicodeEncodingEx::GlyphFromCharCode(uint32_t charcode) {
     45   FXFT_Face face = m_pFont->GetFace();
     46   FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode);
     47   if (nIndex > 0)
     48     return nIndex;
     49   int nmaps = FXFT_Get_Face_CharmapCount(face);
     50   int m = 0;
     51   while (m < nmaps) {
     52     uint32_t nEncodingID =
     53         FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]);
     54     if (m_nEncodingID == nEncodingID)
     55       continue;
     56     int error = FXFT_Select_Charmap(face, nEncodingID);
     57     if (error)
     58       continue;
     59     nIndex = FXFT_Get_Char_Index(face, charcode);
     60     if (nIndex > 0) {
     61       m_nEncodingID = nEncodingID;
     62       return nIndex;
     63     }
     64   }
     65   FXFT_Select_Charmap(face, m_nEncodingID);
     66   return 0;
     67 }
     68 
     69 uint32_t CFX_UnicodeEncodingEx::CharCodeFromUnicode(wchar_t Unicode) const {
     70   if (m_nEncodingID == FXFM_ENCODING_UNICODE ||
     71       m_nEncodingID == FXFM_ENCODING_MS_SYMBOL) {
     72     return Unicode;
     73   }
     74   FXFT_Face face = m_pFont->GetFace();
     75   int nmaps = FXFT_Get_Face_CharmapCount(face);
     76   for (int i = 0; i < nmaps; i++) {
     77     int nEncodingID =
     78         FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]);
     79     if (nEncodingID == FXFM_ENCODING_UNICODE ||
     80         nEncodingID == FXFM_ENCODING_MS_SYMBOL) {
     81       return Unicode;
     82     }
     83   }
     84   return CPDF_Font::kInvalidCharCode;
     85 }
     86 
     87 std::unique_ptr<CFX_UnicodeEncodingEx> FX_CreateFontEncodingEx(
     88     CFX_Font* pFont,
     89     uint32_t nEncodingID) {
     90   if (!pFont || !pFont->GetFace())
     91     return nullptr;
     92 
     93   if (nEncodingID != FXFM_ENCODING_NONE)
     94     return FXFM_CreateFontEncoding(pFont, nEncodingID);
     95 
     96   for (uint32_t id : g_EncodingID) {
     97     auto pFontEncoding = FXFM_CreateFontEncoding(pFont, id);
     98     if (pFontEncoding)
     99       return pFontEncoding;
    100   }
    101   return nullptr;
    102 }
    103