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->GetArray("A"); 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 273