1 // Copyright 2016 The PDFium Authors
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/fxge/cfx_font.h"
12 #include "core/fxge/freetype/fx_freetype.h"
13 #include "core/fxge/fx_font.h"
14 #include "core/fxge/fx_fontencoding.h"
15
16 namespace {
17
18 constexpr fxge::FontEncoding kEncodingIDs[] = {
19 fxge::FontEncoding::kSymbol, fxge::FontEncoding::kUnicode,
20 fxge::FontEncoding::kSjis, fxge::FontEncoding::kGB2312,
21 fxge::FontEncoding::kBig5, fxge::FontEncoding::kWansung,
22 fxge::FontEncoding::kJohab, fxge::FontEncoding::kAdobeStandard,
23 fxge::FontEncoding::kAdobeExpert, fxge::FontEncoding::kAdobeCustom,
24 fxge::FontEncoding::kLatin1, fxge::FontEncoding::kOldLatin2,
25 fxge::FontEncoding::kAppleRoman,
26 };
27
FXFM_CreateFontEncoding(CFX_Font * pFont,fxge::FontEncoding encoding_id)28 std::unique_ptr<CFX_UnicodeEncodingEx> FXFM_CreateFontEncoding(
29 CFX_Font* pFont,
30 fxge::FontEncoding encoding_id) {
31 if (!pFont->GetFace()->SelectCharMap(encoding_id)) {
32 return nullptr;
33 }
34 return std::make_unique<CFX_UnicodeEncodingEx>(pFont, encoding_id);
35 }
36
37 } // namespace
38
CFX_UnicodeEncodingEx(CFX_Font * pFont,fxge::FontEncoding encoding_id)39 CFX_UnicodeEncodingEx::CFX_UnicodeEncodingEx(CFX_Font* pFont,
40 fxge::FontEncoding encoding_id)
41 : CFX_UnicodeEncoding(pFont), encoding_id_(encoding_id) {}
42
43 CFX_UnicodeEncodingEx::~CFX_UnicodeEncodingEx() = default;
44
GlyphFromCharCode(uint32_t charcode)45 uint32_t CFX_UnicodeEncodingEx::GlyphFromCharCode(uint32_t charcode) {
46 RetainPtr<CFX_Face> face = m_pFont->GetFace();
47 FT_UInt nIndex = face->GetCharIndex(charcode);
48 if (nIndex > 0)
49 return nIndex;
50
51 size_t map_index = 0;
52 while (map_index < face->GetCharMapCount()) {
53 fxge::FontEncoding encoding_id =
54 face->GetCharMapEncodingByIndex(map_index++);
55 if (encoding_id_ == encoding_id) {
56 continue;
57 }
58 if (!face->SelectCharMap(encoding_id)) {
59 continue;
60 }
61 nIndex = face->GetCharIndex(charcode);
62 if (nIndex > 0) {
63 encoding_id_ = encoding_id;
64 return nIndex;
65 }
66 }
67 face->SelectCharMap(encoding_id_);
68 return 0;
69 }
70
CharCodeFromUnicode(wchar_t Unicode) const71 uint32_t CFX_UnicodeEncodingEx::CharCodeFromUnicode(wchar_t Unicode) const {
72 if (encoding_id_ == fxge::FontEncoding::kUnicode ||
73 encoding_id_ == fxge::FontEncoding::kSymbol) {
74 return Unicode;
75 }
76 RetainPtr<CFX_Face> face = m_pFont->GetFace();
77 for (size_t i = 0; i < face->GetCharMapCount(); i++) {
78 fxge::FontEncoding encoding_id = face->GetCharMapEncodingByIndex(i);
79 if (encoding_id == fxge::FontEncoding::kUnicode ||
80 encoding_id == fxge::FontEncoding::kSymbol) {
81 return Unicode;
82 }
83 }
84 return kInvalidCharCode;
85 }
86
FX_CreateFontEncodingEx(CFX_Font * pFont)87 std::unique_ptr<CFX_UnicodeEncodingEx> FX_CreateFontEncodingEx(
88 CFX_Font* pFont) {
89 if (!pFont || !pFont->GetFace()) {
90 return nullptr;
91 }
92
93 for (fxge::FontEncoding id : kEncodingIDs) {
94 auto pFontEncoding = FXFM_CreateFontEncoding(pFont, id);
95 if (pFontEncoding)
96 return pFontEncoding;
97 }
98 return nullptr;
99 }
100