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