// Copyright 2014 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "../../include/pdfwindow/PDFWindow.h" #include "../../include/pdfwindow/PWL_Wnd.h" #include "../../include/pdfwindow/PWL_Icon.h" #include "../../include/pdfwindow/PWL_Utils.h" /* ------------------------------- CPWL_Image ---------------------------------- */ CPWL_Image::CPWL_Image() : m_pPDFStream(NULL) { } CPWL_Image::~CPWL_Image() { } CFX_ByteString CPWL_Image::GetImageAppStream() { CFX_ByteTextBuf sAppStream; CFX_ByteString sAlias = this->GetImageAlias(); CPDF_Rect rcPlate = GetClientRect(); CPDF_Matrix mt; mt.SetReverse(GetImageMatrix()); FX_FLOAT fHScale = 1.0f; FX_FLOAT fVScale = 1.0f; GetScale(fHScale,fVScale); FX_FLOAT fx = 0.0f; FX_FLOAT fy = 0.0f; GetImageOffset(fx,fy); if (m_pPDFStream && sAlias.GetLength()>0) { sAppStream << "q\n"; sAppStream << rcPlate.left << " " << rcPlate.bottom << " " << rcPlate.right - rcPlate.left << " " << rcPlate.top - rcPlate.bottom << " re W n\n"; sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx << " " << rcPlate.bottom + fy << " cm\n"; sAppStream << mt.GetA() << " " << mt.GetB() << " " << mt.GetC() << " " << mt.GetD() << " " << mt.GetE() << " " << mt.GetF() << " cm\n"; sAppStream << "0 g 0 G 1 w /" << sAlias << " Do\n" << "Q\n"; } return sAppStream.GetByteString(); } void CPWL_Image::SetPDFStream(CPDF_Stream * pStream) { m_pPDFStream = pStream; } CPDF_Stream * CPWL_Image::GetPDFStream() { return this->m_pPDFStream; } void CPWL_Image::GetImageSize(FX_FLOAT & fWidth,FX_FLOAT & fHeight) { fWidth = 0.0f; fHeight = 0.0f; if (m_pPDFStream) { if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict()) { CPDF_Rect rect = pDict->GetRect("BBox"); fWidth = rect.right - rect.left; fHeight = rect.top - rect.bottom; } } } CPDF_Matrix CPWL_Image::GetImageMatrix() { if (m_pPDFStream) { if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict()) { return pDict->GetMatrix("Matrix"); } } return CPDF_Matrix(); } CFX_ByteString CPWL_Image::GetImageAlias() { if (m_sImageAlias.IsEmpty()) { if (m_pPDFStream) { if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict()) { return pDict->GetString("Name"); } } } else return m_sImageAlias; return CFX_ByteString(); } void CPWL_Image::SetImageAlias(FX_LPCSTR sImageAlias) { m_sImageAlias = sImageAlias; } void CPWL_Image::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale) { fHScale = 1.0f; fVScale = 1.0f; } void CPWL_Image::GetImageOffset(FX_FLOAT & x,FX_FLOAT & y) { x = 0.0f; y = 0.0f; } /* ------------------------------- CPWL_Icon ---------------------------------- */ CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL) { } CPWL_Icon::~CPWL_Icon() { } FX_INT32 CPWL_Icon::GetScaleMethod() { if (m_pIconFit) return m_pIconFit->GetScaleMethod(); return 0; } FX_BOOL CPWL_Icon::IsProportionalScale() { if (m_pIconFit) return m_pIconFit->IsProportionalScale(); return FALSE; } void CPWL_Icon::GetIconPosition(FX_FLOAT & fLeft, FX_FLOAT & fBottom) { if (m_pIconFit) { //m_pIconFit->GetIconPosition(fLeft,fBottom); fLeft = 0.0f; fBottom = 0.0f; CPDF_Array* pA = m_pIconFit->m_pDict->GetArray("A"); if (pA != NULL) { FX_DWORD dwCount = pA->GetCount(); if (dwCount > 0) fLeft = pA->GetNumber(0); if (dwCount > 1) fBottom = pA->GetNumber(1); } } else { fLeft = 0.0f; fBottom = 0.0f; } } FX_BOOL CPWL_Icon::GetFittingBounds() { if (m_pIconFit) return m_pIconFit->GetFittingBounds(); return FALSE; } void CPWL_Icon::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale) { fHScale = 1.0f; fVScale = 1.0f; if (m_pPDFStream) { FX_FLOAT fImageWidth,fImageHeight; FX_FLOAT fPlateWidth,fPlateHeight; CPDF_Rect rcPlate = this->GetClientRect(); fPlateWidth = rcPlate.right - rcPlate.left; fPlateHeight = rcPlate.top - rcPlate.bottom; GetImageSize(fImageWidth,fImageHeight); FX_INT32 nScaleMethod = this->GetScaleMethod(); /* enum ScaleMethod { Always = 0, //A, Always scale Bigger, //B, Scale only when the icon is bigger than the annotation rectangle Smaller, //S, Scale only when the icon is smaller then the annotation rectangle Never //N, Never scale }; */ switch (nScaleMethod) { default: case 0: fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f); fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f); break; case 1: if (fPlateWidth < fImageWidth) fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f); if (fPlateHeight < fImageHeight) fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f); break; case 2: if (fPlateWidth > fImageWidth) fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f); if (fPlateHeight > fImageHeight) fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f); break; case 3: break; } FX_FLOAT fMinScale; if (IsProportionalScale()) { fMinScale = PWL_MIN(fHScale,fVScale); fHScale = fMinScale; fVScale = fMinScale; } } } void CPWL_Icon::GetImageOffset(FX_FLOAT & x,FX_FLOAT & y) { FX_FLOAT fLeft,fBottom; this->GetIconPosition(fLeft,fBottom); x = 0.0f; y = 0.0f; FX_FLOAT fImageWidth,fImageHeight; GetImageSize(fImageWidth,fImageHeight); FX_FLOAT fHScale,fVScale; GetScale(fHScale,fVScale); FX_FLOAT fImageFactWidth = fImageWidth * fHScale; FX_FLOAT fImageFactHeight = fImageHeight * fVScale; FX_FLOAT fPlateWidth,fPlateHeight; CPDF_Rect rcPlate = this->GetClientRect(); fPlateWidth = rcPlate.right - rcPlate.left; fPlateHeight = rcPlate.top - rcPlate.bottom; x = (fPlateWidth - fImageFactWidth) * fLeft; y = (fPlateHeight - fImageFactHeight) * fBottom; }