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 
CPWL_Image()14 CPWL_Image::CPWL_Image() : m_pPDFStream(NULL)
15 {
16 }
17 
~CPWL_Image()18 CPWL_Image::~CPWL_Image()
19 {
20 }
21 
GetImageAppStream()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 
SetPDFStream(CPDF_Stream * pStream)54 void CPWL_Image::SetPDFStream(CPDF_Stream * pStream)
55 {
56 	m_pPDFStream = pStream;
57 }
58 
GetPDFStream()59 CPDF_Stream * CPWL_Image::GetPDFStream()
60 {
61 	return this->m_pPDFStream;
62 }
63 
GetImageSize(FX_FLOAT & fWidth,FX_FLOAT & fHeight)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 
GetImageMatrix()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 
GetImageAlias()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 
SetImageAlias(FX_LPCSTR sImageAlias)112 void CPWL_Image::SetImageAlias(FX_LPCSTR sImageAlias)
113 {
114 	m_sImageAlias = sImageAlias;
115 }
116 
GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)117 void CPWL_Image::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)
118 {
119 	fHScale = 1.0f;
120 	fVScale = 1.0f;
121 }
122 
123 
GetImageOffset(FX_FLOAT & x,FX_FLOAT & y)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 
CPWL_Icon()132 CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL)
133 {
134 }
135 
~CPWL_Icon()136 CPWL_Icon::~CPWL_Icon()
137 {
138 }
139 
GetScaleMethod()140 FX_INT32 CPWL_Icon::GetScaleMethod()
141 {
142 	if (m_pIconFit)
143 		return m_pIconFit->GetScaleMethod();
144 
145 	return 0;
146 }
147 
IsProportionalScale()148 FX_BOOL	CPWL_Icon::IsProportionalScale()
149 {
150 	if (m_pIconFit)
151 		return m_pIconFit->IsProportionalScale();
152 
153 	return FALSE;
154 }
155 
GetIconPosition(FX_FLOAT & fLeft,FX_FLOAT & fBottom)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 
GetFittingBounds()178 FX_BOOL CPWL_Icon::GetFittingBounds()
179 {
180 	if (m_pIconFit)
181 		return m_pIconFit->GetFittingBounds();
182 
183 	return FALSE;
184 }
185 
GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)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 
GetImageOffset(FX_FLOAT & x,FX_FLOAT & y)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 
273