// 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;
}