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