| // 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/fpdfapi/font/cpdf_simplefont.h" |
| |
| #include <utility> |
| #include <vector> |
| |
| #include "constants/font_encodings.h" |
| #include "core/fpdfapi/parser/cpdf_array.h" |
| #include "core/fpdfapi/parser/cpdf_dictionary.h" |
| #include "core/fpdfapi/parser/cpdf_name.h" |
| #include "core/fxge/fx_font.h" |
| |
| namespace { |
| |
| void GetPredefinedEncoding(const ByteString& value, FontEncoding* basemap) { |
| if (value == pdfium::font_encodings::kWinAnsiEncoding) { |
| *basemap = FontEncoding::kWinAnsi; |
| } else if (value == pdfium::font_encodings::kMacRomanEncoding) { |
| *basemap = FontEncoding::kMacRoman; |
| } else if (value == pdfium::font_encodings::kMacExpertEncoding) { |
| *basemap = FontEncoding::kMacExpert; |
| } else if (value == pdfium::font_encodings::kPDFDocEncoding) { |
| *basemap = FontEncoding::kPdfDoc; |
| } |
| } |
| |
| } // namespace |
| |
| CPDF_SimpleFont::CPDF_SimpleFont(CPDF_Document* document, |
| RetainPtr<CPDF_Dictionary> font_dict) |
| : CPDF_Font(document, std::move(font_dict)) {} |
| |
| CPDF_SimpleFont::~CPDF_SimpleFont() = default; |
| |
| void CPDF_SimpleFont::LoadDifferences(const CPDF_Dictionary* encoding) { |
| RetainPtr<const CPDF_Array> diffs = encoding->GetArrayFor("Differences"); |
| if (!diffs) { |
| return; |
| } |
| |
| char_names_.resize(kInternalTableSize); |
| uint32_t cur_code = 0; |
| for (uint32_t i = 0; i < diffs->size(); i++) { |
| RetainPtr<const CPDF_Object> element = diffs->GetDirectObjectAt(i); |
| if (!element) { |
| continue; |
| } |
| |
| const CPDF_Name* name = element->AsName(); |
| if (name) { |
| if (cur_code < char_names_.size()) { |
| char_names_[cur_code] = name->GetString(); |
| } |
| cur_code++; |
| } else { |
| cur_code = element->GetInteger(); |
| } |
| } |
| } |
| |
| void CPDF_SimpleFont::LoadPDFEncoding(bool bEmbedded, bool bTrueType) { |
| RetainPtr<const CPDF_Object> pEncoding = |
| font_dict_->GetDirectObjectFor("Encoding"); |
| if (!pEncoding) { |
| if (base_font_name_ == "Symbol") { |
| base_encoding_ = |
| bTrueType ? FontEncoding::kMsSymbol : FontEncoding::kAdobeSymbol; |
| } else if (!bEmbedded && base_encoding_ == FontEncoding::kBuiltin) { |
| base_encoding_ = FontEncoding::kWinAnsi; |
| } |
| return; |
| } |
| if (pEncoding->IsName()) { |
| if (base_encoding_ == FontEncoding::kAdobeSymbol || |
| base_encoding_ == FontEncoding::kZapfDingbats) { |
| return; |
| } |
| if (FontStyleIsSymbolic(flags_) && base_font_name_ == "Symbol") { |
| if (!bTrueType) { |
| base_encoding_ = FontEncoding::kAdobeSymbol; |
| } |
| return; |
| } |
| ByteString bsEncoding = pEncoding->GetString(); |
| if (bsEncoding == pdfium::font_encodings::kMacExpertEncoding) { |
| bsEncoding = pdfium::font_encodings::kWinAnsiEncoding; |
| } |
| GetPredefinedEncoding(bsEncoding, &base_encoding_); |
| return; |
| } |
| |
| const CPDF_Dictionary* dict = pEncoding->AsDictionary(); |
| if (!dict) { |
| return; |
| } |
| |
| if (base_encoding_ != FontEncoding::kAdobeSymbol && |
| base_encoding_ != FontEncoding::kZapfDingbats) { |
| ByteString bsEncoding = dict->GetByteStringFor("BaseEncoding"); |
| if (bTrueType && bsEncoding == pdfium::font_encodings::kMacExpertEncoding) { |
| bsEncoding = pdfium::font_encodings::kWinAnsiEncoding; |
| } |
| GetPredefinedEncoding(bsEncoding, &base_encoding_); |
| } |
| if ((!bEmbedded || bTrueType) && base_encoding_ == FontEncoding::kBuiltin) { |
| base_encoding_ = FontEncoding::kStandard; |
| } |
| |
| LoadDifferences(dict); |
| } |
| |
| bool CPDF_SimpleFont::IsUnicodeCompatible() const { |
| return base_encoding_ != FontEncoding::kBuiltin && |
| base_encoding_ != FontEncoding::kAdobeSymbol && |
| base_encoding_ != FontEncoding::kZapfDingbats; |
| } |
| |
| WideString CPDF_SimpleFont::UnicodeFromCharCode(uint32_t charcode) const { |
| WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode); |
| if (!unicode.IsEmpty()) { |
| return unicode; |
| } |
| wchar_t ret = encoding_.UnicodeFromCharCode((uint8_t)charcode); |
| if (ret == 0) { |
| return WideString(); |
| } |
| return WideString(ret); |
| } |
| |
| uint32_t CPDF_SimpleFont::CharCodeFromUnicode(wchar_t unicode) const { |
| uint32_t ret = CPDF_Font::CharCodeFromUnicode(unicode); |
| if (ret) { |
| return ret; |
| } |
| return encoding_.CharCodeFromUnicode(unicode); |
| } |
| |
| int CPDF_SimpleFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { |
| if (pVertGlyph) { |
| *pVertGlyph = false; |
| } |
| return -1; |
| } |