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
11CPWL_Image::CPWL_Image() : m_pPDFStream(NULL) {}
12
13CPWL_Image::~CPWL_Image() {}
14
15CFX_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
49void CPWL_Image::SetPDFStream(CPDF_Stream* pStream) {
50  m_pPDFStream = pStream;
51}
52
53CPDF_Stream* CPWL_Image::GetPDFStream() {
54  return m_pPDFStream;
55}
56
57void 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
71CFX_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
81CFX_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
94void CPWL_Image::SetImageAlias(const FX_CHAR* sImageAlias) {
95  m_sImageAlias = sImageAlias;
96}
97
98void CPWL_Image::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
99  fHScale = 1.0f;
100  fVScale = 1.0f;
101}
102
103void CPWL_Image::GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) {
104  x = 0.0f;
105  y = 0.0f;
106}
107
108CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL) {}
109
110CPWL_Icon::~CPWL_Icon() {}
111
112int32_t CPWL_Icon::GetScaleMethod() {
113  if (m_pIconFit)
114    return m_pIconFit->GetScaleMethod();
115
116  return 0;
117}
118
119FX_BOOL CPWL_Icon::IsProportionalScale() {
120  if (m_pIconFit)
121    return m_pIconFit->IsProportionalScale();
122
123  return FALSE;
124}
125
126void 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
145FX_BOOL CPWL_Icon::GetFittingBounds() {
146  if (m_pIconFit)
147    return m_pIconFit->GetFittingBounds();
148
149  return FALSE;
150}
151
152void 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
199void 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