blob: 9c2e5cbf6909a0b633ab3ad6bdf7364dd3cc1387 [file] [log] [blame]
// 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 "fpdfsdk/pdfwindow/PWL_Icon.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
#include "fpdfsdk/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
CPWL_Image::CPWL_Image() : m_pPDFStream(nullptr) {}
CPWL_Image::~CPWL_Image() {}
CFX_ByteString CPWL_Image::GetImageAppStream() {
CFX_ByteTextBuf sAppStream;
CFX_ByteString sAlias = GetImageAlias();
CFX_FloatRect rcPlate = GetClientRect();
CFX_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.AsStringC() << " Do\n"
<< "Q\n";
}
return sAppStream.MakeString();
}
void CPWL_Image::SetPDFStream(CPDF_Stream* pStream) {
m_pPDFStream = pStream;
}
CPDF_Stream* CPWL_Image::GetPDFStream() {
return 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()) {
CFX_FloatRect rect = pDict->GetRectBy("BBox");
fWidth = rect.right - rect.left;
fHeight = rect.top - rect.bottom;
}
}
}
CFX_Matrix CPWL_Image::GetImageMatrix() {
if (m_pPDFStream) {
if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
return pDict->GetMatrixBy("Matrix");
}
}
return CFX_Matrix();
}
CFX_ByteString CPWL_Image::GetImageAlias() {
if (!m_sImageAlias.IsEmpty())
return m_sImageAlias;
if (m_pPDFStream) {
if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
return pDict->GetStringBy("Name");
}
}
return CFX_ByteString();
}
void CPWL_Image::SetImageAlias(const FX_CHAR* 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() : m_pIconFit(nullptr) {}
CPWL_Icon::~CPWL_Icon() {}
int32_t 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) {
fLeft = 0.0f;
fBottom = 0.0f;
CPDF_Array* pA = m_pIconFit->GetDict()
? m_pIconFit->GetDict()->GetArrayBy("A")
: nullptr;
if (pA) {
size_t dwCount = pA->GetCount();
if (dwCount > 0)
fLeft = pA->GetNumberAt(0);
if (dwCount > 1)
fBottom = pA->GetNumberAt(1);
}
} else {
fLeft = 0.0f;
fBottom = 0.0f;
}
}
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;
CFX_FloatRect rcPlate = GetClientRect();
fPlateWidth = rcPlate.right - rcPlate.left;
fPlateHeight = rcPlate.top - rcPlate.bottom;
GetImageSize(fImageWidth, fImageHeight);
int32_t nScaleMethod = GetScaleMethod();
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;
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;
CFX_FloatRect rcPlate = GetClientRect();
fPlateWidth = rcPlate.right - rcPlate.left;
fPlateHeight = rcPlate.top - rcPlate.bottom;
x = (fPlateWidth - fImageFactWidth) * fLeft;
y = (fPlateHeight - fImageFactHeight) * fBottom;
}