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

ИСправлен баг с EvenOdd клипом, исправлен баг с текстурной заливкой картинки...

ИСправлен баг с EvenOdd клипом, исправлен баг с текстурной заливкой картинки по пату, исправлен баг с стилем окончания линий. Сделана поддержка нулей в стиле пунктирных линий. Исаправлен баг, из-за которого не записывалось имя шрифта. Исправлен баг с записью элементов ExtGState для прозрачности заливки и обводки. Сделан специальный класс для чтения картинок из файла (больше он не держит указатель на FILE). Функции Сoncat в рендерере переделаны на функции  SetTransform (был баг с неправильным трансформом). Ускорены запись Hex, Int, Double в стрим. 

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63409 954022d7-b5bf-4e40-9824-e11837661b57
parent b3b3bb48
......@@ -265,13 +265,13 @@ namespace NSOnlineOfficeBinToPdf
}
}
NSString::Replace(wsTempString, L"\\", L"/");
NSStringExt::Replace(wsTempString, L"\\", L"/");
}
if (0 == wsTempString.find(L"file:///"))
{
NSString::Replace(wsTempString, L"file:///", L"");
NSString::Replace(wsTempString, L"\\", L"/");
NSStringExt::Replace(wsTempString, L"file:///", L"");
NSStringExt::Replace(wsTempString, L"\\", L"/");
}
}
......
......@@ -276,8 +276,7 @@ void CPdfRenderer::CCommandManager::Flush()
CPage* pPage = m_pRenderer->m_pPage;
pPage->GrSave();
if (!m_oTransform.IsIdentity())
pPage->Concat(m_oTransform.m11, m_oTransform.m12, m_oTransform.m21, m_oTransform.m22, m_oTransform.dx, m_oTransform.dy);
pPage->SetTransform(m_oTransform.m11, m_oTransform.m12, m_oTransform.m21, m_oTransform.m22, m_oTransform.dx, m_oTransform.dy);
ERendererCommandType eType = m_vCommands.at(0)->GetType();
if (renderercommandtype_Text == eType)
......@@ -990,10 +989,10 @@ HRESULT CPdfRenderer::EndCommand(const DWORD& dwType)
m_lClipDepth++;
UpdateTransform();
if (c_nClipRegionTypeWinding == c_nClipRegionTypeWinding)
m_oPath.Clip(m_pPage, false);
else
if (c_nClipRegionTypeEvenOdd & m_lClipMode)
m_oPath.Clip(m_pPage, true);
else
m_oPath.Clip(m_pPage, false);
}
else if (c_nResetClipType == dwType)
{
......@@ -1435,17 +1434,8 @@ void CPdfRenderer::UpdateFont()
}
void CPdfRenderer::UpdateTransform()
{
CTransform t;
t.m11 = m_oTransform.m11;
t.m12 = -m_oTransform.m12;
t.m21 = -m_oTransform.m21;
t.m22 = m_oTransform.m22;
t.dx = MM_2_PT(m_oTransform.dx + m_oTransform.m21 * m_dPageHeight);
t.dy = MM_2_PT(m_dPageHeight - m_dPageHeight * m_oTransform.m22 - m_oTransform.dy);
if (!t.IsIdentity())
m_pPage->Concat(t.m11, t.m12, t.m21, t.m22, t.dx, t.dy);
CTransform& t = m_oTransform;
m_pPage->SetTransform(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()
{
......@@ -1491,7 +1481,7 @@ void CPdfRenderer::UpdatePen()
LONG lCapStyle = m_oPen.GetStartCapStyle();
if (Aggplus::LineCapRound == lCapStyle)
m_pPage->SetLineCap(linecap_Round);
else if (Aggplus::LineCapSquare)
else if (Aggplus::LineCapSquare == lCapStyle)
m_pPage->SetLineCap(linecap_ProjectingSquare);
else
m_pPage->SetLineCap(linecap_Butt);
......@@ -1557,6 +1547,12 @@ void CPdfRenderer::UpdateBrush()
if (c_BrushTextureModeStretch == lTextureMode)
{
// - , .
dL -= 1;
dT -= 1;
dB += 1;
dR += 1;
//
dW = max(10, dR - dL);
dH = max(10, dB - dT);
......
......@@ -387,12 +387,51 @@ private:
}
else
{
m_pDashPattern = new double[lSize];
if (m_pDashPattern)
// , pdf-
std::vector<double> vPattern;
for (LONG lIndex = 0; lIndex < lSize; lIndex++)
{
memcpy((void*)m_pDashPattern, (const void*)pPattern, lSize * sizeof(double));
m_lDashPatternSize = lSize;
if (lIndex > 1 && abs(pPattern[lIndex]) < 0.001)
{
if (0 == lIndex % 2)
{
if (abs(pPattern[lIndex + 1]) < 0.001)
{
lIndex++;
}
else if (lIndex + 1 < lSize)
{
int nPatternSize = vPattern.size();
vPattern.at(nPatternSize - 1) = vPattern.at(nPatternSize - 1) + pPattern[lIndex + 1];
lIndex++;
}
}
else
{
int nPatternSize = vPattern.size();
vPattern.at(nPatternSize - 2) = vPattern.at(nPatternSize - 2) + vPattern.at(nPatternSize - 1);
vPattern.pop_back();
}
}
else
{
vPattern.push_back(pPattern[lIndex]);
}
}
int nPatternSize = vPattern.size();
if (nPatternSize)
{
m_pDashPattern = new double[nPatternSize];
if (m_pDashPattern)
{
for (int nIndex = 0; nIndex < nPatternSize; nIndex++)
{
m_pDashPattern[nIndex] = vPattern.at(nIndex);
}
m_lDashPatternSize = nPatternSize;
}
}
}
}
inline double*GetDashPattern(LONG& lSize)
......@@ -1461,6 +1500,14 @@ private:
std::vector<CRendererCommandBase*> m_vCommands;
CTransform m_oTransform;
};
struct TImageInfo
{
std::wstring wsPath;
BYTE nAlpha;
int nWidth;
int nHeight;
PdfWriter::CImageDict* pImage;
};
private:
......
......@@ -175,6 +175,7 @@
<ClInclude Include="Src\Document.h" />
<ClInclude Include="Src\Encrypt.h" />
<ClInclude Include="Src\EncryptDictionary.h" />
<ClInclude Include="Src\FastStringToDouble.h" />
<ClInclude Include="Src\Font.h" />
<ClInclude Include="Src\Font14.h" />
<ClInclude Include="Src\FontCidTT.h" />
......
......@@ -167,5 +167,8 @@
<ClInclude Include="OnlineOfficeBinToPdf.h">
<Filter>Src</Filter>
</ClInclude>
<ClInclude Include="Src\FastStringToDouble.h">
<Filter>Src\Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -37,6 +37,8 @@
#include <vector>
#include <ctime>
#include "../Src/FastStringToDouble.h"
#ifdef DrawText
#undef DrawText
#endif
......@@ -918,8 +920,8 @@ void TestMetafile()
}
void TestOnlineBin()
{
std::wstring wsFolderPath = L"D://Test Files//Txt//";
//std::wstring wsFolderPath = L"D://Test Files//Txt//IvanovaVeronica//";
//std::wstring wsFolderPath = L"D://Test Files//Txt//";
std::wstring wsFolderPath = L"D://Test Files//Txt//IvanovaVeronica//";
std::wstring wsTempFolder = L"D://Test Files//Temp//";
CApplicationFonts oFonts;
......@@ -946,6 +948,78 @@ void TestOnlineBin()
printf("%f\n", dElapsedSecs);
}
void TestDouble()
{
const int nMaxInt = NSFastIntToString::c_nMaxInt;
const int nCount = 100000;
double pDoubles[nCount];
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
pDoubles[nIndex] = (rand() % (nMaxInt - 1) + (rand() % (nMaxInt - 1)) / (double)nMaxInt);
}
pDoubles[0] = 120.0012;
pDoubles[1] = 12.012312;
pDoubles[2] = 0.00012312;
clock_t oBeginTime = clock();
char pBuffer[32];
for (int nI = 0; nI < 10; nI++)
{
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
double dValue = pDoubles[nIndex];
memset(pBuffer, 0x00, 32);
FtoA(pBuffer, dValue, pBuffer + 31);
}
}
clock_t oEndTime = clock();
double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC;
printf("FtoA %f\n", dElapsedSecs);
oBeginTime = clock();
for (int nI = 0; nI < 10; nI++)
{
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
int nResLen = 0;
double dValue = pDoubles[nIndex];
int nIVal = (int)dValue;
int nFVal = (int)(abs(dValue - nIVal) * 10000);
int nLen = 0;
const char* sString = NSFastIntToString::GetString(abs(nIVal), nLen);
if (nIVal < 0)
pBuffer[nResLen++] = '-';
memcpy(pBuffer + nResLen, sString, nLen);
nResLen += nLen;
if (nFVal)
{
sString = NSFastIntToString::GetString(nFVal, nLen);
pBuffer[nResLen++] = '.';
int nZeros = 4 - nLen;
if (nZeros > 0)
{
memcpy(pBuffer + nResLen, NSFastIntToString::GetZeros(nZeros), nLen);
nResLen += nZeros;
}
memcpy(pBuffer + nResLen, sString, nLen);
}
}
}
oEndTime = clock();
dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC;
printf("Fast %f\n", dElapsedSecs);
}
void main()
{
//TestStreams();
......@@ -961,8 +1035,30 @@ void main()
//TestDocument7();
//TestDocument8();
//TestDocument9();
TestMetafile();
//TestOnlineBin();
//TestMetafile();
TestOnlineBin();
//TestDouble();
//std::string wsTest = "";
//wsTest = "static const char c_nPrecisionLen[] = {";
//int nMax = 100000;
//for (int nIndex = 0; nIndex < nMax; nIndex++)
//{
// std::string sInt = std::to_string(nIndex);
// while (sInt.length() > 1 && '0' == sInt.at(sInt.length() - 1))
// sInt.pop_back();
// wsTest += std::to_string(sInt.length());
// if (nIndex != nMax - 1)
// wsTest += ",";
//}
//wsTest += "};";
char q;
std::cin >> q;
......
......@@ -568,7 +568,7 @@ namespace PdfWriter
double dHeight = pPage->GetHeight();
// Создаем графический объект, который будет альфа-маской
CDictObject* pXObject = new CDictObject(m_pXref, true);
CDictObject* pXObject = new CDictObject(m_pXref);
pXObject->Add("Type", "XObject");
pXObject->Add("Subtype", "Form");
pXObject->Add("BBox", CArrayObject::CreateBox(0, 0, dWidth, dHeight));
......
......@@ -84,6 +84,7 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
CFontCidTrueType::CFontCidTrueType(CXref* pXref, CDocument* pDocument, const std::wstring& wsFontPath, unsigned int unIndex) : CFontDict(pXref, pDocument)
{
m_bNeedAddFontName = true;
CFontFileTrueType* pFontTT = CFontFileTrueType::LoadFromFile(wsFontPath, unIndex);
m_pFontFile = pFontTT;
......@@ -101,7 +102,7 @@ namespace PdfWriter
pDescendantFonts->Add(pFont);
Add("DescendantFonts", pDescendantFonts);
CDictObject* pToUnicodeDict = new CDictObject(m_pXref, true);
CDictObject* pToUnicodeDict = new CDictObject(m_pXref);
Add("ToUnicode", pToUnicodeDict);
pToUnicodeDict->SetFilter(STREAM_FILTER_FLATE_DECODE);
m_pToUnicodeStream = pToUnicodeDict->GetStream();
......@@ -165,12 +166,12 @@ namespace PdfWriter
pFontDescriptor->Add("StemV", 0);
pFontDescriptor->Add("FontWeight", m_pFontFile->GetWeight());
m_pFontFileDict = new CDictObject(m_pXref, true);
m_pFontFileDict = new CDictObject(m_pXref);
pFontDescriptor->Add("FontFile2", m_pFontFileDict);
pFont->Add("FontDescriptor", pFontDescriptor);
CDictObject* pCIDToGIDMapDict = new CDictObject(m_pXref, true);
CDictObject* pCIDToGIDMapDict = new CDictObject(m_pXref);
pFont->Add("CIDToGIDMap", pCIDToGIDMapDict);
pCIDToGIDMapDict->SetFilter(STREAM_FILTER_FLATE_DECODE);
m_pCidToGidMapStream = pCIDToGIDMapDict->GetStream();
......@@ -414,6 +415,25 @@ namespace PdfWriter
m_pDocument->AddFreeTypeFont(this);
m_nGlyphsCount = m_pFace->num_glyphs;
m_nSymbolicCmap = GetSymbolicCmapIndex(m_pFace);
if (m_bNeedAddFontName)
{
// ,
std::string sFontName = m_pDocument->GetTTFontTag() + std::string(m_pFace->family_name);
if (m_pFace->style_flags & FT_STYLE_FLAG_ITALIC)
sFontName += "-Italic";
if (m_pFace->style_flags & FT_STYLE_FLAG_BOLD)
sFontName += "-Bold";
const char* sName = sFontName.c_str();
Add("BaseFont", sName);
m_pFont->Add("BaseFont", sName);
m_pFontDescriptor->Add("FontName", sName);
m_bNeedAddFontName = false;
}
return true;
}
}
......@@ -66,6 +66,7 @@ namespace PdfWriter
FT_Byte* m_pFaceMemory;
int m_nGlyphsCount;
int m_nSymbolicCmap;
bool m_bNeedAddFontName;
friend class CDocument;
};
......
......@@ -90,20 +90,24 @@ namespace PdfWriter
{
dValue = min(1, max(0, dValue));
Add("CA", dValue);
m_dAlphaStroke = dValue;
}
void CExtGrState::SetAlphaFill (double dValue)
{
dValue = min(1, max(0, dValue));
Add("ca", dValue);
m_dAlphaFill = dValue;
}
void CExtGrState::SetBlendMode (EBlendMode eBlendMode)
{
eBlendMode = min(blendmode_Max, max(blendmode_Min, eBlendMode));
Add("BM", c_sBlendModeNames[(int)eBlendMode]);
m_eBlendMode = eBlendMode;
}
void CExtGrState::SetStrokeAdjustment(bool bValue)
{
Add("SA", bValue);
m_bStrokeAdj = bValue;
}
double CExtGrState::GetAlphaStroke()
{
......
......@@ -17,7 +17,7 @@ namespace PdfWriter
}
void CImageDict::LoadJpeg(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight)
{
CFileStream* pStream = new CFileStream();
CImageFileStream* pStream = new CImageFileStream();
if (!pStream)
return;
......@@ -49,7 +49,7 @@ namespace PdfWriter
}
void CImageDict::LoadJpx(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight)
{
CFileStream* pStream = new CFileStream();
CImageFileStream* pStream = new CImageFileStream();
if (!pStream)
return;
......@@ -81,7 +81,7 @@ namespace PdfWriter
}
void CImageDict::LoadJb2(const wchar_t* wsFilePath, unsigned int unWidth, unsigned int unHeight)
{
CFileStream* pStream = new CFileStream();
CImageFileStream* pStream = new CImageFileStream();
if (!pStream)
return;
......@@ -97,7 +97,7 @@ namespace PdfWriter
}
void CImageDict::LoadCCITT4(const wchar_t* wsTempFile, unsigned int unWidth, unsigned int unHeight)
{
CFileStream* pStream = new CFileStream();
CImageFileStream* pStream = new CImageFileStream();
if (!pStream)
return;
......@@ -289,7 +289,7 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
// CJbig2Global
//----------------------------------------------------------------------------------------
CJbig2Global::CJbig2Global(CXref* pXref) : CDictObject(pXref, true)
CJbig2Global::CJbig2Global(CXref* pXref) : CDictObject(pXref)
{
m_pXref = pXref;
m_pContext = jbig2_init(0.85, 0.5, -1, -1, false, -1);
......
......@@ -334,7 +334,7 @@ namespace PdfWriter
m_unPredictor = STREAM_PREDICTOR_NONE;
m_pStream = NULL;
}
CDictObject::CDictObject(CXref* pXref, bool bMemoryStream, const wchar_t* wsTempFile, unsigned int unCheckSum)
CDictObject::CDictObject(CXref* pXref)
{
m_unFilter = STREAM_FILTER_NONE;
m_unPredictor = STREAM_PREDICTOR_NONE;
......@@ -348,13 +348,7 @@ namespace PdfWriter
Add("Length", (CObjectBase*)pLength);
if (bMemoryStream)
m_pStream = new CMemoryStream(STREAM_BUF_SIZ);
else
{
m_pStream = new CFileStream();
((CFileStream*)m_pStream)->OpenTempFile(wsTempFile, unCheckSum);
}
m_pStream = new CMemoryStream(STREAM_BUF_SIZ);
}
CDictObject::~CDictObject()
{
......
......@@ -297,7 +297,7 @@ namespace PdfWriter
{
public:
CDictObject();
CDictObject(CXref* pXref, bool bMemoryStream = true, const wchar_t* wsTempFile = NULL, unsigned int unCheckSum = 0);
CDictObject(CXref* pXref);
virtual ~CDictObject();
virtual EObjectType GetType() const
{
......
......@@ -766,12 +766,27 @@ namespace PdfWriter
CMatrix oCTM = m_pGrState->m_oMatrix;
// перемножаем матрицы oCTM(новая)= oCTM(преобразования(которая параметрами задана)) x oCTM(старая)
m_pGrState->m_oMatrix.m11 = oCTM.m11 * dM11 + oCTM.m12 * dM21;
m_pGrState->m_oMatrix.m12 = oCTM.m11 * dM12 + oCTM.m12 * dM22;
m_pGrState->m_oMatrix.m21 = oCTM.m21 * dM11 + oCTM.m22 * dM21;
m_pGrState->m_oMatrix.m22 = oCTM.m21 * dM12 + oCTM.m22 * dM22;
m_pGrState->m_oMatrix.x = oCTM.x + dX * oCTM.m11 + dY * oCTM.m21;
m_pGrState->m_oMatrix.y = oCTM.y + dX * oCTM.m12 + dY * oCTM.m22;
m_pGrState->m_oMatrix.m11 = dM11 * oCTM.m11 + dM12 * oCTM.m21;
m_pGrState->m_oMatrix.m12 = dM11 * oCTM.m12 + dM12 * oCTM.m22;
m_pGrState->m_oMatrix.m21 = dM21 * oCTM.m11 + dM22 * oCTM.m21;
m_pGrState->m_oMatrix.m22 = dM21 * oCTM.m12 + dM22 * oCTM.m22;
m_pGrState->m_oMatrix.x = dX * oCTM.m11 + dY * oCTM.m21 + oCTM.x;
m_pGrState->m_oMatrix.y = dX * oCTM.m12 + dY * oCTM.m22 + oCTM.y;
}
void CPage::SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY)
{
CMatrix oInverse = m_pGrState->m_oMatrix.Inverse();
CMatrix oResult;
oResult.m11 = dM11 * oInverse.m11 + dM12 * oInverse.m21;
oResult.m12 = dM11 * oInverse.m12 + dM12 * oInverse.m22;
oResult.m21 = dM21 * oInverse.m11 + dM22 * oInverse.m21;
oResult.m22 = dM21 * oInverse.m12 + dM22 * oInverse.m22;
oResult.x = dX * oInverse.m11 + dY * oInverse.m21 + oInverse.x;
oResult.y = dX * oInverse.m12 + dY * oInverse.m22 + oInverse.y;
if (!oResult.IsIdentity())
Concat(oResult.m11, oResult.m12, oResult.m21, oResult.m22, oResult.x, oResult.y);
}
void CPage::Clip()
{
......
......@@ -83,6 +83,7 @@ namespace PdfWriter
void SetStrokeColor(unsigned char unR, unsigned char unG, unsigned char unB);
void SetFillColor(unsigned char unR, unsigned char unG, unsigned char unB);
void Concat(double dM11, double dM12, double dM21, double dM22, double dX, double dY);
void SetTransform(double dM11, double dM12, double dM21, double dM22, double dX, double dY);
void SetExtGrState(CExtGrState* pExtGrState);
void AddAnnotation(CAnnotation* pAnnot);
void DrawShading(CShading* pShading);
......
......@@ -7,7 +7,7 @@ namespace PdfWriter
//----------------------------------------------------------------------------------------
// CPattern
//----------------------------------------------------------------------------------------
CPattern::CPattern(CXref* pXref) : CDictObject(pXref, true)
CPattern::CPattern(CXref* pXref) : CDictObject(pXref)
{
}
//----------------------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -156,15 +156,43 @@ namespace PdfWriter
{
return StreamFile;
}
bool OpenFile(const std::wstring& wsFilePath, bool bWrite = false);
private:
NSFile::CFileBinary m_oFile;
std::wstring m_wsFilePath;
};
class CImageFileStream : public CStream
{
public:
CImageFileStream();
~CImageFileStream();
bool IsEof();
void Write(const BYTE* pBuffer, unsigned int unSize);
void Read(BYTE* pBuffer, unsigned int* punSize);
void Seek(int nPos, EWhenceMode eMode);
int Tell();
void Close();
unsigned int Size();
EStreamType GetType()
{
return StreamFile;
}
bool OpenFile(const std::wstring& wsFilePath, bool bWrite = false);
bool OpenTempFile(const std::wstring& wsFilePath = L"", unsigned int unCheckSum = 0);
private:
bool OpenFile();
void CloseFile();
private:
NSFile::CFileBinary m_oFile;
std::wstring m_wsFilePath;
bool m_bDelete;
int m_nFilePos;
int m_nFileSize;
};
}
......
......@@ -58,7 +58,18 @@ namespace PdfWriter
x = 0;
y = 0;
}
bool IsIdentity() const
{
if (abs(m11 - 1) < 0.001
&& abs(m12) < 0.001
&& abs(m21) < 0.001
&& abs(m22 - 1) < 0.001
&& abs(x) < 0.001
&& abs(y) < 0.001)
return true;
return false;
}
void Apply(double& dX, double& dY)
{
double _x = dX;
......@@ -79,6 +90,23 @@ namespace PdfWriter
return true;
}
CMatrix Inverse()
{
CMatrix oInverse;
double dDet = m11 * m22 - m12 * m21;
if (dDet < 0.0001 && dDet > 0.0001)
return oInverse;
oInverse.m11 = m22 / dDet;
oInverse.m12 = -m12 / dDet;
oInverse.m21 = -m21 / dDet;
oInverse.m22 = m22 / dDet;
oInverse.x = y * m21 / dDet - x * m22 / dDet;
oInverse.y = x * m12 / dDet - y * m11 / dDet;
return oInverse;
}
public:
......
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