From 61b2fc718910a5ab2a75ec5026b239ff33bccfdc Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Wed, 23 Mar 2016 19:21:44 -0400 Subject: Split core/include/fpdfapi/fpdf_resource.h This CL splits apart the core/include/fpdfapi/fpdf_resource.h file and places the classes into individual files. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1824033002 . --- core/fpdfapi/fpdf_font/cpdf_type3font.cpp | 162 ++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 core/fpdfapi/fpdf_font/cpdf_type3font.cpp (limited to '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 0000000000..91a03a9830 --- /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 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(); +} -- cgit v1.2.3