Files
core/PdfWriter/PdfRenderer.cpp
Ilya.Kirillov 9763fe9021 Реализована простая отрисовка пата.
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63167 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:09:52 +03:00

939 lines
27 KiB
C++

#include "PdfRenderer.h"
#include "Src/Document.h"
#include "Src/Pages.h"
#include "Src/Image.h"
#include "Src/Font.h"
#include "Src/FontCidTT.h"
#include "../DesktopEditor/graphics/Image.h"
#include "../DesktopEditor/raster/BgraFrame.h"
#include "../DesktopEditor/cximage/CxImage/ximage.h"
#include "../DesktopEditor/fontengine/ApplicationFonts.h"
#include "../DesktopEditor/fontengine/FontManager.h"
#define MM_2_PT(X) ((X) * 72.0 / 25.4)
#define PT_2_MM(X) ((X) * 25.4 / 72.0)
#define LONG_2_BOOL(X) ((X) ? true : false)
#ifdef DrawText
#undef DrawText
#endif
using namespace PdfWriter;
#define HI_SURROGATE_START 0xD800
#define HI_SURROGATE_END 0xDBFF
#define LO_SURROGATE_START 0xDC00
#define LO_SURROGATE_END 0xDFFF
CPdfRenderer::CPdfRenderer(CApplicationFonts* pAppFonts)
{
m_pAppFonts = pAppFonts;
// Ñîçäàåì ìåíåäæåð øðèôòîâ ñ ñîáñòâåííûì êýøåì
m_pFontManager = pAppFonts->GenerateFontManager();
CFontsCache* pMeasurerCache = new CFontsCache();
pMeasurerCache->SetStreams(pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
m_pDocument = new CDocument();
if (!m_pDocument || !m_pDocument->CreateNew())
{
SetError();
return;
}
m_bValid = true;
m_dPageHeight = 297;
m_dPageWidth = 210;
m_pPage = NULL;
m_pFont = NULL;
}
CPdfRenderer::~CPdfRenderer()
{
RELEASEOBJECT(m_pDocument);
RELEASEINTERFACE(m_pFontManager);
}
void CPdfRenderer::SaveToFile(const std::wstring& wsPath)
{
if (!IsValid())
return;
m_pDocument->SaveToFile(wsPath);
}
//----------------------------------------------------------------------------------------
// Òèï ðåíäåðåðà
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::get_Type(LONG* lType)
{
*lType = c_nPDFWriter;
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ ðàáîòû ñî ñòðàíèöåé
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::NewPage()
{
if (!IsValid())
return S_FALSE;
m_pPage = m_pDocument->AddPage();
if (!m_pPage)
{
SetError();
return S_FALSE;
}
m_pPage->SetWidth(m_dPageWidth);
m_pPage->SetHeight(m_dPageHeight);
m_oPen.Reset();
return S_OK;
}
HRESULT CPdfRenderer::get_Height(double* dHeight)
{
*dHeight = m_dPageHeight;
return S_OK;
}
HRESULT CPdfRenderer::put_Height(const double& dHeight)
{
if (!IsValid() || !m_pPage)
return S_FALSE;
m_dPageHeight = dHeight;
m_pPage->SetHeight(MM_2_PT(dHeight));
return S_OK;
}
HRESULT CPdfRenderer::get_Width(double* dWidth)
{
*dWidth = m_dPageWidth;
return S_OK;
}
HRESULT CPdfRenderer::put_Width(const double& dWidth)
{
if (!IsValid() || !m_pPage)
return S_FALSE;
m_dPageWidth = dWidth;
m_pPage->SetWidth(MM_2_PT(dWidth));
return S_OK;
}
HRESULT CPdfRenderer::get_DpiX(double* dDpiX)
{
*dDpiX = 72;
return S_OK;
}
HRESULT CPdfRenderer::get_DpiY(double* dDpiY)
{
*dDpiY = 72;
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ ðàáîòû ñ Pen
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::get_PenColor(LONG* lColor)
{
*lColor = m_oPen.GetColor();
return S_OK;
}
HRESULT CPdfRenderer::put_PenColor(const LONG& lColor)
{
m_oPen.SetColor(lColor);
return S_OK;
}
HRESULT CPdfRenderer::get_PenAlpha(LONG* lAlpha)
{
*lAlpha = m_oPen.GetAlpha();
return S_OK;
}
HRESULT CPdfRenderer::put_PenAlpha(const LONG& lAlpha)
{
m_oPen.SetAlpha(lAlpha);
return S_OK;
}
HRESULT CPdfRenderer::get_PenSize(double* dSize)
{
*dSize = m_oPen.GetSize();
return S_OK;
}
HRESULT CPdfRenderer::put_PenSize(const double& dSize)
{
m_oPen.SetSize(dSize);
return S_OK;
}
HRESULT CPdfRenderer::get_PenDashStyle(BYTE* nDashStyle)
{
*nDashStyle = m_oPen.GetDashStyle();
return S_OK;
}
HRESULT CPdfRenderer::put_PenDashStyle(const BYTE& nDashStyle)
{
m_oPen.SetDashStyle(nDashStyle);
return S_OK;
}
HRESULT CPdfRenderer::get_PenLineStartCap(BYTE* nCapStyle)
{
*nCapStyle = m_oPen.GetStartCapStyle();
return S_OK;
}
HRESULT CPdfRenderer::put_PenLineStartCap(const BYTE& nCapStyle)
{
m_oPen.SetStartCapStyle(nCapStyle);
return S_OK;
}
HRESULT CPdfRenderer::get_PenLineEndCap(BYTE* nCapStyle)
{
*nCapStyle = m_oPen.GetEndCapStyle();
return S_OK;
}
HRESULT CPdfRenderer::put_PenLineEndCap(const BYTE& nCapStyle)
{
m_oPen.SetEndCapStyle(nCapStyle);
return S_OK;
}
HRESULT CPdfRenderer::get_PenLineJoin(BYTE* nJoinStyle)
{
*nJoinStyle = m_oPen.GetJoinStyle();
return S_OK;
}
HRESULT CPdfRenderer::put_PenLineJoin(const BYTE& nJoinStyle)
{
m_oPen.SetJoinStyle(nJoinStyle);
return S_OK;
}
HRESULT CPdfRenderer::get_PenDashOffset(double* dOffset)
{
*dOffset = m_oPen.GetDashOffset();
return S_OK;
}
HRESULT CPdfRenderer::put_PenDashOffset(const double& dOffset)
{
m_oPen.SetDashOffset(dOffset);
return S_OK;
}
HRESULT CPdfRenderer::get_PenAlign(LONG* lAlign)
{
*lAlign = m_oPen.GetAlign();
return S_OK;
}
HRESULT CPdfRenderer::put_PenAlign(const LONG& lAlign)
{
m_oPen.SetAlign(lAlign);
return S_OK;
}
HRESULT CPdfRenderer::get_PenMiterLimit(double* dMiter)
{
*dMiter = m_oPen.GetMiter();
return S_OK;
}
HRESULT CPdfRenderer::put_PenMiterLimit(const double& dMiter)
{
m_oPen.SetMiter(dMiter);
return S_OK;
}
HRESULT CPdfRenderer::PenDashPattern(double* pPattern, LONG lCount)
{
m_oPen.SetDashPattern(pPattern, lCount);
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ ðàáîòû ñ Brush
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::get_BrushType(LONG* lType)
{
*lType = m_oBrush.GetType();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushType(const LONG& lType)
{
m_oBrush.SetType(lType);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushColor1(LONG* lColor)
{
*lColor = m_oBrush.GetColor1();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushColor1(const LONG& lColor)
{
m_oBrush.SetColor1(lColor);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushAlpha1(LONG* lAlpha)
{
*lAlpha = m_oBrush.GetAlpha1();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushAlpha1(const LONG& lAlpha)
{
m_oBrush.SetAlpha1(lAlpha);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushColor2(LONG* lColor)
{
*lColor = m_oBrush.GetColor2();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushColor2(const LONG& lColor)
{
m_oBrush.SetColor2(lColor);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushAlpha2(LONG* lAlpha)
{
*lAlpha = m_oBrush.GetAlpha2();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushAlpha2(const LONG& lAlpha)
{
m_oBrush.SetAlpha2(lAlpha);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushTexturePath(std::wstring* wsPath)
{
*wsPath = m_oBrush.GetTexturePath();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushTexturePath(const std::wstring& wsPath)
{
m_oBrush.SetTexturePath(wsPath);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushTextureMode(LONG* lMode)
{
*lMode = m_oBrush.GetTextureMode();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushTextureMode(const LONG& lMode)
{
m_oBrush.SetTextureMode(lMode);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushTextureAlpha(LONG* lAlpha)
{
*lAlpha = m_oBrush.GetTextureAlpha();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushTextureAlpha(const LONG& lAlpha)
{
m_oBrush.SetTextureAlpha(lAlpha);
return S_OK;
}
HRESULT CPdfRenderer::get_BrushLinearAngle(double* dAngle)
{
*dAngle = m_oBrush.GetLinearAngle();
return S_OK;
}
HRESULT CPdfRenderer::put_BrushLinearAngle(const double& dAngle)
{
m_oBrush.SetLinearAngle(dAngle);
return S_OK;
}
HRESULT CPdfRenderer::BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height)
{
// TODO: Ïîêà îïðåäåëÿåòñÿ âñå ïî ãðàíèöàì ïàòà
return S_OK;
}
HRESULT CPdfRenderer::BrushBounds(const double& left, const double& top, const double& width, const double& height)
{
// TODO: Ïîêà îïðåäåëÿåòñÿ âñå ïî ãðàíèöàì ïàòà
return S_OK;
}
HRESULT CPdfRenderer::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG lCount)
{
m_oBrush.SetShadingColors(lColors, pPositions, lCount);
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ ðàáîòû ñî øðèôòàìè
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::get_FontName(std::wstring* wsName)
{
*wsName = m_oFont.GetName();
return S_OK;
}
HRESULT CPdfRenderer::put_FontName(const std::wstring& wsName)
{
m_oFont.SetName(wsName);
return S_OK;
}
HRESULT CPdfRenderer::get_FontPath(std::wstring* wsPath)
{
*wsPath = m_oFont.GetPath();
return S_OK;
}
HRESULT CPdfRenderer::put_FontPath(const std::wstring& wsPath)
{
m_oFont.SetPath(wsPath);
return S_OK;
}
HRESULT CPdfRenderer::get_FontSize(double* dSize)
{
*dSize = m_oFont.GetSize();
return S_OK;
}
HRESULT CPdfRenderer::put_FontSize(const double& dSize)
{
m_oFont.SetSize(dSize);
return S_OK;
}
HRESULT CPdfRenderer::get_FontStyle(LONG* lStyle)
{
*lStyle = m_oFont.GetStyle();
return S_OK;
}
HRESULT CPdfRenderer::put_FontStyle(const LONG& lStyle)
{
m_oFont.SetStyle(lStyle);
return S_OK;
}
HRESULT CPdfRenderer::get_FontStringGID(INT* bGid)
{
*bGid = m_oFont.GetGid() ? 1 : 0;
return S_OK;
}
HRESULT CPdfRenderer::put_FontStringGID(const INT& bGid)
{
m_oFont.SetGid(bGid ? true : false);
return S_OK;
}
HRESULT CPdfRenderer::get_FontCharSpace(double* dSpace)
{
*dSpace = m_oFont.GetCharSpace();
return S_OK;
}
HRESULT CPdfRenderer::put_FontCharSpace(const double& dSpace)
{
m_oFont.SetCharSpace(dSpace);
return S_OK;
}
HRESULT CPdfRenderer::get_FontFaceIndex(int* nFaceIndex)
{
*nFaceIndex = (int)m_oFont.GetFaceIndex();
return S_OK;
}
HRESULT CPdfRenderer::put_FontFaceIndex(const int& nFaceIndex)
{
m_oFont.SetFaceIndex(nFaceIndex);
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ âûâîäà òåêñòà
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset)
{
// TODO: Ðåàëèçîâàòü
return S_OK;
}
HRESULT CPdfRenderer::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset)
{
if (!IsPageValid() || !wsUnicodeText.size())
return S_FALSE;
m_pPage->GrSave();
UpdateTransform();
UpdateFont();
UpdatePen();
UpdateBrush();
if (!m_pFont)
return S_FALSE;
unsigned int* pUnicodes = new unsigned int[wsUnicodeText.size()];
if (!pUnicodes)
return S_FALSE;
unsigned int* pOutput = pUnicodes;
unsigned int unLen = 0;
if (2 == sizeof(wchar_t))
{
const wchar_t* wsEnd = wsUnicodeText.c_str() + wsUnicodeText.size();
wchar_t* wsInput = (wchar_t*)wsUnicodeText.c_str();
wchar_t wLeading, wTrailing;
unsigned int unCode;
while (wsInput < wsEnd)
{
wLeading = *wsInput++;
if (wLeading < 0xD800 || wLeading > 0xDFFF)
{
pUnicodes[unLen++] = (unsigned int)wLeading;
}
else if (wLeading >= 0xDC00)
{
// Òàêîãî íå äîëæíî áûòü
continue;
}
else
{
unCode = (wLeading & 0x3FF) << 10;
wTrailing = *wsInput++;
if (wTrailing < 0xDC00 || wTrailing > 0xDFFF)
{
// Òàêîãî íå äîëæíî áûòü
continue;
}
else
{
pUnicodes[unLen++] = (unCode | (wTrailing & 0x3FF) + 0x10000);
}
}
}
}
else
{
unLen = wsUnicodeText.size();
for (unsigned int unIndex = 0; unIndex < unLen; unIndex++)
{
pUnicodes[unIndex] = (unsigned int)wsUnicodeText.at(unIndex);
}
}
unsigned char* pCodes = m_pFont->EncodeString(pUnicodes, unLen);
delete[] pUnicodes;
m_pPage->BeginText();
m_pPage->SetFontAndSize(m_pFont, m_oFont.GetSize());
m_pPage->DrawText(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), pCodes, unLen * 2);
m_pPage->EndText();
m_pPage->GrRestore();
return S_OK;
}
HRESULT CPdfRenderer::CommandDrawTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset, const DWORD& dwFlags)
{
// TODO: Ðåàëèçîâàòü
return S_OK;
}
HRESULT CPdfRenderer::CommandDrawTextEx(const std::wstring& wsUnicodeText, const std::wstring& wsGidText, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset, const DWORD& dwFlags)
{
// TODO: Ðåàëèçîâàòü
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ìàðêåðû êîìàíä
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::BeginCommand(const DWORD& dwType)
{
// Çäåñü ìû íè÷åãî íå äåëàåì
return S_OK;
}
HRESULT CPdfRenderer::EndCommand(const DWORD& dwType)
{
// Çäåñü ìû ðàçëè÷àåì ëèøü 2 êîìàíäû: ïðèñîåäèíèòü òåêóùèé ïàò ê êëèïó è îòìåíèòü êëèï
// TODO: Ðåàëèçîâàòü
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ ðàáîòû ñ ïàòîì
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::PathCommandStart()
{
m_oPath.Clear();
return S_OK;
}
HRESULT CPdfRenderer::PathCommandEnd()
{
m_oPath.Clear();
return S_OK;
}
HRESULT CPdfRenderer::DrawPath(const LONG& lType)
{
if (!IsPageValid())
return S_FALSE;
m_pPage->GrSave();
UpdateTransform();
UpdatePen();
UpdateBrush();
// TODO: Ðåàëèçîâàòü
bool bStroke = LONG_2_BOOL(lType & c_nStroke);
bool bFill = LONG_2_BOOL(lType & c_nWindingFillMode);
bool bEoFill = LONG_2_BOOL(lType & c_nEvenOddFillMode);
m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill);
m_pPage->GrRestore();
return S_OK;
}
HRESULT CPdfRenderer::PathCommandMoveTo(const double& dX, const double& dY)
{
m_oPath.MoveTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY));
return S_OK;
}
HRESULT CPdfRenderer::PathCommandLineTo(const double& dX, const double& dY)
{
m_oPath.LineTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY));
return S_OK;
}
HRESULT CPdfRenderer::PathCommandLinesTo(double* pPoints, const int& nCount)
{
if (nCount < 4 || !pPoints)
return S_OK;
if (!m_oPath.IsMoveTo())
m_oPath.MoveTo(MM_2_PT(pPoints[0]), MM_2_PT(m_dPageHeight - pPoints[1]));
int nPointsCount = (nCount / 2) - 1;
for (int nIndex = 1; nIndex <= nPointsCount; ++nIndex)
{
m_oPath.LineTo(MM_2_PT(pPoints[nIndex * 2]), MM_2_PT(m_dPageHeight - pPoints[nIndex * 2 + 1]));
}
return S_OK;
}
HRESULT CPdfRenderer::PathCommandCurveTo(const double& dX1, const double& dY1, const double& dX2, const double& dY2, const double& dXe, const double& dYe)
{
m_oPath.CurveTo(MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dX2), MM_2_PT(m_dPageHeight - dY2), MM_2_PT(dXe), MM_2_PT(m_dPageHeight - dYe));
return S_OK;
}
HRESULT CPdfRenderer::PathCommandCurvesTo(double* pPoints, const int& nCount)
{
if (nCount < 8 || !pPoints)
return S_OK;
if (!m_oPath.IsMoveTo())
m_oPath.MoveTo(MM_2_PT(pPoints[0]), MM_2_PT(m_dPageHeight - pPoints[1]));
int nPointsCount = (nCount - 2) / 6;
double* pCur = pPoints + 2;
for (int nIndex = 0; nIndex <= nPointsCount; ++nIndex, pCur += 6)
{
m_oPath.CurveTo(MM_2_PT(pCur[0]), MM_2_PT(m_dPageHeight - pCur[1]), MM_2_PT(pCur[2]), MM_2_PT(m_dPageHeight - pCur[3]), MM_2_PT(pCur[4]), MM_2_PT(m_dPageHeight - pCur[5]));
}
return S_OK;
}
HRESULT CPdfRenderer::PathCommandArcTo(const double& dX, const double& dY, const double& dW, const double& dH, const double& dStartAngle, const double& dSweepAngle)
{
m_oPath.ArcTo(MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH), dStartAngle, dSweepAngle);
return S_OK;
}
HRESULT CPdfRenderer::PathCommandClose()
{
m_oPath.Close();
return S_OK;
}
HRESULT CPdfRenderer::PathCommandGetCurrentPoint(double* dX, double* dY)
{
m_oPath.GetLastPoint(*dX, *dY);
*dX = PT_2_MM(*dX);
*dY = PT_2_MM(*dY);
return S_OK;
}
HRESULT CPdfRenderer::PathCommandTextCHAR(const LONG& lUnicode, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset)
{
m_oPath.AddText(m_oFont, lUnicode, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), MM_2_PT(dW), MM_2_PT(dH), MM_2_PT(dBaselineOffset));
return S_OK;
}
HRESULT CPdfRenderer::PathCommandText(const std::wstring& wsText, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset)
{
m_oPath.AddText(m_oFont, wsText, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), MM_2_PT(dW), MM_2_PT(dH), MM_2_PT(dBaselineOffset));
return S_OK;
}
HRESULT CPdfRenderer::PathCommandTextExCHAR(const LONG& lUnicode, const LONG& lGid, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset, const DWORD& dwFlags)
{
m_oPath.AddText(m_oFont, lUnicode, lGid, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), MM_2_PT(dW), MM_2_PT(dH), MM_2_PT(dBaselineOffset), dwFlags);
return S_OK;
}
HRESULT CPdfRenderer::PathCommandTextEx(const std::wstring& wsUnicodeText, const std::wstring& wsGidText, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset, const DWORD& dwFlags)
{
m_oPath.AddText(m_oFont, wsUnicodeText, wsGidText, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY), MM_2_PT(dW), MM_2_PT(dH), MM_2_PT(dBaselineOffset), dwFlags);
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ âûâîäà èçîáðàæåíèé
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::DrawImage(IGrObject* pImage, const double& dX, const double& dY, const double& dW, const double& dH)
{
if (!IsPageValid() || !pImage)
return S_OK;
if (!DrawImage((Aggplus::CImage*)pImage, dX, dY, dW, dH, 255))
return S_FALSE;
return S_OK;
}
HRESULT CPdfRenderer::DrawImageFromFile(const std::wstring& wsImagePath, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha)
{
if (!IsPageValid())
return S_OK;
Aggplus::CImage oAggImage(wsImagePath);
if (!DrawImage(&oAggImage, dX, dY, dW, dH, nAlpha))
return S_FALSE;
return S_OK;
}
//----------------------------------------------------------------------------------------
// Ôóíêöèè äëÿ âûñòàâëåíèÿ ïðåîáðàçîâàíèÿ
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::SetTransform(const double& dM11, const double& dM12, const double& dM21, const double& dM22, const double& dX, const double& dY)
{
m_oTransform.Set(dM11, dM12, dM21, dM22, dX, dY);
return S_OK;
}
HRESULT CPdfRenderer::GetTransform(double* dM11, double* dM12, double* dM21, double* dM22, double* dX, double* dY)
{
*dM11 = m_oTransform.m11;
*dM12 = m_oTransform.m12;
*dM21 = m_oTransform.m21;
*dM22 = m_oTransform.m22;
*dX = m_oTransform.dx;
*dY = m_oTransform.dy;
return S_OK;
}
HRESULT CPdfRenderer::ResetTransform()
{
m_oTransform.Reset();
return S_OK;
}
//----------------------------------------------------------------------------------------
// Òèï êëèïà
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::get_ClipMode(LONG* lMode)
{
*lMode = m_lClipMode;
return S_OK;
}
HRESULT CPdfRenderer::put_ClipMode(const LONG& lMode)
{
m_lClipMode = lMode;
return S_OK;
}
//----------------------------------------------------------------------------------------
// Äîïîëíèòåëüíûå ôóíêöèè
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::CommandLong(const LONG& lType, const LONG& lCommand)
{
return S_OK;
}
HRESULT CPdfRenderer::CommandDouble(const LONG& lType, const double& dCommand)
{
return S_OK;
}
HRESULT CPdfRenderer::CommandString(const LONG& lType, const std::wstring& sCommand)
{
return S_OK;
}
//----------------------------------------------------------------------------------------
// Äîïîëíèòåëüíûå ôóíêöèè Pdf ðåíäåðåðà
//----------------------------------------------------------------------------------------
HRESULT CPdfRenderer::CommandDrawTextPdf(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const std::wstring& wsSrcCodeText, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset, const DWORD& dwFlags)
{
return S_OK;
}
HRESULT CPdfRenderer::PathCommandTextPdf(const std::wstring& bsUnicodeText, const std::wstring& bsGidText, const std::wstring& bsSrcCodeText, const double& dX, const double& dY, const double& dW, const double& dH, const double& dBaselineOffset, const DWORD& dwFlags)
{
return S_OK;
}
HRESULT CPdfRenderer::DrawImage1bpp(Pix* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH)
{
if (!IsPageValid() || !pImageBuffer)
return S_OK;
m_pPage->GrSave();
UpdateTransform();
CImageDict* pPdfImage = m_pDocument->CreateImage();
pPdfImage->LoadBW(pImageBuffer, unWidth, unHeight);
m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH));
m_pPage->GrRestore();
return S_OK;
}
//----------------------------------------------------------------------------------------
// Âíóòðåííèå ôóíêöèè
//----------------------------------------------------------------------------------------
bool CPdfRenderer::DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha)
{
int nImageW = abs((int)pImage->GetWidth());
int nImageH = abs((int)pImage->GetHeight());
BYTE* pData = pImage->GetData();
int nStride = 4 * nImageW;
// Ïðîáåãàåìñÿ ïî êàðòèíêå è îïðåäåëÿåì åñòü ëè ó íàñ àëüôà-êàíàë
bool bAlpha = false;
for (int nIndex = 0, nSize = nImageW * nImageH; nIndex < nSize; nIndex++)
{
if (pData[4 * nIndex + 3] < 255)
{
bAlpha = true;
break;
}
}
CxImage oCxImage;
if (!oCxImage.CreateFromArray(pData, nImageW, nImageH, 32, nStride, (nStride >= 0) ? true : false))
return false;
BYTE* pBuffer = NULL;
int nBufferSize = 0;
if (!oCxImage.Encode(pBuffer, nBufferSize, CXIMAGE_FORMAT_JP2))
return false;
if (!pBuffer || !nBufferSize)
return false;
CImageDict* pPdfImage = m_pDocument->CreateImage();
if (bAlpha || nAlpha < 255)
pPdfImage->LoadSMask(pData, nImageW, nImageH, nAlpha);
pPdfImage->LoadJpx(pBuffer, nBufferSize, nImageW, nImageH);
m_pPage->GrSave();
UpdateTransform();
m_pPage->DrawImage(pPdfImage, MM_2_PT(dX), MM_2_PT(m_dPageHeight - dY - dH), MM_2_PT(dW), MM_2_PT(dH));
m_pPage->GrRestore();
free(pBuffer);
return true;
}
void CPdfRenderer::UpdateFont()
{
std::wstring& wsFontPath = m_oFont.GetPath();
LONG lFaceIndex = m_oFont.GetFaceIndex();
if (L"" == wsFontPath)
{
CFontSelectFormat oFontSelect;
oFontSelect.wsName = new std::wstring(m_oFont.GetName());
oFontSelect.bItalic = new INT(m_oFont.IsItalic() ? 1 : 0);
oFontSelect.bBold = new INT(m_oFont.IsBold() ? 1 : 0);
CFontInfo* pFontInfo = m_pFontManager->GetFontInfoByParams(oFontSelect);
wsFontPath = pFontInfo->m_wsFontPath;
lFaceIndex = pFontInfo->m_lIndex;
}
m_pFont = NULL;
if (L"" != wsFontPath)
{
// TODO: Ïîêà ìû çäåñü ïðåäïîëàãàåì, ÷òî øðèôòû òîëüêî ëèáî TrueType, ëèáî OpenType
LONG lFaceIndex = m_oFont.GetFaceIndex();
m_pFontManager->LoadFontFromFile(wsFontPath, lFaceIndex, 10, 72, 72);
std::wstring wsFontType = m_pFontManager->GetFontType();
if (L"TrueType" == wsFontType || L"OpenType" == wsFontType || L"CFF" == wsFontType)
m_pFont = m_pDocument->CreateTrueTypeFont(wsFontPath, lFaceIndex);
}
}
void CPdfRenderer::UpdateTransform()
{
CTransform& t = m_oTransform;
m_pPage->Concat(t.m11, -t.m12, -t.m21, t.m22, MM_2_PT(t.dx + t.m21 * m_dPageHeight), MM_2_PT(m_dPageHeight - m_dPageHeight * t.m22 - t.dy));
}
void CPdfRenderer::UpdatePen()
{
TColor& oColor = m_oPen.GetTColor();
m_pPage->SetStrokeColor(oColor.r, oColor.g, oColor.b);
m_pPage->SetLineWidth(MM_2_PT(m_oPen.GetSize()));
LONG lDashCount = 0;
double* pDashPattern = NULL;
LONG lDashStyle = m_oPen.GetDashStyle();
if (Aggplus::DashStyleSolid == lDashStyle)
{
// Íè÷åãî íå äåëàåì
}
else if (Aggplus::DashStyleCustom == lDashStyle)
{
double *pDashPatternMM = m_oPen.GetDashPattern(lDashCount);
if (pDashPatternMM && lDashCount)
{
pDashPattern = new double[lDashCount];
if (pDashPattern)
{
for (LONG lIndex = 0; lIndex < lDashCount; lIndex++)
{
pDashPattern[lIndex] = MM_2_PT(pDashPatternMM[lIndex]);
}
}
}
}
else
{
// TODO: Ðåàëèçîâàòü äðóãèå òèïû ïóíêòèðíûõ ëèíèé
}
if (pDashPattern && lDashCount)
{
m_pPage->SetDash(pDashPattern, lDashCount, MM_2_PT(m_oPen.GetDashOffset()));
delete[] pDashPattern;
}
// TODO: Ðåàëèçîâàòü
}
void CPdfRenderer::UpdateBrush()
{
TColor& oColor1 = m_oBrush.GetTColor1();
m_pPage->SetFillColor(oColor1.r, oColor1.g, oColor1.b);
// TODO: Ðåàëèçîâàòü
}
void CPdfRenderer::CPath::Draw(PdfWriter::CPage* pPage, bool bStroke, bool bFill, bool bEoFill)
{
for (int nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++)
{
CPathCommandBase* pCommand = m_vCommands.at(nIndex);
pCommand->Draw(pPage);
}
if (bStroke && !bFill && !bEoFill)
pPage->Stroke();
else if (bStroke && bFill)
pPage->FillStroke();
else if (bStroke && bEoFill)
pPage->EoFill();
else if (bFill)
pPage->Fill();
else if (bEoFill)
pPage->EoFill();
else
pPage->EndPath();
}
void CPdfRenderer::CPath::CPathMoveTo::Draw(PdfWriter::CPage* pPage)
{
pPage->MoveTo(x, y);
}
void CPdfRenderer::CPath::CPathLineTo::Draw(PdfWriter::CPage* pPage)
{
pPage->LineTo(x, y);
}
void CPdfRenderer::CPath::CPathCurveTo::Draw(PdfWriter::CPage* pPage)
{
pPage->CurveTo(x1, y1, x2, y2, xe, ye);
}
void CPdfRenderer::CPath::CPathArcTo::Draw(PdfWriter::CPage* pPage)
{
pPage->EllipseArcTo(x + w / 2, y + h / 2, w / 2, h / 2, startAngle, sweepAngle);
}
void CPdfRenderer::CPath::CPathClose::Draw(PdfWriter::CPage* pPage)
{
pPage->ClosePath();
}
void CPdfRenderer::CPath::CPathTextChar::Draw(PdfWriter::CPage* pPage)
{
// TODO: Ðåàëèçîâàòü
}
void CPdfRenderer::CPath::CPathText::Draw(PdfWriter::CPage* pPage)
{
// TODO: Ðåàëèçîâàòü
}
void CPdfRenderer::CPath::CPathTextExChar::Draw(PdfWriter::CPage* pPage)
{
// TODO: Ðåàëèçîâàòü
}
void CPdfRenderer::CPath::CPathTextEx::Draw(PdfWriter::CPage* pPage)
{
// TODO: Ðåàëèçîâàòü
}