Home | History | Annotate | Download | only in font
      1 // Copyright 2016 PDFium Authors. All rights reserved.
      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/fpdfapi/font/cpdf_type3char.h"
      8 
      9 #include <utility>
     10 
     11 #include "core/fpdfapi/page/cpdf_form.h"
     12 #include "core/fpdfapi/page/cpdf_image.h"
     13 #include "core/fpdfapi/page/cpdf_imageobject.h"
     14 #include "core/fpdfapi/page/cpdf_pageobject.h"
     15 #include "core/fxge/dib/cfx_dibitmap.h"
     16 #include "core/fxge/fx_dib.h"
     17 
     18 namespace {
     19 
     20 constexpr float kTextUnitInGlyphUnit = 1000.0f;
     21 
     22 }  // namespace
     23 
     24 CPDF_Type3Char::CPDF_Type3Char(std::unique_ptr<CPDF_Form> pForm)
     25     : m_pForm(std::move(pForm)) {}
     26 
     27 CPDF_Type3Char::~CPDF_Type3Char() {}
     28 
     29 // static
     30 float CPDF_Type3Char::TextUnitToGlyphUnit(float fTextUnit) {
     31   return fTextUnit * kTextUnitInGlyphUnit;
     32 }
     33 
     34 // static
     35 void CPDF_Type3Char::TextUnitRectToGlyphUnitRect(CFX_FloatRect* pRect) {
     36   pRect->Scale(kTextUnitInGlyphUnit);
     37 }
     38 
     39 bool CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) {
     40   if (m_pBitmap || !m_pForm)
     41     return true;
     42 
     43   if (m_pForm->GetPageObjectList()->size() != 1 || m_bColored)
     44     return false;
     45 
     46   auto& pPageObj = m_pForm->GetPageObjectList()->front();
     47   if (!pPageObj->IsImage())
     48     return false;
     49 
     50   m_ImageMatrix = pPageObj->AsImage()->matrix();
     51   {
     52     // |pSource| actually gets assigned a CPDF_DIBSource, which has pointers
     53     // into objects owned by |m_pForm|. Make sure it is out of scope before
     54     // clearing the form.
     55     RetainPtr<CFX_DIBSource> pSource =
     56         pPageObj->AsImage()->GetImage()->LoadDIBSource();
     57 
     58     // Clone() is non-virtual, and can't be overloaded by CPDF_DIBSource to
     59     // return a clone of the subclass as one would typically expect from a
     60     // such a method. Instead, it only clones the CFX_DIBSource, none of whose
     61     // members point to objects owned by the form. As a result, |m_pBitmap|
     62     // may outlive |m_pForm|.
     63     if (pSource)
     64       m_pBitmap = pSource->Clone(nullptr);
     65   }
     66   m_pForm.reset();
     67   return true;
     68 }
     69 
     70 void CPDF_Type3Char::InitializeFromStreamData(bool bColored,
     71                                               const float* pData) {
     72   m_bColored = bColored;
     73   m_Width = FXSYS_round(TextUnitToGlyphUnit(pData[0]));
     74   m_BBox.left = FXSYS_round(TextUnitToGlyphUnit(pData[2]));
     75   m_BBox.bottom = FXSYS_round(TextUnitToGlyphUnit(pData[3]));
     76   m_BBox.right = FXSYS_round(TextUnitToGlyphUnit(pData[4]));
     77   m_BBox.top = FXSYS_round(TextUnitToGlyphUnit(pData[5]));
     78 }
     79 
     80 void CPDF_Type3Char::Transform(const CFX_Matrix& matrix) {
     81   m_Width = m_Width * matrix.GetXUnit() + 0.5f;
     82 
     83   CFX_FloatRect char_rect;
     84   if (m_BBox.right <= m_BBox.left || m_BBox.bottom >= m_BBox.top) {
     85     char_rect = form()->CalcBoundingBox();
     86     TextUnitRectToGlyphUnitRect(&char_rect);
     87   } else {
     88     char_rect = CFX_FloatRect(m_BBox);
     89   }
     90 
     91   m_BBox = matrix.TransformRect(char_rect).ToRoundedFxRect();
     92 }
     93 
     94 void CPDF_Type3Char::ResetForm() {
     95   m_pForm.reset();
     96 }
     97 
     98 RetainPtr<CFX_DIBitmap> CPDF_Type3Char::GetBitmap() {
     99   return m_pBitmap;
    100 }
    101 
    102 const RetainPtr<CFX_DIBitmap>& CPDF_Type3Char::GetBitmap() const {
    103   return m_pBitmap;
    104 }
    105