blob: fd7cbf31939664baa0a9483559069b3eada89d67 [file] [log] [blame]
// Copyright 2016 The PDFium Authors
// 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 "core/fxge/cfx_charmap_resolver.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxge/cfx_face.h"
#include "core/fxge/cfx_font.h"
#include "core/fxge/cfx_substfont.h"
#include "core/fxge/fx_font.h"
#include "core/fxge/fx_fontencoding.h"
namespace {
class UnicodeCharmapResolver : public CFX_CharmapResolver {
public:
explicit UnicodeCharmapResolver(const CFX_Font* font)
: CFX_CharmapResolver(font) {}
~UnicodeCharmapResolver() override = default;
uint32_t GlyphFromCharCode(uint32_t charcode) override {
RetainPtr<CFX_Face> face = font_->GetFace();
if (!face) {
return charcode;
}
if (face->SelectCharMap(fxge::FontEncoding::kUnicode)) {
return face->GetCharIndex(charcode);
}
if (font_->GetSubstFont() &&
font_->GetSubstFont()->charset_ == FX_Charset::kSymbol) {
uint32_t index = 0;
if (face->SelectCharMap(fxge::FontEncoding::kSymbol)) {
index = face->GetCharIndex(charcode);
}
if (!index && face->SelectCharMap(fxge::FontEncoding::kAppleRoman)) {
return face->GetCharIndex(charcode);
}
}
return charcode;
}
};
#if defined(PDF_ENABLE_XFA)
constexpr fxge::FontEncoding kEncodingIDs[] = {
fxge::FontEncoding::kSymbol, fxge::FontEncoding::kUnicode,
fxge::FontEncoding::kSjis, fxge::FontEncoding::kGB2312,
fxge::FontEncoding::kBig5, fxge::FontEncoding::kWansung,
fxge::FontEncoding::kJohab, fxge::FontEncoding::kAdobeStandard,
fxge::FontEncoding::kAdobeExpert, fxge::FontEncoding::kAdobeCustom,
fxge::FontEncoding::kLatin1, fxge::FontEncoding::kOldLatin2,
fxge::FontEncoding::kAppleRoman,
};
class AlternateCharmapResolver : public CFX_CharmapResolver {
public:
AlternateCharmapResolver(const CFX_Font* font, fxge::FontEncoding encoding_id)
: CFX_CharmapResolver(font), encoding_id_(encoding_id) {}
~AlternateCharmapResolver() override = default;
uint32_t GlyphFromCharCode(uint32_t charcode) override {
RetainPtr<CFX_Face> face = font_->GetFace();
uint32_t char_index = face->GetCharIndex(charcode);
if (char_index > 0) {
return char_index;
}
size_t map_index = 0;
while (map_index < face->GetCharMapCount()) {
fxge::FontEncoding encoding_id =
face->GetCharMapEncodingByIndex(map_index++);
if (encoding_id_ == encoding_id) {
continue;
}
if (!face->SelectCharMap(encoding_id)) {
continue;
}
char_index = face->GetCharIndex(charcode);
if (char_index > 0) {
encoding_id_ = encoding_id;
return char_index;
}
}
face->SelectCharMap(encoding_id_);
return 0;
}
private:
fxge::FontEncoding encoding_id_;
};
#endif // defined(PDF_ENABLE_XFA)
} // namespace
CFX_CharmapResolver::CFX_CharmapResolver(const CFX_Font* font) : font_(font) {}
CFX_CharmapResolver::~CFX_CharmapResolver() = default;
// static
std::unique_ptr<CFX_CharmapResolver> CFX_CharmapResolver::CreateUnicode(
const CFX_Font* font) {
return std::make_unique<UnicodeCharmapResolver>(font);
}
#if defined(PDF_ENABLE_XFA)
std::unique_ptr<CFX_CharmapResolver> CFX_CharmapResolver::CreateAlternate(
const CFX_Font* font) {
if (!font || !font->GetFace()) {
return nullptr;
}
for (fxge::FontEncoding id : kEncodingIDs) {
if (font->GetFace()->SelectCharMap(id)) {
return std::make_unique<AlternateCharmapResolver>(font, id);
}
}
return nullptr;
}
#endif // defined(PDF_ENABLE_XFA)