| Index: core/fpdfapi/fpdf_font/cpdf_type3font.cpp
|
| diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.cpp b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..91a03a9830e3f09a6411b64565771200728e70ac
|
| --- /dev/null
|
| +++ b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp
|
| @@ -0,0 +1,162 @@
|
| +// Copyright 2016 PDFium Authors. All rights reserved.
|
| +// 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/fpdf_font/cpdf_type3font.h"
|
| +
|
| +#include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
|
| +#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
|
| +#include "core/fpdfapi/fpdf_page/pageint.h"
|
| +#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
|
| +#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
|
| +#include "core/fxcrt/include/fx_system.h"
|
| +#include "third_party/base/stl_util.h"
|
| +
|
| +CPDF_Type3Font::CPDF_Type3Font()
|
| + : m_pCharProcs(nullptr),
|
| + m_pPageResources(nullptr),
|
| + m_pFontResources(nullptr) {
|
| + FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
|
| +}
|
| +
|
| +CPDF_Type3Font::~CPDF_Type3Font() {
|
| + for (auto it : m_CacheMap)
|
| + delete it.second;
|
| +}
|
| +
|
| +bool CPDF_Type3Font::IsType3Font() const {
|
| + return true;
|
| +}
|
| +
|
| +const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
|
| + return this;
|
| +}
|
| +
|
| +CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
|
| + return this;
|
| +}
|
| +
|
| +FX_BOOL CPDF_Type3Font::Load() {
|
| + m_pFontResources = m_pFontDict->GetDictBy("Resources");
|
| + CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("FontMatrix");
|
| + FX_FLOAT xscale = 1.0f, yscale = 1.0f;
|
| + if (pMatrix) {
|
| + m_FontMatrix = pMatrix->GetMatrix();
|
| + xscale = m_FontMatrix.a;
|
| + yscale = m_FontMatrix.d;
|
| + }
|
| + CPDF_Array* pBBox = m_pFontDict->GetArrayBy("FontBBox");
|
| + if (pBBox) {
|
| + m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000);
|
| + m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000);
|
| + m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000);
|
| + m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000);
|
| + }
|
| + int StartChar = m_pFontDict->GetIntegerBy("FirstChar");
|
| + CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
|
| + if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
|
| + FX_DWORD count = pWidthArray->GetCount();
|
| + if (count > 256) {
|
| + count = 256;
|
| + }
|
| + if (StartChar + count > 256) {
|
| + count = 256 - StartChar;
|
| + }
|
| + for (FX_DWORD i = 0; i < count; i++) {
|
| + m_CharWidthL[StartChar + i] =
|
| + FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
|
| + }
|
| + }
|
| + m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
|
| + CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
|
| + if (pEncoding) {
|
| + LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
|
| + if (m_pCharNames) {
|
| + for (int i = 0; i < 256; i++) {
|
| + m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
|
| + if (m_Encoding.m_Unicodes[i] == 0) {
|
| + m_Encoding.m_Unicodes[i] = i;
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return TRUE;
|
| +}
|
| +
|
| +void CPDF_Type3Font::CheckType3FontMetrics() {
|
| + CheckFontMetrics();
|
| +}
|
| +
|
| +CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) {
|
| + if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
|
| + return nullptr;
|
| +
|
| + auto it = m_CacheMap.find(charcode);
|
| + if (it != m_CacheMap.end())
|
| + return it->second;
|
| +
|
| + const FX_CHAR* name =
|
| + GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
|
| + if (!name)
|
| + return nullptr;
|
| +
|
| + CPDF_Stream* pStream =
|
| + ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
|
| + if (!pStream)
|
| + return nullptr;
|
| +
|
| + std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
|
| + m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
|
| + pStream, nullptr)));
|
| +
|
| + // This can trigger recursion into this method. The content of |m_CacheMap|
|
| + // can change as a result. Thus after it returns, check the cache again for
|
| + // a cache hit.
|
| + pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
|
| + level + 1);
|
| + it = m_CacheMap.find(charcode);
|
| + if (it != m_CacheMap.end())
|
| + return it->second;
|
| +
|
| + FX_FLOAT scale = m_FontMatrix.GetXUnit();
|
| + pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
|
| + FX_RECT& rcBBox = pNewChar->m_BBox;
|
| + CFX_FloatRect char_rect(
|
| + (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
|
| + (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
|
| + if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
|
| + char_rect = pNewChar->m_pForm->CalcBoundingBox();
|
| +
|
| + char_rect.Transform(&m_FontMatrix);
|
| + rcBBox.left = FXSYS_round(char_rect.left * 1000);
|
| + rcBBox.right = FXSYS_round(char_rect.right * 1000);
|
| + rcBBox.top = FXSYS_round(char_rect.top * 1000);
|
| + rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
|
| +
|
| + ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
|
| + CPDF_Type3Char* pCachedChar = pNewChar.release();
|
| + m_CacheMap[charcode] = pCachedChar;
|
| + if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
|
| + delete pCachedChar->m_pForm;
|
| + pCachedChar->m_pForm = nullptr;
|
| + }
|
| + return pCachedChar;
|
| +}
|
| +
|
| +int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
|
| + if (charcode >= FX_ArraySize(m_CharWidthL))
|
| + charcode = 0;
|
| +
|
| + if (m_CharWidthL[charcode])
|
| + return m_CharWidthL[charcode];
|
| +
|
| + const CPDF_Type3Char* pChar = LoadChar(charcode, level);
|
| + return pChar ? pChar->m_Width : 0;
|
| +}
|
| +
|
| +FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) {
|
| + const CPDF_Type3Char* pChar = LoadChar(charcode, level);
|
| + return pChar ? pChar->m_BBox : FX_RECT();
|
| +}
|
|
|