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