Re-land: Remove FX_Alloc() null checks now that it can't return NULL.
[pdfium.git] / fpdfsdk / src / pdfwindow / PWL_Icon.cpp
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 "../../include/pdfwindow/PDFWindow.h"
8 #include "../../include/pdfwindow/PWL_Wnd.h"
9 #include "../../include/pdfwindow/PWL_Icon.h"
10 #include "../../include/pdfwindow/PWL_Utils.h"
11
12 /* ------------------------------- CPWL_Image ---------------------------------- */
13
14 CPWL_Image::CPWL_Image() : m_pPDFStream(NULL)
15 {
16 }
17
18 CPWL_Image::~CPWL_Image()
19 {
20 }
21
22 CFX_ByteString CPWL_Image::GetImageAppStream()
23 {
24         CFX_ByteTextBuf sAppStream;
25
26         CFX_ByteString sAlias = this->GetImageAlias();
27         CPDF_Rect rcPlate = GetClientRect();
28         CPDF_Matrix mt;
29         mt.SetReverse(GetImageMatrix());
30
31         FX_FLOAT fHScale = 1.0f;
32         FX_FLOAT fVScale = 1.0f;
33         GetScale(fHScale,fVScale);
34
35         FX_FLOAT fx = 0.0f;
36         FX_FLOAT fy = 0.0f;
37         GetImageOffset(fx,fy);
38
39         if (m_pPDFStream && sAlias.GetLength()>0)
40         {
41                 sAppStream << "q\n";
42                 sAppStream << rcPlate.left << " " << rcPlate.bottom << " "
43                         << rcPlate.right - rcPlate.left << " " << rcPlate.top - rcPlate.bottom << " re W n\n";
44
45                 sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx << " " << rcPlate.bottom + fy << " cm\n";
46                 sAppStream << mt.GetA() << " " << mt.GetB() << " " << mt.GetC() << " " << mt.GetD() << " " << mt.GetE() << " " << mt.GetF() << " cm\n";
47
48                 sAppStream << "0 g 0 G 1 w /" << sAlias << " Do\n" << "Q\n";
49         }
50
51         return sAppStream.GetByteString();
52 }
53
54 void CPWL_Image::SetPDFStream(CPDF_Stream * pStream)
55 {
56         m_pPDFStream = pStream;
57 }
58
59 CPDF_Stream * CPWL_Image::GetPDFStream()
60 {
61         return this->m_pPDFStream;
62 }
63
64 void CPWL_Image::GetImageSize(FX_FLOAT & fWidth,FX_FLOAT & fHeight)
65 {
66         fWidth = 0.0f;
67         fHeight = 0.0f;
68
69         if (m_pPDFStream)
70         {
71                 if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict())
72                 {
73                         CPDF_Rect rect = pDict->GetRect("BBox");
74
75                         fWidth = rect.right - rect.left;
76                         fHeight = rect.top - rect.bottom;
77                 }
78         }
79 }
80
81 CPDF_Matrix     CPWL_Image::GetImageMatrix()
82 {
83         if (m_pPDFStream)
84         {
85                 if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict())
86                 {
87                         return pDict->GetMatrix("Matrix");
88                 }
89         }
90
91         return CPDF_Matrix();
92 }
93
94 CFX_ByteString CPWL_Image::GetImageAlias()
95 {
96         if (m_sImageAlias.IsEmpty())
97         {
98                 if (m_pPDFStream)
99                 {
100                         if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict())          
101                         {
102                                 return pDict->GetString("Name");
103                         }
104                 }
105         }
106         else
107                 return m_sImageAlias;
108
109         return CFX_ByteString();
110 }
111
112 void CPWL_Image::SetImageAlias(FX_LPCSTR sImageAlias)
113 {
114         m_sImageAlias = sImageAlias;
115 }
116
117 void CPWL_Image::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)
118 {
119         fHScale = 1.0f;
120         fVScale = 1.0f;
121 }
122
123
124 void CPWL_Image::GetImageOffset(FX_FLOAT & x,FX_FLOAT & y)
125 {
126         x = 0.0f;
127         y = 0.0f;
128 }
129
130 /* ------------------------------- CPWL_Icon ---------------------------------- */
131
132 CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL)
133 {
134 }
135
136 CPWL_Icon::~CPWL_Icon()
137 {
138 }
139
140 FX_INT32 CPWL_Icon::GetScaleMethod()
141 {
142         if (m_pIconFit)
143                 return m_pIconFit->GetScaleMethod();
144
145         return 0;
146 }
147
148 FX_BOOL CPWL_Icon::IsProportionalScale()
149 {
150         if (m_pIconFit)
151                 return m_pIconFit->IsProportionalScale();
152
153         return FALSE;
154 }
155
156 void CPWL_Icon::GetIconPosition(FX_FLOAT & fLeft, FX_FLOAT & fBottom)
157 {
158         if (m_pIconFit)
159         {
160                 //m_pIconFit->GetIconPosition(fLeft,fBottom);
161                 fLeft = 0.0f;
162                 fBottom = 0.0f;
163                 CPDF_Array* pA = m_pIconFit->m_pDict ? m_pIconFit->m_pDict->GetArray("A") : NULL;
164                 if (pA != NULL)
165                 {
166                         FX_DWORD dwCount = pA->GetCount();
167                         if (dwCount > 0) fLeft = pA->GetNumber(0);
168                         if (dwCount > 1) fBottom = pA->GetNumber(1);
169                 }
170         }
171         else
172         {
173                 fLeft = 0.0f;
174                 fBottom = 0.0f;
175         }
176 }
177
178 FX_BOOL CPWL_Icon::GetFittingBounds()
179 {
180         if (m_pIconFit)
181                 return m_pIconFit->GetFittingBounds();
182
183         return FALSE;
184 }
185
186 void CPWL_Icon::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)
187 {
188         fHScale = 1.0f;
189         fVScale = 1.0f;
190         
191         if (m_pPDFStream)
192         {
193                 FX_FLOAT fImageWidth,fImageHeight;
194                 FX_FLOAT fPlateWidth,fPlateHeight;
195
196                 CPDF_Rect rcPlate = this->GetClientRect();      
197                 fPlateWidth = rcPlate.right - rcPlate.left;
198                 fPlateHeight = rcPlate.top - rcPlate.bottom;
199
200                 GetImageSize(fImageWidth,fImageHeight);
201
202                 FX_INT32 nScaleMethod = this->GetScaleMethod();
203
204                 /*
205                 enum ScaleMethod
206                 {
207                         Always = 0,     //A, Always scale
208                         Bigger,         //B, Scale only when the icon is bigger than the annotation rectangle
209                         Smaller,        //S, Scale only when the icon is smaller then the annotation rectangle
210                         Never           //N, Never scale
211                 };
212                 */
213
214                 switch (nScaleMethod)
215                 {
216                 default:
217                 case 0:
218                         fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f);
219                         fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f);
220                         break;
221                 case 1:
222                         if (fPlateWidth < fImageWidth)
223                                 fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f);
224                         if (fPlateHeight < fImageHeight)
225                                 fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f);
226                         break;
227                 case 2:
228                         if (fPlateWidth > fImageWidth)
229                                 fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f);
230                         if (fPlateHeight > fImageHeight)
231                                 fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f);
232                         break;
233                 case 3:
234                         break;
235                 }
236
237                 FX_FLOAT fMinScale;
238                 if (IsProportionalScale())
239                 {
240                         fMinScale = PWL_MIN(fHScale,fVScale);
241                         fHScale = fMinScale;
242                         fVScale = fMinScale;
243                 }
244         }
245 }
246
247 void CPWL_Icon::GetImageOffset(FX_FLOAT & x,FX_FLOAT & y)
248 {
249         FX_FLOAT fLeft,fBottom;
250
251         this->GetIconPosition(fLeft,fBottom);
252         x = 0.0f;
253         y = 0.0f;
254
255         FX_FLOAT fImageWidth,fImageHeight;
256         GetImageSize(fImageWidth,fImageHeight);
257
258         FX_FLOAT fHScale,fVScale;
259         GetScale(fHScale,fVScale);
260
261         FX_FLOAT fImageFactWidth = fImageWidth * fHScale;
262         FX_FLOAT fImageFactHeight = fImageHeight * fVScale;
263
264         FX_FLOAT fPlateWidth,fPlateHeight;
265         CPDF_Rect rcPlate = this->GetClientRect();      
266         fPlateWidth = rcPlate.right - rcPlate.left;
267         fPlateHeight = rcPlate.top - rcPlate.bottom;
268
269         x = (fPlateWidth - fImageFactWidth) * fLeft;
270         y = (fPlateHeight - fImageFactHeight)  * fBottom;
271 }
272