Commit f4fde172 authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Реализованы градиенты. Реализована прозрачность в градиентах. Сделан конвертер из бинарника в Pdf.

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63265 954022d7-b5bf-4e40-9824-e11837661b57
parent 2d5f7b32
#include "OnlineOfficeBinToPdf.h"
#include "../DesktopEditor/common/File.h"
#include "../DesktopEditor/common/Directory.h"
#include "../DesktopEditor/common/Base64.h"
#include "../DesktopEditor/common/String.h"
#ifndef _INT32
typedef int _INT32;
#endif
#ifndef SHORT
typedef unsigned short USHORT;
#endif
#ifndef BYTE
typedef unsigned char BYTE;
#endif
namespace NSOnlineOfficeBinToPdf
{
enum CommandType
{
ctPenXML = 0,
ctPenColor = 1,
ctPenAlpha = 2,
ctPenSize = 3,
ctPenDashStyle = 4,
ctPenLineStartCap = 5,
ctPenLineEndCap = 6,
ctPenLineJoin = 7,
ctPenDashPatern = 8,
ctPenDashPatternCount = 9,
ctPenDashOffset = 10,
ctPenAlign = 11,
ctPenMiterLimit = 12,
// brush
ctBrushXML = 20,
ctBrushType = 21,
ctBrushColor1 = 22,
ctBrushColor2 = 23,
ctBrushAlpha1 = 24,
ctBrushAlpha2 = 25,
ctBrushTexturePath = 26,
ctBrushTextureAlpha = 27,
ctBrushTextureMode = 28,
ctBrushRectable = 29,
ctBrushRectableEnabled = 30,
ctBrushGradient = 31,
// font
ctFontXML = 40,
ctFontName = 41,
ctFontSize = 42,
ctFontStyle = 43,
ctFontPath = 44,
ctFontGID = 45,
ctFontCharSpace = 46,
// shadow
ctShadowXML = 50,
ctShadowVisible = 51,
ctShadowDistanceX = 52,
ctShadowDistanceY = 53,
ctShadowBlurSize = 54,
ctShadowColor = 55,
ctShadowAlpha = 56,
// edge
ctEdgeXML = 70,
ctEdgeVisible = 71,
ctEdgeDistance = 72,
ctEdgeColor = 73,
ctEdgeAlpha = 74,
// text
ctDrawText = 80,
ctDrawTextEx = 81,
// pathcommands
ctPathCommandMoveTo = 91,
ctPathCommandLineTo = 92,
ctPathCommandLinesTo = 93,
ctPathCommandCurveTo = 94,
ctPathCommandCurvesTo = 95,
ctPathCommandArcTo = 96,
ctPathCommandClose = 97,
ctPathCommandEnd = 98,
ctDrawPath = 99,
ctPathCommandStart = 100,
ctPathCommandGetCurrentPoint = 101,
ctPathCommandText = 102,
ctPathCommandTextEx = 103,
// image
ctDrawImage = 110,
ctDrawImageFromFile = 111,
ctSetParams = 120,
ctBeginCommand = 121,
ctEndCommand = 122,
ctSetTransform = 130,
ctResetTransform = 131,
ctClipMode = 140,
ctCommandLong1 = 150,
ctCommandDouble1 = 151,
ctCommandString1 = 152,
ctCommandLong2 = 153,
ctCommandDouble2 = 154,
ctCommandString2 = 155,
ctPageWidth = 200,
ctPageHeight = 201,
ctPageStart = 202,
ctPageEnd = 203,
// gradients
ctGradientFill = 220,
ctGradientFillXML = 221,
ctGradientStroke = 222,
ctGradientStrokeXML = 223,
ctError = 255
};
static inline _INT32 ReadInt(BYTE*& pData, int& nOffset)
{
#ifdef _ARM_ALIGN_
_INT32 ret = 0;
memcpy(&ret, pData, sizeof(_INT32));
pData += 4;
nOffset += 4;
return ret;
#else
_INT32 ret = *((_INT32*)pData);
pData += 4;
nOffset += 4;
return ret;
#endif
}
static inline USHORT ReadUSHORT(BYTE*& pData, int& nOffset)
{
#ifdef _ARM_ALIGN_
USHORT ret = 0;
memcpy(&ret, pData, sizeof(USHORT));
pData += 2;
nOffset += 2;
return ret;
#else
USHORT ret = *((USHORT*)pData);
pData += 2;
nOffset += 2;
return ret;
#endif
}
static inline std::wstring ReadString16(BYTE*& pData, int& nOffset, int nLen)
{
std::wstring wsTempString;
#ifdef _ARM_ALIGN_
if (sizeof(wchar_t) == 4)
{
#if !defined(_WIN32) && !defined(_WIN64)
int len = nLen / 2;
UTF16* buf = new UTF16[len];
memcpy(buf, pData, nLen);
wsTempString = stringUtf16ToWString(buf, len);
RELEASEARRAYOBJECTS(buf);
#endif
}
else
{
int len = nLen / 2;
wchar_t* buf = new wchar_t[len];
memcpy(buf, pData, nLen);
wsTempString = std::wstring(buf, len);
RELEASEARRAYOBJECTS(buf);
}
#else
if (sizeof(wchar_t) == 4)
{
#if !defined(_WIN32) && !defined(_WIN64)
wsTempString = stringUtf16ToWString((UTF16*)pData, nLen / 2);
#endif
}
else
{
wsTempString = std::wstring((wchar_t*)pData, nLen / 2);
}
#endif
pData += nLen;
nOffset += nLen;
return wsTempString;
}
static std::wstring ReadImagePath(CPdfRenderer* pPdf, const std::wstring& wsHtmlPlace, BYTE*& pData, int& nOffset)
{
int _sLen = 2 * ReadUSHORT(pData, nOffset);
std::wstring wsTempString = ReadString16(pData, nOffset, _sLen);
if (0 == wsTempString.find(L"data:"))
{
try
{
int nFind = wsTempString.find(L",");
wsTempString = wsTempString.substr(nFind + 1);
std::wstring wsBase64TempFile = pPdf->GetTempFile();
std::string sBase64MultyByte(wsTempString.begin(), wsTempString.end());
int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(sBase64MultyByte.length());
BYTE* pImageBuffer = new BYTE[nBufferLen + 64];
if (NSBase64::Base64Decode(sBase64MultyByte.c_str(), sBase64MultyByte.length(), pImageBuffer, &nBufferLen))
{
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(wsBase64TempFile))
{
oFile.WriteFile(pImageBuffer, nBufferLen);
oFile.CloseFile();
wsTempString = wsBase64TempFile;
}
}
else throw;
}
catch (...)
{
}
}
else
{
if (0 != wsTempString.find(L"http:")
&& 0 != wsTempString.find(L"https:")
&& 0 != wsTempString.find(L"ftp:")
&& 0 != wsTempString.find(L"file:"))
{
if (0 == wsTempString.find(L"theme"))
{
std::wstring wsThemesPlace = pPdf->GetThemesPlace();
if (L"" != wsThemesPlace)
wsTempString = wsThemesPlace + L"/" + wsTempString;
}
else
{
if (wsHtmlPlace.length() > 0)
wsTempString = wsHtmlPlace + L"/" + wsTempString;
std::wstring wsSvgExt(L".svg");
if (0 == wsTempString.compare(wsTempString.length() - wsSvgExt.length(), std::wstring::npos, wsSvgExt))
{
std::wstring wsTestPath = wsTempString.substr(0, wsTempString.length() - wsSvgExt.length());
if (NSFile::CFileBinary::Exists(wsTestPath + L".emf"))
wsTempString = wsTestPath + L".emf";
else if (NSFile::CFileBinary::Exists(wsTestPath + L".wmf"))
wsTempString = wsTestPath + L".wmf";
}
}
NSString::Replace(wsTempString, L"\\", L"/");
}
if (0 == wsTempString.find(L"file:///"))
{
NSString::Replace(wsTempString, L"file:///", L"");
NSString::Replace(wsTempString, L"\\", L"/");
}
}
return wsTempString;
}
static bool ConvertBufferToPdf(CPdfRenderer* pPdf, BYTE* pBuffer, LONG lBufferLen, const std::wstring& wsHtmlPlace)
{
CommandType eCommand = ctError;
bool bIsPathOpened = false;
int curindex = 0;
BYTE* current = pBuffer;
while (curindex < lBufferLen)
{
eCommand = (CommandType)(*current);
current++;
curindex++;
switch (eCommand)
{
case ctPageWidth:
{
pPdf->put_Width(ReadInt(current, curindex) / 100000.0);
break;
}
case ctPageHeight:
{
pPdf->put_Height(ReadInt(current, curindex) / 100000.0);
break;
}
case ctPageStart:
{
pPdf->NewPage();
pPdf->BeginCommand(c_nPageType);
break;
}
case ctPageEnd:
{
if (bIsPathOpened)
{
pPdf->PathCommandEnd();
pPdf->EndCommand(c_nPathType);
}
bIsPathOpened = false;
pPdf->EndCommand(c_nPageType);
break;
}
case ctPenColor:
{
pPdf->put_PenColor(ReadInt(current, curindex));
break;
}
case ctPenAlpha:
{
pPdf->put_PenAlpha(*current);
current++;
curindex++;
break;
}
case ctPenSize:
{
pPdf->put_PenSize(ReadInt(current, curindex) / 100000.0);
break;
}
case ctPenLineJoin:
{
pPdf->put_PenLineJoin(*current);
current++;
curindex++;
break;
}
case ctBrushType:
{
pPdf->put_BrushType(ReadInt(current, curindex));
break;
}
case ctBrushColor1:
{
pPdf->put_BrushColor1(ReadInt(current, curindex));
break;
}
case ctBrushAlpha1:
{
pPdf->put_BrushAlpha1(*current);
current++;
curindex++;
break;
}
case ctBrushColor2:
{
pPdf->put_BrushColor1(ReadInt(current, curindex));
break;
}
case ctBrushAlpha2:
{
pPdf->put_BrushAlpha2(*current);
current++;
curindex++;
break;
}
case ctBrushRectable:
{
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
double m3 = ReadInt(current, curindex) / 100000.0;
double m4 = ReadInt(current, curindex) / 100000.0;
pPdf->BrushRect(0, m1, m2, m3, m4);
break;
}
case ctBrushRectableEnabled:
{
bool bEnable = (1 == *current) ? true : false;
pPdf->EnableBrushRect(bEnable);
current += 1;
curindex += 1;
break;
}
case ctBrushTexturePath:
{
std::wstring wsTempString = ReadImagePath(pPdf, wsHtmlPlace, current, curindex);
pPdf->put_BrushTexturePath(wsTempString);
break;
}
case ctBrushGradient:
{
current++;
curindex++;
while (true)
{
BYTE _command = *current;
current++;
curindex++;
if (251 == _command)
break;
switch (_command)
{
case 0:
{
current += 5;
curindex += 5;
double x0 = ReadInt(current, curindex) / 100000.0;
double y0 = ReadInt(current, curindex) / 100000.0;
double x1 = ReadInt(current, curindex) / 100000.0;
double y1 = ReadInt(current, curindex) / 100000.0;
pPdf->SetLinearGradient(x0, y0, x1, y1);
break;
}
case 1:
{
current++;
curindex++;
double x0 = ReadInt(current, curindex) / 100000.0;
double y0 = ReadInt(current, curindex) / 100000.0;
double x1 = ReadInt(current, curindex) / 100000.0;
double y1 = ReadInt(current, curindex) / 100000.0;
double r0 = ReadInt(current, curindex) / 100000.0;
double r1 = ReadInt(current, curindex) / 100000.0;
pPdf->SetRadialGradient(x0, y0, r0, x1, y1, r1);
break;
}
case 2:
{
LONG lColorsCount = (LONG)ReadInt(current, curindex);
LONG* pColors = new LONG[lColorsCount];
double* pPositions = new double[lColorsCount];
if (!pColors)
break;
if (!pPositions)
{
delete[] pColors;
break;
}
for (LONG lIndex = 0; lIndex < lColorsCount; lIndex++)
{
pPositions[lIndex] = ReadInt(current, curindex) / 100000.0;
pColors[lIndex] = ReadInt(current, curindex);
//BYTE _r = *current++;
//BYTE _g = *current++;
//BYTE _b = *current++;
//BYTE _a = *current++;
//curindex += 4;
//int _color = ((_b << 16) & 0xFF0000) | ((_g << 8) & 0xFF00) | _r;
//CString sColor;
//sColor.Format(L"<stop stop-color='%d' stop-opacity='%f' offset='%f' />", _color, _a / 255.0, dPos);
//strColors += sColor;
}
pPdf->put_BrushGradientColors(pColors, pPositions, lColorsCount);
delete[] pColors;
delete[] pPositions;
break;
}
default:
{
break;
}
};
}
break;
}
case ctBrushTextureMode:
{
LONG lMode = (LONG)(*current);
pPdf->put_BrushTextureMode(lMode);
current += 1;
curindex += 1;
break;
}
case ctBrushTextureAlpha:
{
LONG lAlpha = (LONG)(*current);
pPdf->put_BrushTextureAlpha(lAlpha);
current += 1;
curindex += 1;
break;
}
case ctSetTransform:
{
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
double m3 = ReadInt(current, curindex) / 100000.0;
double m4 = ReadInt(current, curindex) / 100000.0;
double m5 = ReadInt(current, curindex) / 100000.0;
double m6 = ReadInt(current, curindex) / 100000.0;
pPdf->SetTransform(m1, m2, m3, m4, m5, m6);
break;
}
case ctPathCommandStart:
{
if (bIsPathOpened)
{
pPdf->PathCommandEnd();
pPdf->EndCommand(c_nPathType);
}
pPdf->BeginCommand(c_nPathType);
pPdf->PathCommandStart();
bIsPathOpened = true;
break;
}
case ctPathCommandMoveTo:
{
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
pPdf->PathCommandMoveTo(m1, m2);
break;
}
case ctPathCommandLineTo:
{
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
pPdf->PathCommandLineTo(m1, m2);
break;
}
case ctPathCommandCurveTo:
{
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
double m3 = ReadInt(current, curindex) / 100000.0;
double m4 = ReadInt(current, curindex) / 100000.0;
double m5 = ReadInt(current, curindex) / 100000.0;
double m6 = ReadInt(current, curindex) / 100000.0;
pPdf->PathCommandCurveTo(m1, m2, m3, m4, m5, m6);
break;
}
case ctPathCommandClose:
{
pPdf->PathCommandClose();
break;
}
case ctPathCommandEnd:
{
if (bIsPathOpened)
{
pPdf->PathCommandEnd();
pPdf->EndCommand(c_nPathType);
bIsPathOpened = false;
}
break;
}
case ctDrawPath:
{
pPdf->DrawPath(ReadInt(current, curindex));
break;
}
case ctDrawImageFromFile:
{
std::wstring wsTempString = ReadImagePath(pPdf, wsHtmlPlace, current, curindex);
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
double m3 = ReadInt(current, curindex) / 100000.0;
double m4 = ReadInt(current, curindex) / 100000.0;
pPdf->DrawImageFromFile(wsTempString, m1, m2, m3, m4);
break;
}
case ctFontName:
{
int _sLen = 2 * (int)ReadUSHORT(current, curindex);
std::wstring wsTempString = ReadString16(current, curindex, _sLen);
pPdf->put_FontName(wsTempString);
break;
}
case ctFontSize:
{
double m1 = ReadInt(current, curindex) / 100000.0;
pPdf->put_FontSize(m1);
break;
}
case ctFontStyle:
{
pPdf->put_FontStyle(ReadInt(current, curindex));
break;
}
case ctDrawText:
{
int _sLen = 2 * (int)ReadUSHORT(current, curindex);
std::wstring wsTempString = ReadString16(current, curindex, _sLen);
double m1 = ReadInt(current, curindex) / 100000.0;
double m2 = ReadInt(current, curindex) / 100000.0;
pPdf->CommandDrawText(wsTempString, m1, m2, 0, 0, 0);
break;
}
case ctBeginCommand:
{
if (bIsPathOpened)
{
pPdf->PathCommandEnd();
pPdf->EndCommand(4);
bIsPathOpened = false;
}
pPdf->BeginCommand((DWORD)(ReadInt(current, curindex)));
break;
}
case ctEndCommand:
{
if (bIsPathOpened)
{
pPdf->PathCommandEnd();
pPdf->EndCommand(4);
bIsPathOpened = false;
}
pPdf->EndCommand((DWORD)(ReadInt(current, curindex)));
pPdf->PathCommandEnd();
break;
}
case ctGradientFill:
{
// TODO:
_INT32 gradientType = ReadInt(current, curindex);
std::wstring sXml, sXmlStop;
if (0 == gradientType) // linearGradient
{
double x1 = ReadInt(current, curindex) / 100000.0;
double x2 = ReadInt(current, curindex) / 100000.0;
double y1 = ReadInt(current, curindex) / 100000.0;
double y2 = ReadInt(current, curindex) / 100000.0;
int stops = ReadInt(current, curindex);
for (int i = 0; i < stops; ++i)
{
_INT32 color = static_cast<_INT32>(*current);
double opacity = static_cast<double>(static_cast<_INT32>(*(current + 1))) / 255.0;
double offset = static_cast<double>(static_cast<_INT32>(*(current + 2))) / 255.0;
current += 6 * 4; // 4 + 1 + 1
curindex += 6 * 4;
}
}
else if (1 == gradientType)
{
double cx = ReadInt(current, curindex) / 100000.0;
double cy = ReadInt(current, curindex) / 100000.0;
double r = ReadInt(current, curindex) / 100000.0;
double fx = ReadInt(current, curindex) / 100000.0;
double fy = ReadInt(current, curindex) / 100000.0;
int stops = ReadInt(current, curindex);
for (int i = 0; i < stops; ++i)
{
_INT32 color = static_cast<_INT32>(*current);
double opacity = static_cast<double>(static_cast<_INT32>(*(current + 1))) / 255.0;
double offset = static_cast<double>(static_cast<_INT32>(*(current + 2))) / 255.0;
current += 6 * 4; // 4 + 1 + 1
curindex += 6 * 4;
}
}
break;
}
case ctGradientFillXML:
{
// TODO:
_INT32 gradientType = ReadInt(current, curindex);
int _sLen = ReadInt(current, curindex);
std::wstring wsTempString = ReadString16(current, curindex, _sLen);
break;
}
case ctGradientStroke:
{
// TODO:
_INT32 gradientType = ReadInt(current, curindex);
if (0 == gradientType) // linearGradient
{
double x1 = ReadInt(current, curindex) / 100000.0;
double x2 = ReadInt(current, curindex) / 100000.0;
double y1 = ReadInt(current, curindex) / 100000.0;
double y2 = ReadInt(current, curindex) / 100000.0;
int stops = ReadInt(current, curindex);
for (int i = 0; i < stops; ++i)
{
_INT32 color = static_cast<_INT32>(*current);
double opacity = static_cast<double>(static_cast<_INT32>(*(current + 1))) / 255.0;
double offset = static_cast<double>(static_cast<_INT32>(*(current + 2))) / 255.0;
current += 6 * 4; // 4 + 1 + 1
curindex += 6 * 4;
}
}
else if (1 == gradientType)
{
double cx = ReadInt(current, curindex) / 100000.0;
double cy = ReadInt(current, curindex) / 100000.0;
double r = ReadInt(current, curindex) / 100000.0;
double fx = ReadInt(current, curindex) / 100000.0;
double fy = ReadInt(current, curindex) / 100000.0;
int stops = ReadInt(current, curindex);
for (int i = 0; i < stops; ++i)
{
_INT32 color = static_cast<_INT32>(*current);
double opacity = static_cast<double>(static_cast<_INT32>(*(current + 1))) / 255.0;
double offset = static_cast<double>(static_cast<_INT32>(*(current + 2))) / 255.0;
current += 6 * 4; // 4 + 1 + 1
curindex += 6 * 4;
}
}
break;
}
case ctGradientStrokeXML:
{
// TODO:
_INT32 gradientType = ReadInt(current, curindex);
int _sLen = (int)ReadInt(current, curindex);
std::wstring wsTempString = ReadString16(current, curindex, _sLen);
break;
}
default:
{
break;
}
}; // switch (eCommand)
} // while (curindex < len)
return true;
}
bool ConvertBinToPdf(CPdfRenderer* pPdf, const std::wstring& wsSrcFile, const std::wstring& wsDstFile, bool bBinary)
{
NSFile::CFileBinary oFile;
if (!oFile.OpenFile(wsSrcFile))
return false;
DWORD dwFileSize = oFile.GetFileSize();
BYTE* pFileContent = new BYTE[dwFileSize];
if (!pFileContent)
{
oFile.CloseFile();
return false;
}
DWORD dwReaded;
oFile.ReadFile(pFileContent, dwFileSize, dwReaded);
oFile.CloseFile();
std::wstring wsHtmlPlace = NSDirectory::GetFolderPath(wsSrcFile);
if (bBinary)
{
ConvertBufferToPdf(pPdf, pFileContent, dwFileSize, wsHtmlPlace);
}
else
{
int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize);
BYTE* pBuffer = new BYTE[nBufferLen];
if (!pBuffer)
{
RELEASEARRAYOBJECTS(pFileContent);
return false;
}
if (NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen))
{
ConvertBufferToPdf(pPdf, pBuffer, nBufferLen, wsHtmlPlace);
}
else
{
RELEASEARRAYOBJECTS(pBuffer);
RELEASEARRAYOBJECTS(pFileContent);
return false;
}
RELEASEARRAYOBJECTS(pBuffer);
}
RELEASEARRAYOBJECTS(pFileContent);
pPdf->SaveToFile(wsDstFile);
return true;
}
}
\ No newline at end of file
#ifndef _PDF_WRITER_ONLINEOFFICEBINTOPDF_H
#define _PDF_WRITER_ONLINEOFFICEBINTOPDF_H
#include <string>
#include "PdfRenderer.h"
namespace NSOnlineOfficeBinToPdf
{
bool ConvertBinToPdf(CPdfRenderer* pPdf, const std::wstring& wsSrcFile, const std::wstring& wsDstFile, bool bBinary);
};
#endif // _PDF_WRITER_ONLINEOFFICEBINTOPDF_H
......@@ -15,6 +15,9 @@
#include "../DesktopEditor/fontengine/FontManager.h"
#include "../DesktopEditor/common/File.h"
#include "../DesktopEditor/common/Directory.h"
#include "OnlineOfficeBinToPdf.h"
#define MM_2_PT(X) ((X) * 72.0 / 25.4)
......@@ -37,6 +40,10 @@ using namespace PdfWriter;
#define LO_SURROGATE_START 0xDC00
#define LO_SURROGATE_END 0xDFFF
// , ,
static const long c_BrushTypeLinearGradient = 8001;
static const long c_BrushTypeRadialGradient = 8002;
CPdfRenderer::CPdfRenderer(CApplicationFonts* pAppFonts)
{
m_pAppFonts = pAppFonts;
......@@ -54,6 +61,8 @@ CPdfRenderer::CPdfRenderer(CApplicationFonts* pAppFonts)
return;
}
//m_pDocument->SetCompressionMode(COMP_ALL);
m_bValid = true;
m_dPageHeight = 297;
m_dPageWidth = 210;
......@@ -61,6 +70,8 @@ CPdfRenderer::CPdfRenderer(CApplicationFonts* pAppFonts)
m_pFont = NULL;
m_nCounter = 0;
SetTempFolder(NSFile::CFileBinary::GetTempPath());
}
CPdfRenderer::~CPdfRenderer()
{
......@@ -74,6 +85,22 @@ void CPdfRenderer::SaveToFile(const std::wstring& wsPath)
m_pDocument->SaveToFile(wsPath);
}
void CPdfRenderer::SetTempFolder(const std::wstring& wsPath)
{
m_wsTempFolder = wsPath;
}
std::wstring CPdfRenderer::GetTempFile()
{
return NSFile::CFileBinary::CreateTempFileWithUniqueName(m_wsTempFolder, L"PDF");
}
void CPdfRenderer::SetThemesPlace(const std::wstring& wsThemesPlace)
{
m_wsThemesPlace = wsThemesPlace;
}
std::wstring CPdfRenderer::GetThemesPlace()
{
return m_wsThemesPlace;
}
//----------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------
......@@ -102,6 +129,11 @@ HRESULT CPdfRenderer::NewPage()
m_pPage->SetHeight(m_dPageHeight);
m_oPen.Reset();
m_oBrush.Reset();
m_oFont.Reset();
m_oPath.Clear();
m_lClipDepth = 0;
return S_OK;
}
......@@ -344,19 +376,21 @@ 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)
HRESULT CPdfRenderer::BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight)
{
// TODO:
// , EnableBrushRect, ,
// .
m_oBrush.SetBrushRect(nVal, dLeft, dTop, dWidth, dHeight);
return S_OK;
}
HRESULT CPdfRenderer::BrushBounds(const double& left, const double& top, const double& width, const double& height)
HRESULT CPdfRenderer::BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight)
{
// TODO:
return S_OK;
}
HRESULT CPdfRenderer::put_BrushGradientColors(LONG* lColors, double* pPositions, LONG lCount)
{
m_oBrush.SetShadingColors(lColors, pPositions, lCount);
m_oBrush.SetGradientColors(lColors, pPositions, lCount);
return S_OK;
}
//----------------------------------------------------------------------------------------
......@@ -541,8 +575,30 @@ HRESULT CPdfRenderer::BeginCommand(const DWORD& dwType)
}
HRESULT CPdfRenderer::EndCommand(const DWORD& dwType)
{
if (!IsPageValid())
return S_FALSE;
// 2 :
// TODO:
if (c_nClipType == dwType)
{
m_pPage->GrSave();
m_lClipDepth++;
UpdateTransform();
if (c_nClipRegionTypeWinding == c_nClipRegionTypeWinding)
m_oPath.Clip(m_pPage, false);
else
m_oPath.Clip(m_pPage, true);
}
else if (c_nResetClipType == dwType)
{
while (m_lClipDepth)
{
m_pPage->GrRestore();
m_lClipDepth--;
}
}
return S_OK;
}
//----------------------------------------------------------------------------------------
......@@ -563,16 +619,41 @@ HRESULT CPdfRenderer::DrawPath(const LONG& lType)
if (!IsPageValid())
return S_FALSE;
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_pPage->GrSave();
UpdateTransform();
if (bStroke)
UpdatePen();
UpdateBrush();
bool bStroke = LONG_2_BOOL(lType & c_nStroke);
bool bFill = LONG_2_BOOL(lType & c_nWindingFillMode);
bool bEoFill = LONG_2_BOOL(lType & c_nEvenOddFillMode);
if (bFill || bEoFill)
UpdateBrush();
if (!m_pShading)
{
m_oPath.Draw(m_pPage, bStroke, bFill, bEoFill);
}
else
{
if (bFill || bEoFill)
{
m_pPage->GrSave();
m_oPath.Clip(m_pPage, bEoFill);
if (NULL != m_pShadingExtGrState)
m_pPage->SetExtGrState(m_pShadingExtGrState);
m_pPage->DrawShading(m_pShading);
m_pPage->GrRestore();
}
if (bStroke)
m_oPath.Draw(m_pPage, bStroke, false, false);
}
m_pPage->GrRestore();
return S_OK;
......@@ -763,6 +844,23 @@ HRESULT CPdfRenderer::DrawImage1bpp(Pix* pImageBuffer, const unsigned int& unWid
m_pPage->GrRestore();
return S_OK;
}
HRESULT CPdfRenderer::EnableBrushRect(const LONG& lEnable)
{
m_oBrush.EnableBrushRect(LONG_2_BOOL(lEnable));
return S_OK;
}
HRESULT CPdfRenderer::SetLinearGradient(const double& dX0, const double& dY0, const double& dX1, const double& dY1)
{
m_oBrush.SetType(c_BrushTypeLinearGradient);
m_oBrush.SetLinearGradientPattern(dX0, dY0, dX1, dY1);
return S_OK;
}
HRESULT CPdfRenderer::SetRadialGradient(const double& dX0, const double& dY0, const double& dR0, const double& dX1, const double& dY1, const double& dR1)
{
m_oBrush.SetType(c_BrushTypeRadialGradient);
m_oBrush.SetRadialGradientPattern(dX0, dY0, dR0, dX1, dY1, dR1);
return S_OK;
}
//----------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------
......@@ -778,6 +876,10 @@ PdfWriter::CImageDict* CPdfRenderer::LoadImage(Aggplus::CImage* pImage, const BY
if (nImageH < 100 || nImageW < 100)
bJpeg = true;
// TODO: CxImage Jpeg2000,
// .. .
bJpeg = true;
// -
bool bAlpha = false;
for (int nIndex = 0, nSize = nImageW * nImageH; nIndex < nSize; nIndex++)
......@@ -793,6 +895,8 @@ PdfWriter::CImageDict* CPdfRenderer::LoadImage(Aggplus::CImage* pImage, const BY
if (!oCxImage.CreateFromArray(pData, nImageW, nImageH, 32, nStride, (pImage->GetStride() >= 0) ? true : false))
return NULL;
oCxImage.SetJpegQualityF(85.0f);
BYTE* pBuffer = NULL;
int nBufferSize = 0;
if (!oCxImage.Encode(pBuffer, nBufferSize, bJpeg ? CXIMAGE_FORMAT_JPG : CXIMAGE_FORMAT_JP2))
......@@ -847,7 +951,6 @@ void CPdfRenderer::UpdateFont()
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)
......@@ -863,6 +966,7 @@ void CPdfRenderer::UpdatePen()
{
TColor& oColor = m_oPen.GetTColor();
m_pPage->SetStrokeColor(oColor.r, oColor.g, oColor.b);
m_pPage->SetStrokeAlpha((unsigned char)m_oPen.GetAlpha());
m_pPage->SetLineWidth(MM_2_PT(m_oPen.GetSize()));
LONG lDashCount = 0;
......@@ -920,7 +1024,11 @@ void CPdfRenderer::UpdatePen()
}
void CPdfRenderer::UpdateBrush()
{
m_pShading = NULL;
m_pShadingExtGrState = NULL;
LONG lBrushType = m_oBrush.GetType();
m_pDocument->GetExtGState();
if (c_BrushTypeTexture == lBrushType)
{
std::wstring& wsTexturePath = m_oBrush.GetTexturePath();
......@@ -959,11 +1067,13 @@ void CPdfRenderer::UpdateBrush()
double dW = 10;
double dH = 10;
double dL, dR, dT, dB;
m_oPath.GetBounds(dL, dT, dR, dB);
if (c_BrushTextureModeStretch == lTextureMode)
{
//
double dL, dR, dT, dB;
m_oPath.GetBounds(dL, dT, dR, dB);
dW = max(10, dR - dL);
dH = max(10, dB - dT);
}
......@@ -974,7 +1084,13 @@ void CPdfRenderer::UpdateBrush()
dH = nImageH * 72 / 96;
}
m_pPage->SetPatternColorSpace(m_pDocument->CreateImageTilePattern(dW, dH, pImage));
// , .
CMatrix* pMatrix = m_pPage->GetTransform();
pMatrix->Apply(dL, dB);
CMatrix oPatternMatrix = *pMatrix;
oPatternMatrix.x = dL;
oPatternMatrix.y = dB;
m_pPage->SetPatternColorSpace(m_pDocument->CreateImageTilePattern(dW, dH, pImage, &oPatternMatrix));
}
}
else if (c_BrushTypeHatch1 == lBrushType)
......@@ -991,12 +1107,65 @@ void CPdfRenderer::UpdateBrush()
m_pPage->SetPatternColorSpace(m_pDocument->CreateHatchPattern(dW, dH, oColor1.r, oColor1.g, oColor1.b, nAlpha1, oColor2.r, oColor2.g, oColor2.b, nAlpha2, wsHatchType));
}
else if (c_BrushTypeRadialGradient == lBrushType || c_BrushTypeLinearGradient == lBrushType)
{
TColor* pGradientColors;
double* pPoints;
LONG lCount;
m_oBrush.GetGradientColors(pGradientColors, pPoints, lCount);
if (lCount > 0)
{
unsigned char* pColors = new unsigned char[3 * lCount];
unsigned char* pAlphas = new unsigned char[lCount];
if (pColors)
{
for (LONG lIndex = 0; lIndex < lCount; lIndex++)
{
pColors[3 * lIndex + 0] = pGradientColors[lIndex].r;
pColors[3 * lIndex + 1] = pGradientColors[lIndex].g;
pColors[3 * lIndex + 2] = pGradientColors[lIndex].b;
pAlphas[lIndex] = pGradientColors[lIndex].a;
}
if (c_BrushTypeLinearGradient == lBrushType)
{
double dX0, dY0, dX1, dY1;
m_oBrush.GetLinearGradientPattern(dX0, dY0, dX1, dY1);
m_pShading = m_pDocument->CreateAxialShading(m_pPage, MM_2_PT(dX0), MM_2_PT(m_dPageHeight - dY0), MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), pColors, pAlphas, pPoints, lCount, m_pShadingExtGrState);
}
else //if (c_BrushTypeRadialGradient == lBrushType)
{
double dX0, dY0, dR0, dX1, dY1, dR1;
m_oBrush.GetRadialGradientPattern(dX0, dY0, dR0, dX1, dY1, dR1);
m_pShading = m_pDocument->CreateRadialShading(m_pPage, MM_2_PT(dX0), MM_2_PT(m_dPageHeight - dY0), MM_2_PT(dR0), MM_2_PT(dX1), MM_2_PT(m_dPageHeight - dY1), MM_2_PT(dR1), pColors, pAlphas, pPoints, lCount, m_pShadingExtGrState);
}
delete[] pColors;
}
}
}
else// if (c_BrushTypeSolid == lBrushType)
{
TColor& oColor1 = m_oBrush.GetTColor1();
m_pPage->SetFillColor(oColor1.r, oColor1.g, oColor1.b);
m_pPage->SetFillAlpha((unsigned char)m_oBrush.GetAlpha1());
}
}
HRESULT CPdfRenderer::OnlineWordToPdf (const std::wstring& wsSrcFile, const std::wstring& wsDstFile)
{
if (!NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, false))
return S_FALSE;
return S_OK;
}
HRESULT CPdfRenderer::OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile)
{
if (!NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, true))
return S_FALSE;
return S_OK;
}
static inline void UpdateMaxMinPoints(double& dMinX, double& dMinY, double& dMaxX, double& dMaxY, const double& dX, const double& dY)
{
......@@ -1033,6 +1202,21 @@ void CPdfRenderer::CPath::Draw(PdfWriter::CPage* pPage, bool bStroke, bool bFill
else
pPage->EndPath();
}
void CPdfRenderer::CPath::Clip(PdfWriter::CPage* pPage, bool bEvenOdd)
{
for (int nIndex = 0, nCount = m_vCommands.size(); nIndex < nCount; nIndex++)
{
CPathCommandBase* pCommand = m_vCommands.at(nIndex);
pCommand->Draw(pPage);
}
if (bEvenOdd)
pPage->Eoclip();
else
pPage->Clip();
pPage->EndPath();
}
void CPdfRenderer::CPath::GetLastPoint(double& dX, double& dY)
{
dX = 0;
......@@ -1144,3 +1328,26 @@ void CPdfRenderer::CPath::CPathTextEx::UpdateBounds(double& dL, double& dT, doub
{
// TODO:
}
void CPdfRenderer::CBrushState::Reset()
{
m_lType = c_BrushTypeSolid;
m_oColor1.Set(0);
m_oColor2.Set(0);
m_nAlpha1 = 255;
m_nAlpha2 = 255;
m_wsTexturePath = L"";
m_lTextureMode = c_BrushTextureModeStretch;
m_nTextureAlpha = 255;
m_dLinearAngle = 0;
m_oRect.Reset();
if (m_pShadingColors)
delete[] m_pShadingColors;
if (m_pShadingPoints)
delete[] m_pShadingPoints;
m_pShadingColors = NULL;
m_pShadingPoints = NULL;
m_lShadingPointsCount = 0;
}
\ No newline at end of file
......@@ -14,6 +14,8 @@ namespace PdfWriter
class CPage;
class CFontCidTrueType;
class CImageDict;
class CShading;
class CExtGrState;
}
namespace Aggplus
......@@ -30,6 +32,10 @@ public:
CPdfRenderer(CApplicationFonts* pAppFonts);
~CPdfRenderer();
void SaveToFile(const std::wstring& wsPath);
void SetTempFolder(const std::wstring& wsPath);
std::wstring GetTempFile();
void SetThemesPlace(const std::wstring& wsThemesPlace);
std::wstring GetThemesPlace();
//----------------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------------
......@@ -89,8 +95,8 @@ public:
virtual HRESULT put_BrushTextureAlpha(const LONG& lAlpha);
virtual HRESULT get_BrushLinearAngle(double* dAngle);
virtual HRESULT put_BrushLinearAngle(const double& dAngle);
virtual HRESULT BrushRect(const INT& val, const double& left, const double& top, const double& width, const double& height);
virtual HRESULT BrushBounds(const double& left, const double& top, const double& width, const double& height);
virtual HRESULT BrushRect(const INT& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight);
virtual HRESULT BrushBounds(const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight);
virtual HRESULT put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount);
//----------------------------------------------------------------------------------------
//
......@@ -164,12 +170,18 @@ public:
//----------------------------------------------------------------------------------------
// Pdf
//----------------------------------------------------------------------------------------
virtual HRESULT 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);
virtual HRESULT 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);
virtual HRESULT DrawImage1bpp(Pix* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH);
HRESULT 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);
HRESULT 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);
HRESULT DrawImage1bpp(Pix* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH);
HRESULT EnableBrushRect(const LONG& lEnable);
HRESULT SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2);
HRESULT SetRadialGradient(const double& dX1, const double& dY1, const double& dR1, const double& dX2, const double& dY2, const double& dR2);
HRESULT OnlineWordToPdf (const std::wstring& wsSrcFile, const std::wstring& wsDstFile);
HRESULT OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile);
private:
void OnlineWordToPdfInternal(BYTE* dstArray, LONG lLen, const std::wstring& wsHtmlPlace, std::wstring& wsHypers, int& nCountPages, const std::wstring& wsTempLogo, LONG lReg);
PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, const BYTE& nAlpha);
bool DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha);
void UpdateFont();
......@@ -202,10 +214,11 @@ private:
r = 0;
g = 0;
b = 0;
a = 255;
}
TColor(const LONG& lColor)
TColor(const LONG& _lColor)
{
Set(lColor);
Set(_lColor);
}
void Set(const LONG& _lColor)
......@@ -215,24 +228,27 @@ private:
r = (unsigned char)(lColor & 0xFF);
g = (unsigned char)((lColor >> 8) & 0xFF);
b = (unsigned char)((lColor >> 16) & 0xFF);
a = (unsigned char)((lColor >> 24) & 0xFF);
}
void operator=(const LONG& _lColor)
{
Set(lColor);
Set(_lColor);
}
void Set(BYTE _r, BYTE _g, BYTE _b)
void Set(BYTE _r, BYTE _g, BYTE _b, BYTE _a = 255)
{
r = _r;
g = _g;
b = _b;
a = _a;
lColor = (LONG)(((LONG)r) | ((LONG)g << 8) | ((LONG)b << 16) | ((LONG)0 << 24));
lColor = (LONG)(((LONG)r) | ((LONG)g << 8) | ((LONG)b << 16) | ((LONG)a << 24));
}
LONG lColor;
BYTE r;
BYTE g;
BYTE b;
BYTE a;
};
class CPenState
{
......@@ -371,7 +387,14 @@ private:
m_oColor.Set(0);
m_dSize = 0;
m_nAlpha = 255;
m_nDashStyle = 0;
m_nStartCapStyle = Aggplus::LineCapRound;
m_nEndCapStyle = Aggplus::LineCapRound;
m_nJoinStyle = Aggplus::LineJoinRound;
m_lAlign = 0;
m_dMiter = 0;
m_nDashStyle = Aggplus::DashStyleSolid;
m_lDashPatternSize = 0;
m_pDashPattern = NULL;
}
......@@ -402,6 +425,7 @@ private:
m_pShadingColors = NULL;
m_pShadingPoints = NULL;
m_lShadingPointsCount = 0;
Reset();
}
~CBrushState()
{
......@@ -410,6 +434,7 @@ private:
if (m_pShadingPoints)
delete[] m_pShadingPoints;
}
void Reset();
inline LONG GetType()
{
return m_lType;
......@@ -490,7 +515,7 @@ private:
{
m_dLinearAngle = dAngle;
}
inline void SetShadingColors(LONG* pColors, double* pPoints, const LONG& lCount)
inline void SetGradientColors(LONG* pColors, double* pPoints, const LONG& lCount)
{
// , 0 1 .
if (m_pShadingColors)
......@@ -539,8 +564,8 @@ private:
if (-1 == lMinIn || dPoint < vPoints.at(lMinIn).dPoint)
lMinIn = lIndex;
if (-1 == lMaxOut || dPoint > vPoints.at(lMaxOut).dPoint)
lMaxOut = lIndex;
if (-1 == lMaxIn || dPoint > vPoints.at(lMaxIn).dPoint)
lMaxIn = lIndex;
}
else if (dPoint < 0)
{
......@@ -689,6 +714,56 @@ private:
}
}
}
inline void SetBrushRect(const int& nVal, const double& dLeft, const double& dTop, const double& dWidth, const double& dHeight)
{
m_oRect.nVal = nVal;
m_oRect.dLeft = dLeft;
m_oRect.dTop = dTop;
m_oRect.dWidth = dWidth;
m_oRect.dHeight = dHeight;
}
inline void EnableBrushRect(bool bEnable)
{
m_oRect.bUse = bEnable;
}
inline void SetLinearGradientPattern(const double& dX0, const double& dY0, const double& dX1, const double& dY1)
{
m_pShadingPattern[0] = dX0;
m_pShadingPattern[1] = dY0;
m_pShadingPattern[2] = dX1;
m_pShadingPattern[3] = dY1;
}
inline void SetRadialGradientPattern(const double& dX0, const double& dY0, const double& dR0, const double& dX1, const double& dY1, const double& dR1)
{
m_pShadingPattern[0] = dX0;
m_pShadingPattern[1] = dY0;
m_pShadingPattern[2] = dR0;
m_pShadingPattern[3] = dX1;
m_pShadingPattern[4] = dY1;
m_pShadingPattern[5] = dR1;
}
inline void GetLinearGradientPattern(double& dX0, double& dY0, double& dX1, double& dY1)
{
dX0 = m_pShadingPattern[0];
dY0 = m_pShadingPattern[1];
dX1 = m_pShadingPattern[2];
dY1 = m_pShadingPattern[3];
}
inline void GetRadialGradientPattern(double& dX0, double& dY0, double& dR0, double& dX1, double& dY1, double& dR1)
{
dX0 = m_pShadingPattern[0];
dY0 = m_pShadingPattern[1];
dR0 = m_pShadingPattern[2];
dX1 = m_pShadingPattern[3];
dY1 = m_pShadingPattern[4];
dR1 = m_pShadingPattern[5];
}
inline void GetGradientColors(TColor*& pColors, double*& pPoints, LONG& lCount)
{
pColors = m_pShadingColors;
pPoints = m_pShadingPoints;
lCount = m_lShadingPointsCount;
}
private:
......@@ -728,9 +803,10 @@ private:
BYTE r = (BYTE)max(0, min(255, (oColor1.r + (oColor2.r - oColor1.r) / dDiff * (dDstPoint - dPoint1))));
BYTE g = (BYTE)max(0, min(255, (oColor1.g + (oColor2.g - oColor1.g) / dDiff * (dDstPoint - dPoint1))));
BYTE b = (BYTE)max(0, min(255, (oColor1.b + (oColor2.b - oColor1.b) / dDiff * (dDstPoint - dPoint1))));
BYTE a = (BYTE)max(0, min(255, (oColor1.a + (oColor2.a - oColor1.a) / dDiff * (dDstPoint - dPoint1))));
TColor oResColor;
oResColor.Set(r, g, b);
oResColor.Set(r, g, b, a);
return oResColor.lColor;
}
......@@ -738,6 +814,30 @@ private:
double dPoint;
bool bUse;
};
struct TBrushRect
{
TBrushRect()
{
Reset();
}
void Reset()
{
bUse = false;
nVal = 0;
dLeft = 0;
dTop = 0;
dWidth = 0;
dHeight = 0;
}
bool bUse;
int nVal;
double dLeft;
double dTop;
double dWidth;
double dHeight;
};
private:
......@@ -750,10 +850,12 @@ private:
LONG m_lTextureMode;
BYTE m_nTextureAlpha;
double m_dLinearAngle;
TBrushRect m_oRect;
TColor* m_pShadingColors;
double* m_pShadingPoints;
LONG m_lShadingPointsCount;
double m_pShadingPattern[6]; // x0, y0, x1, y1 (2 ), x0, y0, r0, x1, y1, r1
};
class CFontState
{
......@@ -764,6 +866,19 @@ private:
{
}
void Reset()
{
m_wsPath = L"";
m_wsName = L"Arial";
m_lStyle = 0;
m_bBold = false;
m_bItalic = false;
m_dCharSpace = 0;
m_lFaceIndex = 0;
m_dSize = 10;
m_bGid = false;
}
inline std::wstring GetName()
{
return m_wsName;
......@@ -1228,6 +1343,7 @@ private:
}
void GetLastPoint(double& dX, double& dY);
void Draw(PdfWriter::CPage* pPage, bool bStroke, bool bFill, bool bEoFill);
void Clip(PdfWriter::CPage* pPage, bool bEvenOdd = false);
void GetBounds(double& dL, double& dT, double& dR, double& dB);
private:
......@@ -1290,10 +1406,14 @@ private:
CApplicationFonts* m_pAppFonts;
CFontManager* m_pFontManager;
std::wstring m_wsTempFolder;
std::wstring m_wsThemesPlace;
PdfWriter::CDocument* m_pDocument;
PdfWriter::CPage* m_pPage;
PdfWriter::CFontCidTrueType* m_pFont;
PdfWriter::CShading* m_pShading;
PdfWriter::CExtGrState* m_pShadingExtGrState;
CPenState m_oPen;
CBrushState m_oBrush;
......@@ -1303,6 +1423,7 @@ private:
LONG m_lClipMode;
double m_dPageHeight;
double m_dPageWidth;
LONG m_lClipDepth;
bool m_bValid;
......
......@@ -141,6 +141,7 @@
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="OnlineOfficeBinToPdf.cpp" />
<ClCompile Include="PdfRenderer.cpp" />
<ClCompile Include="Src\Annotation.cpp" />
<ClCompile Include="Src\Catalog.cpp" />
......@@ -164,6 +165,7 @@
<ClCompile Include="Src\Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="OnlineOfficeBinToPdf.h" />
<ClInclude Include="PdfRenderer.h" />
<ClInclude Include="Src\Annotation.h" />
<ClInclude Include="Src\Catalog.h" />
......
......@@ -90,6 +90,9 @@
<ClCompile Include="PdfRenderer.cpp">
<Filter>Src</Filter>
</ClCompile>
<ClCompile Include="OnlineOfficeBinToPdf.cpp">
<Filter>Src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\Annotation.h">
......@@ -161,5 +164,8 @@
<ClInclude Include="PdfRenderer.h">
<Filter>Src</Filter>
</ClInclude>
<ClInclude Include="OnlineOfficeBinToPdf.h">
<Filter>Src</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -381,7 +381,9 @@ void TestDocument3()
pPage->ClosePath();
pPage->EoFillStroke();
pPage->SetExtGrState(oPdf.GetExtGState(0.8, 0.8));
//pPage->SetExtGrState(oPdf.GetExtGState(0.8, 0.8));
pPage->SetStrokeAlpha(20);
pPage->SetFillAlpha(20);
pPage->SetFillColor(15, 15, 120);
pPage->MoveTo(230, 210);
pPage->LineTo(320, 210);
......@@ -404,7 +406,9 @@ void TestDocument3()
pPage->Clip();
pPage->EndPath();
pPage->SetExtGrState(oPdf.GetExtGState(0.5, 0.5));
pPage->SetStrokeAlpha(122);
pPage->SetFillAlpha(122);
//pPage->SetExtGrState(oPdf.GetExtGState(0.5, 0.5));
pPage->MoveTo(230, 310);
pPage->LineTo(320, 310);
pPage->LineTo(320, 340);
......@@ -749,9 +753,11 @@ void TestDocument8()
0, 0, 255
};
double pPoints[] ={0, 1};
unsigned char pAlphas[] ={ 255, 255 };
CExtGrState* pExtGrState = NULL;
CShading* pShading = oPdf.CreateAxialShading(200, 150, 200, 250, pColors, pPoints, 2);
double pPoints[] ={0, 1};
CShading* pShading = oPdf.CreateAxialShading(pPage, 200, 150, 200, 250, pColors, pAlphas, pPoints, 2, pExtGrState);
pPage->DrawShading(pShading);
pPage->GrRestore();
......@@ -768,10 +774,11 @@ void TestDocument8()
255, 255, 255,
0, 0, 255
};
unsigned char pAlphas2[] ={ 255, 255, 255, 255 };
double pPoints2[] ={ 0, 0.3, 0.7, 1 };
CShading* pShading2 = oPdf.CreateAxialShading(400, 150, 400, 250, pColors2, pPoints2, nCount2);
CShading* pShading2 = oPdf.CreateAxialShading(pPage, 400, 150, 400, 250, pColors2, pAlphas2, pPoints2, nCount2, pExtGrState);
pPage->DrawShading(pShading2);
pPage->GrRestore();
......@@ -788,10 +795,11 @@ void TestDocument8()
255, 255, 0,
0, 0, 255
};
unsigned char pAlphas3[] ={ 255, 255, 255 };
double pPoints3[] ={ 0, 0.5, 1 };
CShading* pShading3 = oPdf.CreateRaidalShading(200, 375, 20, 200, 425, 100, pColors3, pPoints3, nCount3);
CShading* pShading3 = oPdf.CreateRadialShading(pPage, 200, 375, 20, 200, 425, 100, pColors3, pAlphas3, pPoints3, nCount3, pExtGrState);
pPage->DrawShading(pShading3);
pPage->GrRestore();
......@@ -814,7 +822,7 @@ void TestDocument9()
CImageDict* pJpegImage = oPdf.CreateImage();
pJpegImage->LoadJpeg(L"D:/Test Files/Test.jpg", 600, 400);
CImageTilePattern* pPattern = oPdf.CreateImageTilePattern(70, 70, pJpegImage, imagetilepatterntype_InverseX);
CImageTilePattern* pPattern = oPdf.CreateImageTilePattern(70, 70, pJpegImage, NULL, imagetilepatterntype_InverseX);
pPage->GrSave();
pPage->SetPatternColorSpace(pPattern);
......@@ -908,6 +916,27 @@ void TestMetafile()
//ConvertFolder(L"D://Test Files//Emf//", MetaFile::c_lMetaEmf);
ConvertFolder(L"D://Test Files//Wmf//", MetaFile::c_lMetaWmf);
}
void TestOnlineBin()
{
std::wstring wsFolderPath = L"D://Test Files//Txt//";
CApplicationFonts oFonts;
oFonts.Initialize();
double dPx2Mm = 25.4 / 96;
std::vector<std::wstring> vFiles = GetAllFilesInFolder(wsFolderPath, L"txt");
for (int nIndex = 0; nIndex < vFiles.size(); nIndex++)
{
std::wstring wsFilePath = wsFolderPath;
wsFilePath.append(vFiles.at(nIndex));
std::wstring wsOutPath = wsFolderPath + L"Out.pdf";
CPdfRenderer oRenderer(&oFonts);
oRenderer.OnlineWordToPdf(wsFilePath, wsOutPath);
printf("%d of %d %S\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str());
}
}
void main()
{
......@@ -924,6 +953,6 @@ void main()
//TestDocument7();
//TestDocument8();
//TestDocument9();
TestMetafile();
//TestMetafile();
TestOnlineBin();
}
......@@ -43,6 +43,7 @@ namespace PdfWriter
m_unCompressMode = COMP_NONE;
m_pJbig2 = NULL;
memset((void*)m_sTTFontTag, 0x00, 8);
m_pTransparencyGroup = NULL;
}
CDocument::~CDocument()
{
......@@ -65,7 +66,7 @@ namespace PdfWriter
return false;
m_pCatalog->SetPageMode(pagemode_UseNone);
m_pCatalog->SetPageLayout(pagelayout_Single);
m_pCatalog->SetPageLayout(pagelayout_OneColumn);
m_pPageTree = m_pCatalog->GetRoot();
if (!m_pPageTree)
......@@ -81,6 +82,11 @@ namespace PdfWriter
m_nCurPageNum = -1;
m_vPages.clear();
m_vExtGrStates.clear();
m_vFillAlpha.clear();
m_vStrokeAlpha.clear();
m_pTransparencyGroup = NULL;
return true;
}
......@@ -186,7 +192,7 @@ namespace PdfWriter
}
CPage* CDocument::AddPage()
{
CPage* pPage = new CPage(m_pXref, m_pPageTree);
CPage* pPage = new CPage(m_pXref, m_pPageTree, this);
m_pPageTree->AddPage(pPage);
m_pCurPage = pPage;
m_vPages.push_back(pPage);
......@@ -330,6 +336,44 @@ namespace PdfWriter
return pExtGrState;
}
CExtGrState* CDocument::GetStrokeAlpha(double dAlpha)
{
CExtGrState* pExtGrState = NULL;
for (unsigned int unIndex = 0, unCount = m_vStrokeAlpha.size(); unIndex < unCount; unIndex++)
{
pExtGrState = m_vStrokeAlpha.at(unIndex);
if (abs(dAlpha - pExtGrState->GetAlphaStroke()) < 0.001)
return pExtGrState;
}
pExtGrState = new CExtGrState(m_pXref);
if (!pExtGrState)
return NULL;
pExtGrState->SetAlphaStroke(dAlpha);
m_vStrokeAlpha.push_back(pExtGrState);
return pExtGrState;
}
CExtGrState* CDocument::GetFillAlpha(double dAlpha)
{
CExtGrState* pExtGrState = NULL;
for (unsigned int unIndex = 0, unCount = m_vFillAlpha.size(); unIndex < unCount; unIndex++)
{
pExtGrState = m_vFillAlpha.at(unIndex);
if (abs(dAlpha == pExtGrState->GetAlphaFill()) < 0.001)
return pExtGrState;
}
pExtGrState = new CExtGrState(m_pXref);
if (!pExtGrState)
return NULL;
pExtGrState->SetAlphaFill(dAlpha);
m_vFillAlpha.push_back(pExtGrState);
return pExtGrState;
}
CAnnotation* CDocument::CreateTextAnnot(unsigned int unPageNum, TRect oRect, const char* sText)
{
CAnnotation* pAnnot = new CTextAnnotation(m_pXref, oRect, sText);
......@@ -423,6 +467,96 @@ namespace PdfWriter
return m_pJbig2;
}
CShading* CDocument::CreateShading(CPage* pPage, double *pPattern, bool bAxial, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState)
{
pExtGrState = NULL;
bool bNeedAlpha = false;
unsigned char* pA = new unsigned char[3 * nCount];
if (!pA)
return NULL;
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
pA[3 * nIndex + 0] = pAlphas[nIndex];
pA[3 * nIndex + 1] = pAlphas[nIndex];
pA[3 * nIndex + 2] = pAlphas[nIndex];
if (255 != pAlphas[nIndex])
bNeedAlpha = true;
}
if (!bNeedAlpha)
{
delete[] pA;
if (bAxial)
return CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pColors, pPoints, nCount);
else
return CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pColors, pPoints, nCount);
}
// Создаем 2 shading-объекта, один цветной RGB, второй серый со значениями альфа-канала
CShading* pColorShading = NULL;
CShading* pAlphaShading = NULL;
if (bAxial)
{
pColorShading = CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pColors, pPoints, nCount);
pAlphaShading = CreateAxialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pA, pPoints, nCount);
}
else
{
pColorShading = CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pColors, pPoints, nCount);
pAlphaShading = CreateRadialShading(pPattern[0], pPattern[1], pPattern[2], pPattern[3], pPattern[4], pPattern[5], pA, pPoints, nCount);
}
delete[] pA;
if (!m_pTransparencyGroup)
{
m_pTransparencyGroup = new CDictObject();
m_pTransparencyGroup->Add("Type", "Group");
m_pTransparencyGroup->Add("S", "Transparency");
m_pTransparencyGroup->Add("CS", "DeviceRGB");
}
pPage->Add("Group", m_pTransparencyGroup);
double dWidth = pPage->GetWidth();
double dHeight = pPage->GetHeight();
// Создаем графический объект, который будет альфа-маской
CDictObject* pXObject = new CDictObject(m_pXref, true);
pXObject->Add("Type", "XObject");
pXObject->Add("Subtype", "Form");
pXObject->Add("BBox", CArrayObject::CreateBox(0, 0, dWidth, dHeight));
pXObject->Add("Group", m_pTransparencyGroup);
CDictObject* pResources = new CDictObject();
pXObject->Add("Resources", pResources);
CDictObject* pResShadings = new CDictObject();
pResources->Add("Shading", pResShadings);
pResShadings->Add("S1", pAlphaShading);
CStream* pStream = pXObject->GetStream();
pStream->WriteStr("0 0 ");
pStream->WriteReal(dWidth);
pStream->WriteChar(' ');
pStream->WriteReal(dHeight);
pStream->WriteStr(" re\012W\012\n\012/S1 sh\012");
// Создаем обект-маску для графического состояние
CDictObject* pMask = new CDictObject();
m_pXref->Add(pMask);
pMask->Add("Type", "Mask");
pMask->Add("S", "Luminosity");
pMask->Add("G", pXObject);
// Создаем ExtGState объект, в который мы запишем альфа-маску
pExtGrState = new CExtGrState(m_pXref);
pExtGrState->Add("BM", "Normal");
pExtGrState->Add("ca", 1);
pExtGrState->Add("SMask", pMask);
return pColorShading;
}
CShading* CDocument::CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount)
{
for (int nIndex = 0, nShadingsCount = m_vShadings.size(); nIndex < nShadingsCount; nIndex++)
......@@ -430,7 +564,7 @@ namespace PdfWriter
CShading* pShading = m_vShadings.at(nIndex);
if (shadingtype_Axial == pShading->GetShadingType()
&& ((CAxialShading*)pShading)->Compare(dX0, dY0, dX1, dY1)
&& pShading->CompareColors(pColors, pPoints, nCount)
&& pShading->CompareColors(pColors, pPoints, nCount, true)
&& pShading->CompareExtend(true, true))
return pShading;
}
......@@ -439,21 +573,21 @@ namespace PdfWriter
if (!pShading)
return NULL;
pShading->SetColors(pColors, pPoints, nCount);
pShading->SetRgbColors(pColors, pPoints, nCount);
pShading->SetExtend(true, true);
m_vShadings.push_back(pShading);
return pShading;
}
CShading* CDocument::CreateRaidalShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount)
CShading* CDocument::CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount)
{
for (int nIndex = 0, nShadingsCount = m_vShadings.size(); nIndex < nShadingsCount; nIndex++)
{
CShading* pShading = m_vShadings.at(nIndex);
if (shadingtype_Radial == pShading->GetShadingType()
&& ((CRadialShading*)pShading)->Compare(dX0, dY0, dR0, dX1, dY1, dR1)
&& pShading->CompareColors(pColors, pPoints, nCount)
&& pShading->CompareColors(pColors, pPoints, nCount, true)
&& pShading->CompareExtend(true, true))
return pShading;
}
......@@ -462,16 +596,16 @@ namespace PdfWriter
if (!pShading)
return NULL;
pShading->SetColors(pColors, pPoints, nCount);
pShading->SetRgbColors(pColors, pPoints, nCount);
pShading->SetExtend(true, true);
m_vShadings.push_back(pShading);
return pShading;
}
CImageTilePattern*CDocument::CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, EImageTilePatternType eType)
CImageTilePattern*CDocument::CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, CMatrix* pMatrix, EImageTilePatternType eType)
{
return new CImageTilePattern(m_pXref, dW, dH, pImageDict, eType);
return new CImageTilePattern(m_pXref, dW, dH, pImageDict, pMatrix, eType);
}
CImageTilePattern*CDocument::CreateHatchPattern(double dW, double dH, const BYTE& nR1, const BYTE& nG1, const BYTE& nB1, const BYTE& nAlpha1, const BYTE& nR2, const BYTE& nG2, const BYTE& nB2, const BYTE& nAlpha2, const std::wstring& wsHatch)
{
......@@ -499,6 +633,16 @@ namespace PdfWriter
}
}
return CreateImageTilePattern(dW, dH, pImage, imagetilepatterntype_Default);
return CreateImageTilePattern(dW, dH, pImage, NULL, imagetilepatterntype_Default);
}
CShading* CDocument::CreateAxialShading(CPage* pPage, double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState)
{
double pPattern[] ={ dX0, dY0, dX1, dY1 };
return CreateShading(pPage, pPattern, true, pColors, pAlphas, pPoints, nCount, pExtGrState);
}
CShading* CDocument::CreateRadialShading(CPage* pPage, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState)
{
double pPattern[] ={ dX0, dY0, dR0, dX1, dY1, dR1 };
return CreateShading(pPage, pPattern, false, pColors, pAlphas, pPoints, nCount, pExtGrState);
}
}
......@@ -32,6 +32,7 @@ namespace PdfWriter
class CJbig2Global;
class CShading;
class CImageTilePattern;
class CPattern;
//----------------------------------------------------------------------------------------
// CDocument
//----------------------------------------------------------------------------------------
......@@ -58,6 +59,8 @@ namespace PdfWriter
CDestination* CreateDestination(unsigned int unPageIndex);
CExtGrState* GetExtGState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1);
CExtGrState* GetStrokeAlpha(double dAlpha);
CExtGrState* GetFillAlpha(double dAlpha);
CJbig2Global* GetJbig2Global();
CAnnotation* CreateTextAnnot(unsigned int unPageNum, TRect oRect, const char* sText);
......@@ -68,10 +71,10 @@ namespace PdfWriter
CFont14* CreateFont14(EStandard14Fonts eType);
CFontCidTrueType* CreateTrueTypeFont(const std::wstring& wsFontPath, unsigned int unIndex);
CShading* CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount);
CShading* CreateRaidalShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount);
CImageTilePattern*CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, EImageTilePatternType eType = imagetilepatterntype_Default);
CImageTilePattern*CreateImageTilePattern(double dW, double dH, CImageDict* pImageDict, CMatrix* pMatrix = NULL, EImageTilePatternType eType = imagetilepatterntype_Default);
CImageTilePattern*CreateHatchPattern(double dW, double dH, const BYTE& nR1, const BYTE& nG1, const BYTE& nB1, const BYTE& nAlpha1, const BYTE& nR2, const BYTE& nG2, const BYTE& nB2, const BYTE& nAlpha2, const std::wstring& wsHatch);
CShading* CreateAxialShading(CPage* pPage, double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState);
CShading* CreateRadialShading(CPage* pPage, double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState);
private:
......@@ -80,6 +83,9 @@ namespace PdfWriter
void SaveToStream(CStream* pStream);
void PrepareEncryption();
CDictObject* CreatePageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix);
CShading* CreateShading(CPage* pPage, double *pPattern, bool bAxial, unsigned char* pColors, unsigned char* pAlphas, double* pPoints, int nCount, CExtGrState*& pExtGrState);
CShading* CreateAxialShading(double dX0, double dY0, double dX1, double dY1, unsigned char* pColors, double* pPoints, int nCount);
CShading* CreateRadialShading(double dX0, double dY0, double dR0, double dX1, double dY1, double dR1, unsigned char* pColors, double* pPoints, int nCount);
private:
......@@ -111,10 +117,13 @@ namespace PdfWriter
unsigned int m_unCompressMode;
std::vector<CPage*> m_vPages;
std::vector<CExtGrState*> m_vExtGrStates;
std::vector<CExtGrState*> m_vStrokeAlpha;
std::vector<CExtGrState*> m_vFillAlpha;
char m_sTTFontTag[8]; // 6 символов + '+' + 0x00 ("BAAAAA+/0")
CJbig2Global* m_pJbig2;
std::vector<CShading*> m_vShadings;
std::vector<TFontInfo> m_vTTFonts;
CDictObject* m_pTransparencyGroup;
friend class CFontCidTrueType;
};
......
......@@ -8,6 +8,7 @@
#include "Image.h"
#include "Shading.h"
#include "Pattern.h"
#include "Document.h"
#ifdef DrawText
#undef DrawText
......@@ -165,11 +166,12 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
// CPage
//----------------------------------------------------------------------------------------
CPage::CPage(CXref* pXref, CPageTree* pParent)
CPage::CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument)
{
pXref->Add(this);
m_pXref = pXref;
m_pDocument = pDocument;
m_pContents = new CDictObject(pXref);
m_pStream = m_pContents->GetStream();
m_eGrMode = grmode_PAGE;
......@@ -1087,6 +1089,18 @@ namespace PdfWriter
m_pStream->WriteEscapeName(sShadingName);
m_pStream->WriteStr(" sh\012");
}
void CPage::SetStrokeAlpha(unsigned char unAlpha)
{
CExtGrState* pExtGrState = m_pDocument->GetStrokeAlpha((double)(unAlpha / 255.0));
if (pExtGrState)
SetExtGrState(pExtGrState);
}
void CPage::SetFillAlpha(unsigned char unAlpha)
{
CExtGrState* pExtGrState = m_pDocument->GetFillAlpha((double)(unAlpha / 255.0));
if (pExtGrState)
SetExtGrState(pExtGrState);
}
const char* CPage::GetLocalShadingName(CShading* pShading)
{
if (!m_pShadings)
......@@ -1162,4 +1176,17 @@ namespace PdfWriter
m_pStream->WriteEscapeName(sPatternName);
m_pStream->WriteStr(" scn\012");
}
void CPage::SetFilter(unsigned int unFiler)
{
if (m_pContents)
m_pContents->SetFilter(unFiler);
}
CMatrix* CPage::GetTransform()
{
return &m_pGrState->m_oMatrix;
}
void CPage::AddGroup(CDictObject* pDict)
{
Add("Group", pDict);
}
}
\ No newline at end of file
......@@ -18,6 +18,7 @@ namespace PdfWriter
class CImageDict;
class CShading;
class CImageTilePattern;
class CDocument;
//----------------------------------------------------------------------------------------
// CPageTree
//----------------------------------------------------------------------------------------
......@@ -40,7 +41,7 @@ namespace PdfWriter
class CPage : public CDictObject
{
public:
CPage(CXref* pXref, CPageTree* pParent);
CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument);
~CPage();
void SetHeight(double dHeight);
......@@ -82,6 +83,8 @@ namespace PdfWriter
void SetExtGrState(CExtGrState* pExtGrState);
void AddAnnotation(CAnnotation* pAnnot);
void DrawShading(CShading* pShading);
void SetStrokeAlpha(unsigned char unAlpha);
void SetFillAlpha(unsigned char unAlpha);
void BeginText();
void EndText();
......@@ -97,6 +100,9 @@ namespace PdfWriter
void ExecuteXObject(CXObject* pXObject);
void DrawImage(CImageDict* pImage, double dX, double dY, double dWidth, double dHeight);
void SetPatternColorSpace(CImageTilePattern* pPattern);
void SetFilter(unsigned int unFiler);
CMatrix* GetTransform();
void AddGroup(CDictObject* pDict);
private:
......@@ -119,6 +125,7 @@ namespace PdfWriter
private:
CDocument* m_pDocument;
CPageTree* m_pParent;
CXref* m_pXref;
CPoint m_oStartPos; // Позиция начала текущего пата
......
......@@ -13,13 +13,28 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
// CImageTilePattern
//----------------------------------------------------------------------------------------
CImageTilePattern::CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, EImageTilePatternType eType) : CPattern(pXref)
CImageTilePattern::CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, CMatrix* pMatrix, EImageTilePatternType eType) : CPattern(pXref)
{
Add("Type", "Pattern");
Add("PatternType", 1);
Add("PaintType", 1); // Uncolored
Add("TilingType", 1); // No distortion
if (pMatrix)
{
CArrayObject* pMatrixArray = new CArrayObject();
if (!pMatrixArray)
return;
pMatrixArray->Add(pMatrix->m11);
pMatrixArray->Add(pMatrix->m12);
pMatrixArray->Add(pMatrix->m21);
pMatrixArray->Add(pMatrix->m22);
pMatrixArray->Add(pMatrix->x);
pMatrixArray->Add(pMatrix->y);
Add("Matrix", pMatrixArray);
}
CDictObject* pResources = new CDictObject();
if (!pResources)
return;
......
......@@ -20,7 +20,7 @@ namespace PdfWriter
class CImageTilePattern : public CPattern
{
public:
CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, EImageTilePatternType eType = imagetilepatterntype_Default);
CImageTilePattern(CXref* pXref, const double& dW, const double& dH, CImageDict* pImageDict, CMatrix* pMatrix = NULL, EImageTilePatternType eType = imagetilepatterntype_Default);
};
}
......
......@@ -105,6 +105,7 @@ namespace PdfWriter
m_pXref = pXref;
pXref->Add(this);
m_bRgb = true;
m_pColors = NULL;
m_pColorsPoints = NULL;
m_nColorsCount = 0;
......@@ -119,11 +120,12 @@ namespace PdfWriter
if (m_pColorsPoints)
delete[] m_pColorsPoints;
}
void CShading::SetColors(unsigned char* pColors, double* pPoints, int nCount)
void CShading::SetRgbColors(unsigned char* pColors, double* pPoints, int nCount)
{
if (!pColors || !pPoints || nCount <= 1)
return;
m_bRgb = true;
m_pColors = new unsigned char[3 * nCount];
m_pColorsPoints = new double[nCount];
m_nColorsCount = nCount;
......@@ -193,6 +195,53 @@ namespace PdfWriter
delete[] ppValues;
}
}
void CShading::SetGrayColors(unsigned char* pColors, double* pPoints, int nCount)
{
if (!pColors || !pPoints || nCount <= 1)
return;
m_bRgb = false;
m_pColors = new unsigned char[nCount];
m_pColorsPoints = new double[nCount];
m_nColorsCount = nCount;
if (!m_pColors || !m_pColorsPoints)
return;
memcpy(m_pColors, pColors, nCount);
Add("ColorSpace", "DeviceGray");
CArrayObject* pDomain = new CArrayObject();
if (!pDomain)
return;
pDomain->Add(0.0);
pDomain->Add(1.0);
Add("Domain", pDomain);
if (nCount <= 2)
{
double pC0Values = pColors[0] / 255.0;
double pC1Values = pColors[1] / 255.0;
CLinearFuntion* pFunction = new CLinearFuntion(m_pXref, &pC0Values, &pC1Values, 1);
Add("Function", pFunction);
}
else
{
double* pValues = new double[(nCount - 1) * 2];
for (int nIndex = 0; nIndex < nCount - 1; nIndex++)
{
pValues[2 * nIndex + 0] = pColors[nIndex] / 255.0;
pValues[2 * nIndex + 1] = pColors[nIndex + 1] / 255.0;
}
CLineSegmentFuntion* pFunction = new CLineSegmentFuntion(m_pXref, &pValues, pPoints + 1, nCount - 1, 1);
Add("Function", pFunction);
delete[] pValues;
}
}
void CShading::SetExtend(bool bBegin, bool bEnd)
{
CArrayObject* pExtend = new CArrayObject();
......@@ -206,15 +255,18 @@ namespace PdfWriter
m_bBeginExtend = bBegin;
m_bEndExtend = bEnd;
}
bool CShading::CompareColors(unsigned char* pColors, double* pPoints, int nCount)
bool CShading::CompareColors(unsigned char* pColors, double* pPoints, int nCount, bool bRgb)
{
if (nCount != m_nColorsCount
|| (pColors && !m_pColors)
|| (pPoints && !m_pColorsPoints)
|| (!pColors && m_pColors)
|| (!pPoints && m_pColorsPoints))
|| (!pPoints && m_pColorsPoints)
|| bRgb != m_bRgb)
return false;
if (m_bRgb)
{
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
if (pColors[3 * nIndex + 0] != m_pColors[3 * nIndex + 0]
......@@ -223,6 +275,16 @@ namespace PdfWriter
|| abs(pPoints[nIndex] - m_pColorsPoints[nIndex]) > 0.01)
return false;
}
}
else
{
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
if (pColors[nIndex] != m_pColors[nIndex]
|| abs(pPoints[nIndex] - m_pColorsPoints[nIndex]) > 0.01)
return false;
}
}
return true;
}
......
......@@ -2,6 +2,7 @@
#define _PDF_WRITER_SRC_STREAMS_H
#include "Objects.h"
#include "Pattern.h"
namespace PdfWriter
{
......@@ -20,9 +21,10 @@ namespace PdfWriter
CShading(CXref* pXref);
virtual ~CShading();
void SetColors(unsigned char* pColors, double* dPoints, int nCount);
void SetRgbColors(unsigned char* pColors, double* dPoints, int nCount);
void SetGrayColors(unsigned char* pColors, double* dPoints, int nCount);
void SetExtend(bool bBeing, bool bEnd);
bool CompareColors(unsigned char* pColors, double* pPoints, int nCount);
bool CompareColors(unsigned char* pColors, double* pPoints, int nCount, bool bRgb);
bool CompareExtend(bool bBeing, bool bEnd);
virtual EShadingType GetShadingType()
......@@ -36,6 +38,7 @@ namespace PdfWriter
private:
bool m_bRgb; // Rgb Gray
unsigned char* m_pColors;
double* m_pColorsPoints;
int m_nColorsCount;
......
......@@ -59,6 +59,27 @@ namespace PdfWriter
y = 0;
}
void Apply(double& dX, double& dY)
{
double _x = dX;
double _y = dY;
dX = _x * m11 + _y * m21 + x;
dY = _x * m12 + _y * m22 + y;
}
bool operator==(const CMatrix& oMatrix)
{
if (abs(oMatrix.m11 - m11) > 0.001
|| abs(oMatrix.m12 - m12) > 0.001
|| abs(oMatrix.m21 - m21) > 0.001
|| abs(oMatrix.m22 - m22) > 0.001
|| abs(oMatrix.x - x) > 0.001
|| abs(oMatrix.y - y) > 0.001)
return false;
return true;
}
public:
double m11;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment