Home | History | Annotate | Download | only in pdfwindow
      1 // Copyright 2014 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 "fpdfsdk/pdfwindow/PWL_Icon.h"
      8 
      9 #include <algorithm>
     10 
     11 #include "core/fpdfapi/parser/cpdf_array.h"
     12 #include "core/fpdfapi/parser/cpdf_stream.h"
     13 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
     14 #include "fpdfsdk/pdfwindow/PWL_Wnd.h"
     15 
     16 CPWL_Image::CPWL_Image() : m_pPDFStream(nullptr) {}
     17 
     18 CPWL_Image::~CPWL_Image() {}
     19 
     20 CFX_ByteString CPWL_Image::GetImageAppStream() {
     21   CFX_ByteTextBuf sAppStream;
     22 
     23   CFX_ByteString sAlias = GetImageAlias();
     24   CFX_FloatRect rcPlate = GetClientRect();
     25   CFX_Matrix mt;
     26   mt.SetReverse(GetImageMatrix());
     27 
     28   FX_FLOAT fHScale = 1.0f;
     29   FX_FLOAT fVScale = 1.0f;
     30   GetScale(fHScale, fVScale);
     31 
     32   FX_FLOAT fx = 0.0f;
     33   FX_FLOAT fy = 0.0f;
     34   GetImageOffset(fx, fy);
     35 
     36   if (m_pPDFStream && sAlias.GetLength() > 0) {
     37     sAppStream << "q\n";
     38     sAppStream << rcPlate.left << " " << rcPlate.bottom << " "
     39                << rcPlate.right - rcPlate.left << " "
     40                << rcPlate.top - rcPlate.bottom << " re W n\n";
     41 
     42     sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx
     43                << " " << rcPlate.bottom + fy << " cm\n";
     44     sAppStream << mt.a << " " << mt.b << " " << mt.c << " " << mt.d << " "
     45                << mt.e << " " << mt.f << " cm\n";
     46 
     47     sAppStream << "0 g 0 G 1 w /" << sAlias.AsStringC() << " Do\n"
     48                << "Q\n";
     49   }
     50 
     51   return sAppStream.MakeString();
     52 }
     53 
     54 void CPWL_Image::SetPDFStream(CPDF_Stream* pStream) {
     55   m_pPDFStream = pStream;
     56 }
     57 
     58 CPDF_Stream* CPWL_Image::GetPDFStream() {
     59   return m_pPDFStream;
     60 }
     61 
     62 void CPWL_Image::GetImageSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight) {
     63   fWidth = 0.0f;
     64   fHeight = 0.0f;
     65 
     66   if (m_pPDFStream) {
     67     if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
     68       CFX_FloatRect rect = pDict->GetRectFor("BBox");
     69 
     70       fWidth = rect.right - rect.left;
     71       fHeight = rect.top - rect.bottom;
     72     }
     73   }
     74 }
     75 
     76 CFX_Matrix CPWL_Image::GetImageMatrix() {
     77   if (m_pPDFStream) {
     78     if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
     79       return pDict->GetMatrixFor("Matrix");
     80     }
     81   }
     82 
     83   return CFX_Matrix();
     84 }
     85 
     86 CFX_ByteString CPWL_Image::GetImageAlias() {
     87   if (!m_sImageAlias.IsEmpty())
     88     return m_sImageAlias;
     89 
     90   if (m_pPDFStream) {
     91     if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
     92       return pDict->GetStringFor("Name");
     93     }
     94   }
     95 
     96   return CFX_ByteString();
     97 }
     98 
     99 void CPWL_Image::SetImageAlias(const FX_CHAR* sImageAlias) {
    100   m_sImageAlias = sImageAlias;
    101 }
    102 
    103 void CPWL_Image::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
    104   fHScale = 1.0f;
    105   fVScale = 1.0f;
    106 }
    107 
    108 void CPWL_Image::GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) {
    109   x = 0.0f;
    110   y = 0.0f;
    111 }
    112 
    113 CPWL_Icon::CPWL_Icon() : m_pIconFit(nullptr) {}
    114 
    115 CPWL_Icon::~CPWL_Icon() {}
    116 
    117 CPDF_IconFit* CPWL_Icon::GetIconFit() {
    118   return m_pIconFit;
    119 }
    120 
    121 int32_t CPWL_Icon::GetScaleMethod() {
    122   if (m_pIconFit)
    123     return m_pIconFit->GetScaleMethod();
    124 
    125   return 0;
    126 }
    127 
    128 bool CPWL_Icon::IsProportionalScale() {
    129   if (m_pIconFit)
    130     return m_pIconFit->IsProportionalScale();
    131 
    132   return false;
    133 }
    134 
    135 void CPWL_Icon::GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom) {
    136   if (m_pIconFit) {
    137     fLeft = 0.0f;
    138     fBottom = 0.0f;
    139     CPDF_Array* pA = m_pIconFit->GetDict()
    140                          ? m_pIconFit->GetDict()->GetArrayFor("A")
    141                          : nullptr;
    142     if (pA) {
    143       size_t dwCount = pA->GetCount();
    144       if (dwCount > 0)
    145         fLeft = pA->GetNumberAt(0);
    146       if (dwCount > 1)
    147         fBottom = pA->GetNumberAt(1);
    148     }
    149   } else {
    150     fLeft = 0.0f;
    151     fBottom = 0.0f;
    152   }
    153 }
    154 
    155 void CPWL_Icon::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
    156   fHScale = 1.0f;
    157   fVScale = 1.0f;
    158 
    159   if (m_pPDFStream) {
    160     FX_FLOAT fImageWidth, fImageHeight;
    161     FX_FLOAT fPlateWidth, fPlateHeight;
    162 
    163     CFX_FloatRect rcPlate = GetClientRect();
    164     fPlateWidth = rcPlate.right - rcPlate.left;
    165     fPlateHeight = rcPlate.top - rcPlate.bottom;
    166 
    167     GetImageSize(fImageWidth, fImageHeight);
    168 
    169     int32_t nScaleMethod = GetScaleMethod();
    170 
    171     switch (nScaleMethod) {
    172       default:
    173       case 0:
    174         fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
    175         fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
    176         break;
    177       case 1:
    178         if (fPlateWidth < fImageWidth)
    179           fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
    180         if (fPlateHeight < fImageHeight)
    181           fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
    182         break;
    183       case 2:
    184         if (fPlateWidth > fImageWidth)
    185           fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
    186         if (fPlateHeight > fImageHeight)
    187           fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
    188         break;
    189       case 3:
    190         break;
    191     }
    192 
    193     FX_FLOAT fMinScale;
    194     if (IsProportionalScale()) {
    195       fMinScale = std::min(fHScale, fVScale);
    196       fHScale = fMinScale;
    197       fVScale = fMinScale;
    198     }
    199   }
    200 }
    201 
    202 void CPWL_Icon::GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) {
    203   FX_FLOAT fLeft, fBottom;
    204 
    205   GetIconPosition(fLeft, fBottom);
    206   x = 0.0f;
    207   y = 0.0f;
    208 
    209   FX_FLOAT fImageWidth, fImageHeight;
    210   GetImageSize(fImageWidth, fImageHeight);
    211 
    212   FX_FLOAT fHScale, fVScale;
    213   GetScale(fHScale, fVScale);
    214 
    215   FX_FLOAT fImageFactWidth = fImageWidth * fHScale;
    216   FX_FLOAT fImageFactHeight = fImageHeight * fVScale;
    217 
    218   FX_FLOAT fPlateWidth, fPlateHeight;
    219   CFX_FloatRect rcPlate = GetClientRect();
    220   fPlateWidth = rcPlate.right - rcPlate.left;
    221   fPlateHeight = rcPlate.top - rcPlate.bottom;
    222 
    223   x = (fPlateWidth - fImageFactWidth) * fLeft;
    224   y = (fPlateHeight - fImageFactHeight) * fBottom;
    225 }
    226