Files
core/PdfReader/Src/RendererOutputDev.cpp
Ilya.Kirillov eb965c1d6d Добавлен новый проект PdfReader для кроссплатформенного чтения Pdf.
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62480 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:01:53 +03:00

3640 lines
117 KiB
C++

#include "GState.h"
#include "GFont.h"
#include "File.h"
#include "CMap.h"
#include "Dict.h"
#include "Stream.h"
#include "FontFileTrueType.h"
#include "FontFileType1C.h"
#include "CharCodeToUnicode.h"
#include "RendererOutputDev.h"
#include "XmlUtils.h"
#include "../../DesktopEditor/graphics/Image.h"
#include "../../DesktopEditor/fontengine/ApplicationFonts.h"
#include "../../DesktopEditor/common/File.h"
#include "../../DesktopEditor/common/Array.h"
// TODO: 1. Ïåðåçàïèñü â PDF íå áóäåò ðàáîòàòü èç-çà òîãî, ÷òî â ðåíäåðåðå óáðàíû íóæíûå ôóíêöèè
// 2. Ãðàäèåíòíûå çàëèâêè
// 3. FontManager->GetFontType
// 4. FontManager->GetNameIndex
// 5. m_pRenderer->SetAdditionalParam(L"TilingHtmlPattern", oWriter.GetXmlString());
// 6. Ïîäáîð øðèôòîâ íåîáõîäèìî ïåðåíåñòè â GlobalParams->FindFontFile
// 7. Äîáàâèòü îáðàáîòêó ñòàíäàðòíûõ 14 øðèôòîâ
// 8. Â èäåíòåôèêàöèþ øðèôòà ê ïóòþ äîáàâèòü íîìåð øðèôòà â ôàéëå
// 9. Ðåàëèçîâàòü ëèíåéíûé è ðàäèàëüíûé ãðàäèåíòû
namespace PdfReader
{
//--------------------------------------------------------------------------------------
// CFontList
//--------------------------------------------------------------------------------------
CFontList::CFontList()
{
m_oCS.InitializeCriticalSection();
m_oFontMap.clear();
}
CFontList::~CFontList()
{
m_oCS.DeleteCriticalSection();
Clear();
}
void CFontList::LoadFromFile(std::wstring wsDirPath)
{
return;
//Clear();
//CStringW wsFilePath = wsDirPath + CStringW( _T("/FontList.rsc") );
//XmlUtils::CXmlNode oMainNode;
//if ( !oMainNode.FromXmlFile( wsFilePath ) )
// return;
//if ( _T("PDFFontList") == oMainNode.GetName() )
//{
// XmlUtils::CXmlNodes oFonts;
// oMainNode.GetNodes( _T("Font"), oFonts );
// for ( int nIndex = 0; nIndex < oFonts.GetCount(); nIndex++ )
// {
// XmlUtils::CXmlNode oFont;
// Ref oRef;
// CStringW sFilePath;
// int nLength = 0;
// unsigned short *pCodeToGid = NULL, *pCodeToUnicode = NULL;
// if ( oFonts.GetAt( nIndex, oFont ) )
// {
// XmlUtils::CXmlNode oNode;
// CStringW sValue;
// if ( oFont.GetNode( _T("ID"), oNode ) )
// {
// sValue = oNode.GetAttribute( _T("num") );
// oRef.nNum = XmlUtils::GetInteger( sValue );
// sValue = oNode.GetAttribute( _T("gen") );
// oRef.nGen = XmlUtils::GetInteger( sValue );
// }
// if ( oFont.GetNode( _T("FilePath"), oNode ) )
// {
// sFilePath = oNode.GetAttribute( _T("value") );
// }
// if ( oFont.GetNode( _T("CodeToGid"), oNode ) )
// {
// sValue = oNode.GetAttribute( _T("length") );
// nLength = XmlUtils::GetInteger( sValue );
// pCodeToGid = (unsigned short *)MemUtilsMalloc( sizeof(unsigned short) * nLength );
// if ( !pCodeToGid )
// return;
// XmlUtils::CXmlNodes oArray;
// oNode.GetNodes( _T("Entry"), oArray );
// for ( int nCurIndex = 0; nCurIndex < oArray.GetCount() && nCurIndex < nLength; nCurIndex++ )
// {
// XmlUtils::CXmlNode oArrayItem;
// if ( oArray.GetAt( nCurIndex, oArrayItem ) )
// {
// sValue = oArrayItem.GetAttribute( _T("value") );
// pCodeToGid[nCurIndex] = XmlUtils::GetInteger( sValue );
// }
// else
// pCodeToGid[nCurIndex] = 0;
// }
// }
// if ( oFont.GetNode( _T("CodeToUnicode"), oNode ) )
// {
// sValue = oNode.GetAttribute( _T("length") );
// nLength = XmlUtils::GetInteger( sValue );
// pCodeToUnicode = (unsigned short *)MemUtilsMalloc( sizeof(unsigned short) * nLength );
// if ( !pCodeToUnicode )
// return;
// XmlUtils::CXmlNodes oArray;
// oNode.GetNodes( _T("Entry"), oArray );
// for ( int nCurIndex = 0; nCurIndex < oArray.GetCount() && nCurIndex < nLength; nCurIndex++ )
// {
// XmlUtils::CXmlNode oArrayItem;
// if ( oArray.GetAt( nCurIndex, oArrayItem ) )
// {
// sValue = oArrayItem.GetAttribute( _T("value") );
// pCodeToUnicode[nCurIndex] = XmlUtils::GetInteger( sValue );
// }
// else
// pCodeToUnicode[nCurIndex] = 0;
// }
// }
// }
// Add( oRef, sFilePath, pCodeToGid, pCodeToUnicode, nLength );
// }
//}
}
void CFontList::SaveToFile(std::wstring wsDirPath)
{
return;
//CStringW wsFilePath = wsDirPath + CStringW( _T("/FontList.rsc") );
//XmlUtils::CXmlWriter oWriter;
//oWriter.WriteNodeBegin( _T("PDFFontList") );
//for ( int nIndex = 0; nIndex < (int)m_arrList.GetCount(); nIndex++ )
//{
// TFontEntry oEntry = m_arrList.GetAt( nIndex );
// oWriter.WriteNodeBegin( _T("Font") );
// oWriter.WriteNodeBegin( _T("ID"), true );
// oWriter.WriteAttribute( _T("num"), oEntry.oRef.nNum );
// oWriter.WriteAttribute( _T("gen"), oEntry.oRef.nGen );
// oWriter.WriteNodeEnd( _T("ID"), true, true );
// oWriter.WriteNodeBegin( _T("FilePath"), true );
// oWriter.WriteAttribute( _T("value"), oEntry.wsFilePath );
// oWriter.WriteNodeEnd( _T("FilePath"), true, true );
// if ( NULL != oEntry.pCodeToGID )
// {
// oWriter.WriteNodeBegin( _T("CodeToGid"), true );
// oWriter.WriteAttribute( _T("length"), oEntry.nLen );
// oWriter.WriteNodeEnd( _T("CodeToGid"), true, false );
// for ( int nCurIndex = 0; nCurIndex < oEntry.nLen; nCurIndex++ )
// {
// oWriter.WriteNodeBegin( _T("Entry"), true );
// oWriter.WriteAttribute( _T("value"), oEntry.pCodeToGID[nCurIndex] );
// oWriter.WriteNodeEnd( _T("Entry"), true, true );
// }
// oWriter.WriteNodeEnd( _T("CodeToGid") );
// }
// if ( NULL != oEntry.pCodeToUnicode )
// {
// oWriter.WriteNodeBegin( _T("CodeToUnicode"), true );
// oWriter.WriteAttribute( _T("length"), oEntry.nLen );
// oWriter.WriteNodeEnd( _T("CodeToUnicode"), true, false );
// for ( int nCurIndex = 0; nCurIndex < oEntry.nLen; nCurIndex++ )
// {
// oWriter.WriteNodeBegin( _T("Entry"), true );
// oWriter.WriteAttribute( _T("value"), oEntry.pCodeToUnicode[nCurIndex] );
// oWriter.WriteNodeEnd( _T("Entry"), true, true );
// }
// oWriter.WriteNodeEnd( _T("CodeToUnicode") );
// }
// oWriter.WriteNodeEnd( _T("Font") );
//}
//oWriter.WriteNodeEnd( _T("PDFFontList") );
//oWriter.SaveToFile( wsFilePath );
}
bool CFontList::Find(Ref oRef, TFontEntry *pEntry)
{
CTemporaryCS* pCS = new CTemporaryCS(&m_oCS);
bool bResult = (NULL != (pEntry = Lookup(oRef)));
if (bResult)
{
// Øðèôò íàøåëñÿ, íî ïîêà èì ïîëüçîâàòüñÿ íåëüçÿ, ïîòîìó ÷òî îí çàãðóæàåòñÿ â ïàðàëëåëüíîì ïîòîêå
while (!pEntry->bAvailable)
Sleep(10);
}
RELEASEOBJECT(pCS);
return bResult;
}
bool CFontList::Find2(Ref oRef, TFontEntry **ppEntry)
{
CTemporaryCS* pCS = new CTemporaryCS(&m_oCS);
bool bResult = (NULL != ((*ppEntry) = Lookup(oRef)));
if (bResult)
{
// Øðèôò íàøåëñÿ, íî ïîêà èì ïîëüçîâàòüñÿ íåëüçÿ, ïîòîìó ÷òî îí çàãðóæàåòñÿ â ïàðàëëåëüíîì ïîòîêå
while (!(*ppEntry)->bAvailable)
Sleep(10);
}
if (!bResult)
{
(*ppEntry) = Add(oRef, L"", NULL, NULL, 0, 0);
(*ppEntry)->bAvailable = false;
}
RELEASEOBJECT(pCS);
return bResult;
}
TFontEntry* CFontList::Add(Ref oRef, std::wstring wsFileName, unsigned short *pCodeToGID, unsigned short *pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode)
{
// Äàííàÿ ôóíêöèÿ ïðèõîäèò òîëüêî èç Find2, ïîýòîìó ïðîâåðÿòü åñòü ëè äàííûé øðèôò óæå íå íàäî
CTemporaryCS* pCS = new CTemporaryCS(&m_oCS);
TFontEntry *pNewEntry = new TFontEntry;
pNewEntry->oRef.nGen = oRef.nGen;
pNewEntry->oRef.nNum = oRef.nNum;
pNewEntry->wsFilePath = wsFileName;
pNewEntry->pCodeToGID = pCodeToGID;
pNewEntry->pCodeToUnicode = pCodeToUnicode;
pNewEntry->unLenGID = unLenGID;
pNewEntry->unLenUnicode = unLenUnicode;
Add(oRef, pNewEntry);
RELEASEOBJECT(pCS);
return pNewEntry;
}
void CFontList::Clear()
{
for (auto const &oIt : m_oFontMap)
{
TFontEntry *pEntry = oIt.second;
if (NULL != pEntry)
{
MemUtilsFree(pEntry->pCodeToGID);
MemUtilsFree(pEntry->pCodeToUnicode);
}
delete pEntry;
}
m_oFontMap.clear();
}
bool CFontList::GetFont(Ref *pRef, TFontEntry *pEntry)
{
TFontEntry* pFindEntry = Lookup(*pRef);
if (NULL == pFindEntry)
return false;
*pEntry = *pFindEntry;
return true;
}
//--------------------------------------------------------------------------------------
// RendererOutputDev
//--------------------------------------------------------------------------------------
RendererOutputDev::RendererOutputDev(GlobalParams *pGlobalParams, IRenderer *pRenderer, CFontManager* pFontManager, CFontList *pFontList)
{
m_pFontManager = pFontManager;
m_pGlobalParams = pGlobalParams;
m_pFontList = pFontList;
m_bTiling = false;
m_pBufferTextClip = NULL;
m_pClip = NULL;
m_lRendererType = c_nUnknownRenderer;
m_pRenderer = pRenderer;
m_bUseAxialShaded = false;
m_bUseRadialShaded = false;
if (NULL != m_pRenderer)
{
m_pRenderer->put_PenColor(0);
m_pRenderer->put_PenAlpha(255);
m_pRenderer->put_PenSize(1);
m_pRenderer->put_FontName(L"Arial");
m_pRenderer->put_FontStyle(0);
m_pRenderer->put_FontSize(10.0);
m_pRenderer->get_Type(&m_lRendererType);
//if (c_nSWFRenderer == m_lRendererType)
//{
// m_bUseAxialShaded = true;
// m_bUseRadialShaded = true;
//}
}
m_pbBreak = NULL;
m_bTransparentGroup = false;
m_bTransparentGroupSoftMask = false;
m_pTransparentGroupSoftMask = NULL;
//m_oFontList.LoadFromFile( m_pGlobalParams->GetTempFolder() );
//// Òåñòîâûé ïðèìåð
//m_pRenderer->NewPage();
//m_pRenderer->BeginCommand( c_nPageType );
//m_pRenderer->SetWidth( 100.0f );
//m_pRenderer->SetHeight( 100.0f );
//m_oFont.SetFontSize( 1.0 );
//m_oPen.SetSize( 0.3 );
//m_oPen.SetAlpha( 128 );
//m_pRenderer->SetFont( m_oFont.ToXmlString().AllocSysString() );
//m_pRenderer->SetShadow( m_oShadow.ToXmlString().AllocSysString() );
//m_pRenderer->SetPen( m_oPen.ToXmlString().AllocSysString() );
//m_pRenderer->PathCommandMoveTo( 0, 50 );
//m_pRenderer->PathCommandLineTo( 100, 50 );
//m_pRenderer->DrawPath( c_nStroke );
//m_pRenderer->PathCommandMoveTo( 50, 0 );
//m_pRenderer->PathCommandLineTo( 50, 100 );
//m_pRenderer->DrawPath( c_nStroke );
//
//m_oPen.SetSize( 0.3 );
//m_oPen.SetAlpha( 255 );
//m_pRenderer->SetPen( m_oPen.ToXmlString().AllocSysString() );
//IAVSOfficeRendererTemplate2 *pRenderer2 = NULL;
//m_pRenderer->QueryInterface( __uuidof(AVSOfficeEditor::IAVSOfficeRendererTemplate2), (void**)&pRenderer2 );
//double pNewTm[6], arrMatrix[6];
//double dAscent = 0.905;
//double dDescent = -0.211;
//double dKoef = ( dAscent - fabs( dDescent ) ) * 1;
//double pCTM[6] = { 10, 0, 0, 10, 50, 50};
//pNewTm[0] = 1;//pTm[0];
//pNewTm[1] = 0;//pTm[1];
//pNewTm[2] = -0;//pTm[2];
//pNewTm[3] = -1;//pTm[3];
//pNewTm[4] = 0 + 0 * dKoef;
//pNewTm[5] = 0 + 1 * dKoef;
//arrMatrix[0] = pNewTm[0] * pCTM[0] + pNewTm[1] * pCTM[2];
//arrMatrix[1] = -(pNewTm[0] * pCTM[1] + pNewTm[1] * pCTM[3]);
//arrMatrix[2] = pNewTm[2] * pCTM[0] + pNewTm[3] * pCTM[2];
//arrMatrix[3] = -(pNewTm[2] * pCTM[1] + pNewTm[3] * pCTM[3]);
//arrMatrix[4] = pNewTm[4] * pCTM[0] + pNewTm[5] * pCTM[2] + pCTM[4];
//arrMatrix[5] = -(pNewTm[4] * pCTM[1] + pNewTm[5] * pCTM[3] + pCTM[5]) + 100;
//double dAcsentFactor = ( ( fabs(-0.324) + fabs(1.005) ) - ( dAscent + fabs( dDescent ) ) ) / 2 + dAscent;
//double dAscentShiftX = -arrMatrix[2] * dAcsentFactor;
//double dAscentShiftY = -arrMatrix[3] * dAcsentFactor;
////arrMatrix[4] += dAscentShiftX;
////arrMatrix[5] += dAscentShiftY;
//pRenderer2->SetTransform( arrMatrix[0], arrMatrix[1], arrMatrix[2], arrMatrix[3], arrMatrix[4], arrMatrix[5] );
//m_pRenderer->PathCommandMoveTo( -0.664, -0.324 );
//m_pRenderer->PathCommandLineTo( 2.000, -0.324 );
//m_pRenderer->PathCommandLineTo( 2.000, 1.005 );
//m_pRenderer->PathCommandLineTo( -0.664, 1.005 );
//m_pRenderer->PathCommandClose();
//m_pRenderer->DrawPath( c_nStroke );
//m_pRenderer->CommandDrawText( _T("A"), 0, 0, 0, 0, 0 );
//double dAlpha = 0*(3.14 / 180.f) * 160;
//pRenderer2->SetTransform( cos( dAlpha ), -sin( dAlpha ), -sin( dAlpha ), -cos( dAlpha ), 50, 50 );
//m_pRenderer->PathCommandMoveTo( 0, 0 );
//m_pRenderer->PathCommandLineTo( 10, 0 );
//m_pRenderer->PathCommandLineTo( 10, 10 );
//m_pRenderer->PathCommandLineTo( 0, 10 );
//m_pRenderer->PathCommandClose();
//m_pRenderer->DrawPath( c_nStroke );
//m_pRenderer->EndCommand( c_nPageType );
//RELEASEINTERFACE( pRenderer2 );
}
RendererOutputDev::~RendererOutputDev()
{
m_pRenderer = NULL;
if (m_pClip)
delete m_pClip;
if (m_pBufferTextClip)
delete m_pBufferTextClip;
if (m_pTransparentGroupSoftMask)
delete[]m_pTransparentGroupSoftMask;
}
void RendererOutputDev::StartPage(int nPageIndex, GrState *pGState)
{
m_pRenderer->NewPage();
m_pRenderer->BeginCommand(c_nPageType);
// Ïåðåâîäèì ïóíêòû â ìèëëèìåòðû
double dPageHeight = PDFCoordsToMM(pGState->GetPageHeight());
double dPageWidth = PDFCoordsToMM(pGState->GetPageWidth());
m_arrMatrix[0] = 1; m_arrMatrix[1] = 0;
m_arrMatrix[2] = 0; m_arrMatrix[3] = 1;
m_arrMatrix[4] = 0; m_arrMatrix[5] = 0;
m_pRenderer->put_Width(dPageWidth);
m_pRenderer->put_Height(dPageHeight);
m_bTransparentGroup = false;
m_bTransparentGroupSoftMask = false;
if (m_pTransparentGroupSoftMask)
delete[]m_pTransparentGroupSoftMask;
m_pTransparentGroupSoftMask = NULL;
}
void RendererOutputDev::EndPage()
{
m_pRenderer->EndCommand(c_nPageType);
}
void RendererOutputDev::SaveGState(GrState *pGState)
{
UpdateAll(pGState);
}
void RendererOutputDev::RestoreGState(GrState *pGState)
{
UpdateAll(pGState);
}
void RendererOutputDev::UpdateCTM(GrState *pGState, double dMatrix11, double dMatrix12, double dMatrix21, double dMatrix22, double dMatrix31, double dMatrix32)
{
}
void RendererOutputDev::UpdateLineDash(GrState *pGState)
{
double *pDash = NULL;
int nSize = 0;
double dStart = 0;
pGState->GetLineDash(&pDash, &nSize, &dStart);
if (0 == nSize) // Solid
{
m_pRenderer->put_PenDashStyle(Aggplus::DashStyleSolid);
m_pRenderer->put_PenDashOffset(0);
}
else
{
m_pRenderer->PenDashPattern(pDash, (long)nSize);
m_pRenderer->put_PenDashStyle(Aggplus::DashStyleCustom);
m_pRenderer->put_PenDashOffset(dStart);
}
}
void RendererOutputDev::UpdateFlatness(GrState *pGState)
{
}
void RendererOutputDev::UpdateLineJoin(GrState *pGState)
{
int nJoinStyle = pGState->GetLineJoin();
if (1 == nJoinStyle)
nJoinStyle = 2;
else if (2 == nJoinStyle)
nJoinStyle = 1;
m_pRenderer->put_PenLineJoin(nJoinStyle);
}
void RendererOutputDev::UpdateLineCap(GrState *pGState)
{
int nCapStyle = pGState->GetLineCap();
if (1 == nCapStyle)
nCapStyle = 2;
else if (2 == nCapStyle)
nCapStyle = 1;
m_pRenderer->put_PenLineStartCap(nCapStyle);
m_pRenderer->put_PenLineEndCap(nCapStyle);
}
void RendererOutputDev::UpdateMiterLimit(GrState *pGState)
{
}
void RendererOutputDev::UpdateLineWidth(GrState *pGState)
{
m_pRenderer->put_PenSize(PDFCoordsToMM(pGState->GetLineWidth()));
}
void RendererOutputDev::UpdateStrokeAdjust(GrState *pGState)
{
}
void RendererOutputDev::UpdateFillColor(GrState *pGState)
{
GrColor *pColor = pGState->GetFillColor();
GrColorSpace *pColorSpace = pGState->GetFillColorSpace();
DWORD dwColor = pColorSpace->GetDwordColor(pColor);
m_pRenderer->put_BrushColor1(dwColor);
m_pRenderer->put_BrushColor2(dwColor);
}
void RendererOutputDev::UpdateStrokeColor(GrState *pGState)
{
GrColor *pColor = pGState->GetStrokeColor();
GrColorSpace *pColorSpace = pGState->GetStrokeColorSpace();
DWORD dwColor = pColorSpace->GetDwordColor(pColor);
m_pRenderer->put_PenColor(dwColor);
}
void RendererOutputDev::UpdateBlendMode(GrState *pGState)
{
}
void RendererOutputDev::UpdateFillOpacity(GrState *pGState)
{
m_pRenderer->put_BrushAlpha1(min(255, max(0, int(pGState->GetFillOpacity() * 255))));
m_pRenderer->put_BrushAlpha2(min(255, max(0, int(pGState->GetFillOpacity() * 255))));
}
void RendererOutputDev::UpdateStrokeOpacity(GrState *pGState)
{
m_pRenderer->put_PenAlpha(min(255, max(0, int(pGState->GetStrokeOpacity() * 255))));
}
void RendererOutputDev::UpdateAll(GrState *pGState)
{
UpdateCTM(pGState, pGState->GetCTM()[0], pGState->GetCTM()[1], pGState->GetCTM()[2], pGState->GetCTM()[3], pGState->GetCTM()[4], pGState->GetCTM()[5]);
UpdateLineDash(pGState);
UpdateFlatness(pGState);
UpdateLineJoin(pGState);
UpdateLineCap(pGState);
UpdateMiterLimit(pGState);
UpdateLineWidth(pGState);
UpdateStrokeAdjust(pGState);
UpdateFillColorSpace(pGState);
UpdateFillColor(pGState);
UpdateStrokeColorSpace(pGState);
UpdateStrokeColor(pGState);
UpdateBlendMode(pGState);
UpdateFillOpacity(pGState);
UpdateStrokeOpacity(pGState);
UpdateFont(pGState);
UpdateClip(pGState);
}
void RendererOutputDev::UpdateRender(GrState *pGState)
{
}
void RendererOutputDev::UpdateFont(GrState *pGState)
{
// Ïðîâåðÿåì íàëè÷èå ñïèñêà ñî øðèôòàìè
if (NULL == m_pFontList)
return;
GrFont *pFont = pGState->GetFont();
if (NULL == pFont)
return;
m_pRenderer->put_FontSize(pGState->GetFontSize());
//m_oFont.Size = pGState->GetFontSize();
std::wstring wsFileName = L"";
std::wstring wsFontName = L"";
TFontEntry *pEntry = NULL;
if (!m_pFontList->Find2((*pFont->GetID()), &pEntry))
{
GrFontType eFontType = pFont->GetType();
if (fontType3 == eFontType) // FontType3 îáðàáàòûâàåòñÿ îòäåëüíîé êîìàíäîé
{
pEntry->bAvailable = true;
return;
}
std::wstring wsTempFileName = L"";
Ref oEmbRef;
// 1. Åñëè øðèôò âíåäðåííûé, òîãäà ñêèäûâàåì åãî â òåìïîâûé ôàéë.
// 2. Åñëè øðèôò ëåæèò âíå ïäô, à â ñàìîì ïäô åñòü ññûëêà íà íåãî, òîãäà èñïîëüçóåì ýòó ññûëêó.
// 3.  ïðîòèâíîì ñëó÷àå ïîäáèðàåì øðèôò.
if (pFont->GetEmbeddedFontFileRef(&oEmbRef))
{
std::wstring wsExt;
switch (pFont->GetType())
{
case fontType1: wsExt = L".pfb_t1"; break;
case fontType1C: wsExt = L".pfb_t1c"; break;
case fontType1COT: wsExt = L".pfb_t1cot"; break;
case fontTrueType: wsExt = L".ttf"; break;
case fontTrueTypeOT: wsExt = L".otf"; break;
case fontCIDType0: wsExt = L".cid_0"; break;
case fontCIDType0C: wsExt = L".cid_0c"; break;
case fontCIDType0COT: wsExt = L".cid_0cot"; break;
case fontCIDType2: wsExt = L".cid_2"; break;
case fontCIDType2OT: wsExt = L".cid_2ot"; break;
}
FILE* pTempFile = NULL;
if (!NSFile::CFileBinary::OpenTempFile(&wsTempFileName, &pTempFile, L"wb", (wchar_t*)wsExt.c_str(), (wchar_t*)m_pGlobalParams->GetTempFolder().c_str(), NULL))
{
if (L"" != wsTempFileName)
NSFile::CFileBinary::Remove(wsTempFileName);
pEntry->bAvailable = true;
return;
}
Object oReferenceObject, oStreamObject;
oReferenceObject.InitRef(oEmbRef.nNum, oEmbRef.nGen);
oReferenceObject.Fetch(m_pXref, &oStreamObject);
oReferenceObject.Free();
if (!oStreamObject.IsStream())
{
// Âíåäðåííûé øðèôò íåïðàâèëüíî çàïèñàí
oStreamObject.Free();
fclose(pTempFile);
if (L"" != wsTempFileName)
NSFile::CFileBinary::Remove(wsTempFileName);
pEntry->bAvailable = true;
return;
}
oStreamObject.StreamReset();
int nChar;
while ((nChar = oStreamObject.StreamGetChar()) != EOF)
{
fputc(nChar, pTempFile);
}
oStreamObject.StreamClose();
oStreamObject.Free();
fclose(pTempFile);
wsFileName = wsTempFileName;
// Äëÿ øðèôòîâ òèïà Type1 íóæíî äîïèñàòü Afm ôàéë ñ ìåòðèêàìè
if (fontType1 == pFont->GetType() || fontType1C == pFont->GetType() || fontType1COT == pFont->GetType())
{
std::wstring wsSplitFileName, wsSplitFileExt;
SpitPathExt(wsFileName, &wsSplitFileName, &wsSplitFileExt);
std::wstring wsAfmPath = wsSplitFileName + L".afm";
NSFile::CFileBinary oFile;
oFile.CreateFileW(wsAfmPath);
FILE* pFile = oFile.GetFileNative();
if (pFile)
{
Ref *pRef = pFont->GetID();
Object oRefObject, oFontObject;
oRefObject.InitRef(pRef->nNum, pRef->nGen);
oRefObject.Fetch(m_pXref, &oFontObject);
oRefObject.Free();
if (oFontObject.IsDict())
{
char *sFontName = NULL, *sFontFamily = NULL, *sFontStretch = NULL;
int nFontWeight = 0, nItalicAngle = 0, nAscent = 0, nDescent = 0, nLeading = 0;
int nCapHeight = 0, nXHeight = 0, nStemV = 0, nStemH = 0, nAvgWidth = 0, nMaxWidth = 0, nMissingWidth = 0;
Array *pBBox = NULL;
int arrBBox[4] ={ 0, 0, 0, 0 };
Dict *pFontDict = oFontObject.GetDict();
Object oFontDescriptor;
if (pFontDict->Search("FontDescriptor", &oFontDescriptor)->IsDict())
{
Object oDictItem;
// FontName
oFontDescriptor.DictLookup("FontName", &oDictItem);
if (oDictItem.IsName()) sFontName = oDictItem.GetName();
oDictItem.Free();
// FontFamily
oFontDescriptor.DictLookup("FontFamily", &oDictItem);
if (oDictItem.IsName()) sFontFamily = oDictItem.GetName();
oDictItem.Free();
// FontStretch
oFontDescriptor.DictLookup("FontStretch", &oDictItem);
if (oDictItem.IsName()) sFontStretch = oDictItem.GetName();
oDictItem.Free();
// FontWeight
oFontDescriptor.DictLookup("FontWeight", &oDictItem);
if (oDictItem.IsInt()) nFontWeight = oDictItem.GetInt();
oDictItem.Free();
// FontBBox
oFontDescriptor.DictLookup("FontBBox", &oDictItem);
if (oDictItem.IsArray()) pBBox = oDictItem.GetArray();
if (4 == pBBox->GetCount())
{
for (int nIndex = 0; nIndex < 4; nIndex++)
{
Object oArrayItem;
pBBox->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt())
arrBBox[nIndex] = oArrayItem.GetInt();
oArrayItem.Free();
}
}
oDictItem.Free();
// ItalicAngle
oFontDescriptor.DictLookup("ItalicAngle", &oDictItem);
if (oDictItem.IsInt()) nItalicAngle = oDictItem.GetInt();
oDictItem.Free();
// Ascent
oFontDescriptor.DictLookup("Ascent", &oDictItem);
if (oDictItem.IsInt()) nAscent = oDictItem.GetInt();
oDictItem.Free();
// Leading
oFontDescriptor.DictLookup("Leading", &oDictItem);
if (oDictItem.IsInt()) nLeading = oDictItem.GetInt();
oDictItem.Free();
// CapHeight
oFontDescriptor.DictLookup("CapHeight", &oDictItem);
if (oDictItem.IsInt()) nCapHeight = oDictItem.GetInt();
oDictItem.Free();
// XHeight
oFontDescriptor.DictLookup("XHeight", &oDictItem);
if (oDictItem.IsInt()) nXHeight = oDictItem.GetInt();
oDictItem.Free();
// StemV
oFontDescriptor.DictLookup("StemV", &oDictItem);
if (oDictItem.IsInt()) nStemV = oDictItem.GetInt();
oDictItem.Free();
// StemH
oFontDescriptor.DictLookup("StemH", &oDictItem);
if (oDictItem.IsInt()) nStemH = oDictItem.GetInt();
oDictItem.Free();
// Descent
oFontDescriptor.DictLookup("Descent", &oDictItem);
if (oDictItem.IsInt()) nDescent = oDictItem.GetInt();
oDictItem.Free();
// AvgWidth
oFontDescriptor.DictLookup("AvgWidth", &oDictItem);
if (oDictItem.IsInt()) nAvgWidth = oDictItem.GetInt();
oDictItem.Free();
// MaxWidth
oFontDescriptor.DictLookup("MaxWidth", &oDictItem);
if (oDictItem.IsInt()) nMaxWidth = oDictItem.GetInt();
oDictItem.Free();
// MissingWidth
oFontDescriptor.DictLookup("MissingWidth", &oDictItem);
if (oDictItem.IsInt()) nMissingWidth = oDictItem.GetInt();
oDictItem.Free();
}
oFontDescriptor.Free();
fprintf(pFile, "StartFontMetrics 3.0\n");
if (NULL != sFontName) fprintf(pFile, "FontName %s\n", sFontName);
if (NULL != sFontFamily) fprintf(pFile, "FamilyName %s\n", sFontFamily);
if (nFontWeight >= 550) fprintf(pFile, "Weight Bold\n");
fprintf(pFile, "ItalicAngle %d\n", nItalicAngle);
fprintf(pFile, "FontBBox %d %d %d %d\n", arrBBox[0], arrBBox[1], arrBBox[2], arrBBox[3]);
fprintf(pFile, "CapHeight %d\n", nCapHeight);
fprintf(pFile, "XHeight %d\n", nXHeight);
fprintf(pFile, "Ascender %d\n", nAscent);
fprintf(pFile, "Descender %d\n", nDescent);
fprintf(pFile, "StdHW %d\n", nStemH);
fprintf(pFile, "StdHV %d\n", nStemV);
int nFirstChar = 0;
Object oDictItem;
pFontDict->Search("FirstChar", &oDictItem);
if (oDictItem.IsInt()) nFirstChar = oDictItem.GetInt();
oDictItem.Free();
int nLastChar = nFirstChar;
pFontDict->Search("LastChar", &oDictItem);
if (oDictItem.IsInt()) nLastChar = oDictItem.GetInt();
oDictItem.Free();
Array *pWidths = NULL;
pFontDict->Search("Widths", &oDictItem);
if (oDictItem.IsArray()) pWidths = oDictItem.GetArray();
int nCount = nLastChar - nFirstChar + 1;
Gr8BitFont *pT1Font = (Gr8BitFont *)pFont;
if (NULL != pWidths)
{
int nWidthsCount = pWidths->GetCount();
fprintf(pFile, "StartCharMetrics %d\n", nWidthsCount);
for (int nIndex = 0; nIndex < nWidthsCount; nIndex++)
{
int nWidth = nMissingWidth;
Object oArrayItem;
pWidths->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt()) nWidth = oArrayItem.GetInt();
oArrayItem.Free();
char **ppEncoding = pT1Font->GetEncoding();
if (NULL != ppEncoding && NULL != ppEncoding[nIndex])
fprintf(pFile, "C %d ; WX %d ; N %s ;\n", nIndex + nFirstChar, nWidth, ppEncoding[nIndex]);
else
fprintf(pFile, "C %d ; WX %d ;\n", nIndex + nFirstChar, nWidth);
}
fprintf(pFile, "EndCharMetrics\n");
}
oDictItem.Free();
}
fclose(pFile);
}
}
// Çàãðóçèì ñàì ôàéë ñî øðèôòîì, ÷òîáû òî÷íî îïðåäåëèòü åãî òèï
if (!m_pFontManager->LoadFontFromFile(wsFileName, 0, 10, 72, 72))
{
pEntry->bAvailable = true;
return;
}
// TODO: Ðåàëèçîâàòü m_pFontManager->GetFontType
std::wstring wsFontType = L"";
//m_pFontManager->GetFontType(&wsFontType);
if (L"TrueType" == wsFontType)
{
if (eFontType != fontType1COT && eFontType != fontTrueType
&& eFontType != fontTrueTypeOT && eFontType != fontCIDType0COT
&& eFontType != fontCIDType2 && eFontType != fontCIDType2OT)
{
if (eFontType == fontType1 || eFontType == fontType1C)
eFontType = fontType1COT;
else if (eFontType == fontCIDType0 || eFontType == fontCIDType0C)
eFontType = fontCIDType0COT;
}
}
else if (L"Type 1" == wsFontType)
{
if (eFontType != fontType1 && eFontType != fontType1C)
{
eFontType = fontType1;
}
}
else if (L"CID Type 1" == wsFontType)
{
if (eFontType != fontCIDType0 && eFontType != fontCIDType0C
&& eFontType != fontCIDType2OT && eFontType != fontCIDType0COT)
{
eFontType = fontCIDType0;
}
}
else if (L"CFF" == wsFontType)
{
if (eFontType != fontType1C && eFontType != fontType1COT
&& eFontType != fontTrueTypeOT && eFontType != fontCIDType0C
&& eFontType != fontCIDType0COT && eFontType != fontCIDType2OT)
{
if (eFontType == fontType1 || eFontType == fontTrueType)
eFontType = fontType1C;
else if (eFontType == fontCIDType0 || eFontType == fontCIDType2)
eFontType = fontCIDType0C;
}
}
}
else if (L"" == (wsFileName = pFont->GetExternalFontFilePath()))
{
// TODO: Ñíà÷àëà òóò ìû äîëæíû ïðîâåðèòü, åñëè èùåòñÿ îäèí èç 14 ñòàíäàðòíûõ øðèôòîâ,
// òîãäà ìû äîëæíû âåðíóòü ïóòü ê ñòàíäàðòíîìó øðèôòó.
CFontInfo* pFontInfo = NULL;
if (m_pFontManager)
{
Ref *pRef = pFont->GetID();
Object oRefObject, oFontObject;
oRefObject.InitRef(pRef->nNum, pRef->nGen);
oRefObject.Fetch(m_pXref, &oFontObject);
oRefObject.Free();
CFontSelectFormat oFontSelect;
std::wstring wsFontBaseName = pFont->GetBaseName()->GetWString();
if (oFontObject.IsDict())
{
Dict *pFontDict = oFontObject.GetDict();
Object oFontDescriptor;
if (pFontDict->Search("FontDescriptor", &oFontDescriptor)->IsDict())
{
Object oDictItem;
// FontName
oFontDescriptor.DictLookup("FontName", &oDictItem);
if (oDictItem.IsName())
oFontSelect.wsName = AStringToPWString(oDictItem.GetName());
else
oFontSelect.wsName = new std::wstring(wsFontBaseName);
oDictItem.Free();
// FontFamily
oFontDescriptor.DictLookup("FontFamily", &oDictItem);
oDictItem.Free();
// FontStretch
oFontDescriptor.DictLookup("FontStretch", &oDictItem);
oDictItem.Free();
// FontWeight
oFontDescriptor.DictLookup("FontWeight", &oDictItem);
oDictItem.Free();
// FontBBox
oFontDescriptor.DictLookup("FontBBox", &oDictItem);
oDictItem.Free();
// ItalicAngle
oFontDescriptor.DictLookup("ItalicAngle", &oDictItem);
if (oDictItem.IsInt() && 0 != oDictItem.GetInt()) oFontSelect.bItalic = new INT(1);
oDictItem.Free();
// Ascent
oFontDescriptor.DictLookup("Ascent", &oDictItem);
if (oDictItem.IsInt()) oFontSelect.shAscent = new SHORT(oDictItem.GetInt());
oDictItem.Free();
// Leading
oFontDescriptor.DictLookup("Leading", &oDictItem);
if (oDictItem.IsInt()) oFontSelect.shLineGap = new SHORT(oDictItem.GetInt());
oDictItem.Free();
// CapHeight
oFontDescriptor.DictLookup("CapHeight", &oDictItem);
if (oDictItem.IsInt()) oFontSelect.shCapHeight = new SHORT(oDictItem.GetInt());
oDictItem.Free();
// XHeight
oFontDescriptor.DictLookup("XHeight", &oDictItem);
if (oDictItem.IsInt()) oFontSelect.shXHeight = new SHORT(oDictItem.GetInt());
oDictItem.Free();
// StemV
oFontDescriptor.DictLookup("StemV", &oDictItem);
oDictItem.Free();
// StemH
oFontDescriptor.DictLookup("StemH", &oDictItem);
oDictItem.Free();
// Descent
oFontDescriptor.DictLookup("Descent", &oDictItem);
if (oDictItem.IsInt()) oFontSelect.shDescent = new SHORT(oDictItem.GetInt());
oDictItem.Free();
// AvgWidth
oFontDescriptor.DictLookup("AvgWidth", &oDictItem);
if (oDictItem.IsInt()) oFontSelect.shAvgCharWidth = new SHORT(oDictItem.GetInt());
oDictItem.Free();
// MaxWidth
oFontDescriptor.DictLookup("MaxWidth", &oDictItem);
oDictItem.Free();
// MissingWidth
oFontDescriptor.DictLookup("MissingWidth", &oDictItem);
oDictItem.Free();
}
else
oFontSelect.wsName = new std::wstring(wsFontBaseName);
oFontDescriptor.Free();
}
else
oFontSelect.wsName = new std::wstring(wsFontBaseName);
pFontInfo = m_pFontManager->GetFontInfoByParams(oFontSelect);
}
if (pFontInfo && L"" != pFontInfo->m_wsFontPath)
{
wsFileName = pFontInfo->m_wsFontPath;
eFontType = pFont->IsCIDFont() ? fontCIDType2 : fontTrueType;
}
else //  êðàéíåì ñëó÷àå, â äàííîì øðèôòå ïðîñòî íå ïèøåì íè÷åãî
{
pEntry->bAvailable = true;
return;
}
// Çàïèñûâàåì ôàéë ñ êîäèðîâêîé. (Ñïåöèàëüíî äëÿ ïåðåçàïèñè â PDF)
if (c_nPDFWriter == m_lRendererType)
{
std::wstring wsExt;
if (!pFont->IsCIDFont())
{
wsExt = L".non";
}
else if (pFont->IsCIDFont())
{
wsExt = L".cid_non";
}
FILE* pTempFile = NULL;
if (!NSFile::CFileBinary::OpenTempFile(&wsTempFileName, &pTempFile, L"wb", (wchar_t*)wsExt.c_str(), (wchar_t*)m_pGlobalParams->GetTempFolder().c_str(), NULL))
{
if (L"" != wsTempFileName)
NSFile::CFileBinary::Remove(wsTempFileName);
pEntry->bAvailable = true;
return;
}
fclose(pTempFile);
// Êîïèðóåì ôàéë, äëÿ ñîçäàíèÿ óíèêàëüíîãî èìåíè, ÷òîáû ñâÿçàòü ñ ôàéëîì ñ êîäèðîâêîé
if (NSFile::CFileBinary::Copy(wsFileName, wsTempFileName))
{
wsFileName = wsTempFileName;
}
else
{
NSFile::CFileBinary::Remove(wsTempFileName);
wsTempFileName = L"";
}
if (L"" != wsTempFileName)
{
std::wstring wsSplitFileName, wsSplitFileExt;
SpitPathExt(wsFileName, &wsSplitFileName, &wsSplitFileExt);
std::wstring wsEncodingPath = wsSplitFileName + L".enc";
CXmlWriter oXmlWriter;
Ref *pRef = pFont->GetID();
Object oRefObject, oFontObject;
oRefObject.InitRef(pRef->nNum, pRef->nGen);
oRefObject.Fetch(m_pXref, &oFontObject);
oRefObject.Free();
if (oFontObject.IsDict())
{
Dict *pFontDict = oFontObject.GetDict();
int nEncodingType = -1; // Îáúåêòà Encoding íåò
int nBaseEncoding = -1;
Object oDictItem;
pFontDict->Search("Encoding", &oDictItem);
if (oDictItem.IsDict())
{
nEncodingType = 1; // Encoding - èäåò îòäåëüíûì îáúåêòîì
Object oTemp;
oDictItem.DictLookup("BaseEncoding", &oTemp);
if (oTemp.IsName("MacRomanEncoding"))
nBaseEncoding = 0;
else if (oTemp.IsName("MacExpertEncoding"))
nBaseEncoding = 1;
else if (oTemp.IsName("WinAnsiEncoding"))
nBaseEncoding = 2;
oTemp.Free();
}
else if (oDictItem.IsName("MacRomanEncoding"))
{
nEncodingType = 0;
nBaseEncoding = 0;
}
else if (oDictItem.IsName("MacExpertEncoding"))
{
nEncodingType = 0;
nBaseEncoding = 1;
}
else if (oDictItem.IsName("WinAnsiEncoding"))
{
nEncodingType = 0;
nBaseEncoding = 2;
}
else
{
nEncodingType = -1;
}
oXmlWriter.WriteNodeBegin(L"Encoding", true);
oXmlWriter.WriteAttribute(L"type", nEncodingType);
oXmlWriter.WriteAttribute(L"base", nBaseEncoding);
oXmlWriter.WriteNodeEnd(L"Encoding", true, false);
// Differences
if (oDictItem.IsDict())
{
Object oDifferences;
oDictItem.DictLookup("Differences", &oDifferences);
if (oDifferences.IsArray())
{
int nArrayLen = oDifferences.ArrayGetLength();
oXmlWriter.WriteNodeBegin(L"Differences", true);
oXmlWriter.WriteAttribute(L"count", nArrayLen);
oXmlWriter.WriteNodeEnd(L"Differences", true, false);
for (int nIndex = 0; nIndex < nArrayLen; ++nIndex)
{
Object oTemp;
oDifferences.ArrayGet(nIndex, &oTemp);
if (oTemp.IsInt())
{
int nCode = oTemp.GetInt();
oXmlWriter.WriteNodeBegin(L"Code", true);
oXmlWriter.WriteAttribute(L"value", nCode);
oXmlWriter.WriteNodeEnd(L"Code", true, true);
}
else if (oTemp.IsName())
{
char *sName = oTemp.GetName();
oXmlWriter.WriteNodeBegin(L"Name", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(sName));
oXmlWriter.WriteNodeEnd(L"Name", true, true);
}
else
{
// TODO: Íåïðàâèëüíûé òèï çàïèñè
}
oTemp.Free();
}
oXmlWriter.WriteNodeEnd(L"Differences");
}
oDifferences.Free();
}
oDictItem.Free();
oXmlWriter.WriteNodeEnd(L"Encoding");
}
oFontObject.Free();
oXmlWriter.SaveToFile(wsEncodingPath);
}
}
}
// Çäåñü ìû ãðóçèì êîäèðîâêè
unsigned short *pCodeToGID = NULL, *pCodeToUnicode = NULL;
int nLen = 0;
CFontFileTrueType *pTTFontFile = NULL;
CFontFileType1C *pT1CFontFile = NULL;
switch (eFontType)
{
case fontType1:
case fontType1C:
case fontType1COT:
{
if (L"" != wsFileName)
{
char **ppEncoding = ((Gr8BitFont *)pFont)->GetEncoding();
if (!ppEncoding)
break;
if (!m_pFontManager)
break;
m_pFontManager->LoadFontFromFile(wsFileName, 0, 1, 72, 72);
pCodeToGID = (unsigned short *)MemUtilsMallocArray(256, sizeof(unsigned short));
if (!pCodeToGID)
break;
nLen = 256;
for (int nIndex = 0; nIndex < 256; ++nIndex)
{
pCodeToGID[nIndex] = 0;
char* sName = NULL;
if ((sName = ppEncoding[nIndex]))
{
unsigned short ushGID = 0;
// TODO: pFontManager->GetNameIndex
//m_pFontManager->GetNameIndex(AStringToWString(sName), &ushGID);
pCodeToGID[nIndex] = ushGID;
}
}
}
break;
}
case fontTrueType:
case fontTrueTypeOT:
{
if ((pTTFontFile = CFontFileTrueType::LoadFromFile((wchar_t*)wsFileName.c_str())))
{
pCodeToGID = ((Gr8BitFont *)pFont)->GetCodeToGIDMap(pTTFontFile);
nLen = 256;
delete pTTFontFile;
pTTFontFile = NULL;
}
else
{
pCodeToGID = NULL;
nLen = 0;
}
break;
}
case fontCIDType0:
case fontCIDType0C:
{
// TODO: Ïðîâåðèòü, ïî÷åìó ïîëó÷åíèå äàííîé êîäèðîâêè áûëî îòêëþ÷åíî
//if ((pT1CFontFile = CFontFileType1C::LoadFromFile((wchar_t*)wsFileName.c_str())))
//{
// pCodeToGID = pT1CFontFile->GetCIDToGIDMap(&nLen);
// delete pT1CFontFile;
//}
//else
//{
pCodeToGID = NULL;
nLen = 0;
//}
break;
}
case fontCIDType0COT:
{
if ((pTTFontFile = CFontFileTrueType::LoadFromFile((wchar_t*)wsFileName.c_str())))
{
if (pTTFontFile->IsOpenTypeCFF())
{
pCodeToGID = pTTFontFile->GetCIDToGIDMap(&nLen);
}
else
{
pCodeToGID = NULL;
nLen = 0;
}
delete pTTFontFile;
pTTFontFile = NULL;
}
else
{
pCodeToGID = NULL;
nLen = 0;
}
break;
}
case fontCIDType2:
case fontCIDType2OT:
{
pCodeToGID = NULL;
nLen = 0;
if (L"" != wsFileName)
{
// Ñîçäàåì êàðòó CID-to-GID
CharCodeToUnicode *pCodeToUnicode = NULL;
if ((pCodeToUnicode = ((GrCIDFont *)pFont)->GetToUnicode()))
{
if ((pTTFontFile = CFontFileTrueType::LoadFromFile((wchar_t*)wsFileName.c_str())))
{
// Èùåì Unicode Cmap
CArray<int> arrCMapIndex;
for (int nCMapIndex = 0; nCMapIndex < pTTFontFile->GetCmapsCount(); ++nCMapIndex)
{
if ((pTTFontFile->GetCmapPlatform(nCMapIndex) == 3 && pTTFontFile->GetCmapEncoding(nCMapIndex) == 1) || pTTFontFile->GetCmapPlatform(nCMapIndex) == 0)
{
arrCMapIndex.Add(nCMapIndex);
}
}
if (arrCMapIndex.GetSize() > 0)
{
// CID -> Unicode -> GID
nLen = pCodeToUnicode->GetLength();
pCodeToGID = (unsigned short *)MemUtilsMallocArray(nLen, sizeof(unsigned short));
for (int nCode = 0; nCode < nLen; ++nCode)
{
Unicode arrUnicodeBuffer[8];
if (pCodeToUnicode->MapToUnicode(nCode, arrUnicodeBuffer, 8) > 0)
{
pCodeToGID[nCode] = pTTFontFile->MapCodeToGID(arrCMapIndex[0], arrUnicodeBuffer[0]);
for (int nIndex = 1; nIndex < arrCMapIndex.GetSize(); nIndex++)
{
if (0 == pCodeToGID[nCode])
pCodeToGID[nCode] = pTTFontFile->MapCodeToGID(arrCMapIndex[nIndex], arrUnicodeBuffer[0]);
else
break;
}
}
else
{
pCodeToGID[nCode] = nCode;
}
}
}
delete pTTFontFile;
pTTFontFile = NULL;
}
pCodeToUnicode->Release();
}
else
{
if (((GrCIDFont *)pFont)->GetCIDToGID())
{
nLen = ((GrCIDFont *)pFont)->GetCIDToGIDLen();
pCodeToGID = (unsigned short *)MemUtilsMallocArray(nLen, sizeof(unsigned short));
if (!pCodeToGID)
break;
memcpy(pCodeToGID, ((GrCIDFont *)pFont)->GetCIDToGID(), nLen * sizeof(unsigned short));
}
}
}
else
{
if (((GrCIDFont *)pFont)->GetCIDToGID())
{
nLen = ((GrCIDFont *)pFont)->GetCIDToGIDLen();
pCodeToGID = (unsigned short *)MemUtilsMallocArray(nLen, sizeof(unsigned short));
if (!pCodeToGID)
break;
memcpy(pCodeToGID, ((GrCIDFont *)pFont)->GetCIDToGID(), nLen * sizeof(unsigned short));
}
}
break;
}
default:
{
// Òàêîãî íå äîëæíî ïðîèçîéòè
if (L"" != wsTempFileName)
NSFile::CFileBinary::Remove(wsTempFileName);
break;
}
}
// Ñîñòàâëÿåì òàáëèöó Code -> Unicode
int nToUnicodeLen = 0;
if (pFont->IsCIDFont())
{
GrCIDFont *pCIDFont = (GrCIDFont *)pFont;
CharCodeToUnicode *pToUnicode = pCIDFont->GetToUnicode();
if (NULL != pToUnicode)
{
nToUnicodeLen = pToUnicode->GetLength();
pCodeToUnicode = (unsigned short *)MemUtilsMallocArray(nToUnicodeLen, sizeof(unsigned short));
if (pCodeToUnicode)
{
for (int nIndex = 0; nIndex < nToUnicodeLen; ++nIndex)
{
Unicode aUnicode[2];
if (pToUnicode->MapToUnicode(nIndex, aUnicode, 2))
pCodeToUnicode[nIndex] = (unsigned short)aUnicode[0];
else
pCodeToUnicode[nIndex] = 0;
}
}
pToUnicode->Release();
}
}
else
{
CharCodeToUnicode *pToUnicode = ((Gr8BitFont *)pFont)->GetToUnicode();
if (NULL != pToUnicode)
{
nToUnicodeLen = pToUnicode->GetLength();
pCodeToUnicode = (unsigned short *)MemUtilsMallocArray(nToUnicodeLen, sizeof(unsigned short));
if (pCodeToUnicode)
{
for (int nIndex = 0; nIndex < nToUnicodeLen; ++nIndex)
{
Unicode nUnicode = 0;
if (pToUnicode->MapToUnicode(nIndex, &nUnicode, 1))
pCodeToUnicode[nIndex] = (unsigned short)nUnicode;
else
pCodeToUnicode[nIndex] = nIndex;
}
}
pToUnicode->Release();
}
}
// Çàïèñûâàåì ôàéë ñ íàñòðîéêàìè øðèôòà (Ñïåöèàëüíî äëÿ ïåðåçàïèñè â PDF)
if (L"" != wsFileName && c_nPDFWriter == m_lRendererType)
{
std::wstring wsSplitFileName, wsSplitFileExt;
SpitPathExt(wsFileName, &wsSplitFileName, &wsSplitFileExt);
std::wstring wsEncodingPath = wsSplitFileName + L".enc";
GrFontType eFontType = pFont->GetType();
if (fontType1 == eFontType || fontType1C == eFontType || fontType1COT == eFontType || fontTrueType == eFontType || fontTrueTypeOT == eFontType)
{
// Çàïèñü èíôîðìàöèè äëÿ ïðîñòûõ øðèôòîâ
CXmlWriter oXmlWriter;
Ref *pRef = pFont->GetID();
Object oRefObject, oFontObject;
oRefObject.InitRef(pRef->nNum, pRef->nGen);
oRefObject.Fetch(m_pXref, &oFontObject);
oRefObject.Free();
if (oFontObject.IsDict())
{
Dict *pFontDict = oFontObject.GetDict();
int nEncodingType = -1; // Îáúåêòà Encoding íåò
int nBaseEncoding = -1;
Object oDictItem;
pFontDict->Search("Encoding", &oDictItem);
if (oDictItem.IsDict())
{
nEncodingType = 1; // Encoding - èäåò îòäåëüíûì îáúåêòîì
Object oTemp;
oDictItem.DictLookup("BaseEncoding", &oTemp);
if (oTemp.IsName("MacRomanEncoding"))
nBaseEncoding = 0;
else if (oTemp.IsName("MacExpertEncoding"))
nBaseEncoding = 1;
else if (oTemp.IsName("WinAnsiEncoding"))
nBaseEncoding = 2;
oTemp.Free();
}
else if (oDictItem.IsName("MacRomanEncoding"))
{
nEncodingType = 0;
nBaseEncoding = 0;
}
else if (oDictItem.IsName("MacExpertEncoding"))
{
nEncodingType = 0;
nBaseEncoding = 1;
}
else if (oDictItem.IsName("WinAnsiEncoding"))
{
nEncodingType = 0;
nBaseEncoding = 2;
}
else
{
nEncodingType = -1;
}
oXmlWriter.WriteNodeBegin(L"PDF-resources");
oXmlWriter.WriteNodeBegin(L"Encoding", true);
oXmlWriter.WriteAttribute(L"type", nEncodingType);
oXmlWriter.WriteAttribute(L"base", nBaseEncoding);
oXmlWriter.WriteNodeEnd(L"Encoding", true, false);
// Differences
if (oDictItem.IsDict())
{
Object oDifferences;
oDictItem.DictLookup("Differences", &oDifferences);
if (oDifferences.IsArray())
{
int nArrayLen = oDifferences.ArrayGetLength();
oXmlWriter.WriteNodeBegin(L"Differences", true);
oXmlWriter.WriteAttribute(L"count", nArrayLen);
oXmlWriter.WriteNodeEnd(L"Differences", true, false);
for (int nIndex = 0; nIndex < nArrayLen; ++nIndex)
{
Object oTemp;
oDifferences.ArrayGet(nIndex, &oTemp);
if (oTemp.IsInt())
{
int nCode = oTemp.GetInt();
oXmlWriter.WriteNodeBegin(L"Code", true);
oXmlWriter.WriteAttribute(L"value", nCode);
oXmlWriter.WriteNodeEnd(L"Code", true, true);
}
else if (oTemp.IsName())
{
char* sName = oTemp.GetName();
oXmlWriter.WriteNodeBegin(L"Name", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(sName));
oXmlWriter.WriteNodeEnd(L"Name", true, true);
}
else
{
// TO DO: Error "Wrong type in font encoding resource differences"
}
oTemp.Free();
}
oXmlWriter.WriteNodeEnd(L"Differences");
}
oDifferences.Free();
}
oDictItem.Free();
oXmlWriter.WriteNodeEnd(L"Encoding");
pFontDict->Search("BaseFont", &oDictItem);
if (oDictItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"FontBase", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.GetName()));
oXmlWriter.WriteNodeEnd(L"FontBase", true, true);
}
oDictItem.Free();
pFontDict->Search("ToUnicode", &oDictItem);
if (oDictItem.IsStream())
{
oXmlWriter.WriteNodeBegin(L"ToUnicode");
StringExt *seBuffer = new StringExt();
if (NULL != seBuffer)
{
oDictItem.StreamReset();
int nChar = 0;
while ((nChar = oDictItem.StreamGetChar()) != EOF)
{
seBuffer->Append(nChar);
}
oDictItem.StreamClose();
CBase64 oBase64;
oBase64.Encode((unsigned char *)seBuffer->GetBuffer(), seBuffer->GetLength());
oXmlWriter.WriteString(AStringToWString(oBase64.GetCString()));
delete seBuffer;
}
oXmlWriter.WriteNodeEnd(L"ToUnicode");
}
oDictItem.Free();
oXmlWriter.WriteNodeBegin(L"FontDescriptor");
Object oFontDescriptor;
if (pFontDict->Search("FontDescriptor", &oFontDescriptor)->IsDict())
{
// FontName
oFontDescriptor.DictLookup("FontName", &oDictItem);
if (oDictItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"FontName", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.GetName()));
oXmlWriter.WriteNodeEnd(L"FontName", true);
}
oDictItem.Free();
// FontFamily
oFontDescriptor.DictLookup("FontFamily", &oDictItem);
if (oDictItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"FontFamily", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.GetName()));
oXmlWriter.WriteNodeEnd(L"FontFamily", true);
}
oDictItem.Free();
// FontStretch
oFontDescriptor.DictLookup("FontStretch", &oDictItem);
if (oDictItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"FontStretch", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.GetName()));
oXmlWriter.WriteNodeEnd(L"FontStretch", true);
}
oDictItem.Free();
// FontWeight
oFontDescriptor.DictLookup("FontWeight", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"FontWeight", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"FontWeight", true);
}
oDictItem.Free();
// FontWeight
oFontDescriptor.DictLookup("Flags", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Flags", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Flags", true);
}
oDictItem.Free();
// FontBBox
oFontDescriptor.DictLookup("FontBBox", &oDictItem);
if (oDictItem.IsArray())
{
Array *pBBox = oDictItem.GetArray();
if (NULL != pBBox && 4 == pBBox->GetCount())
{
oXmlWriter.WriteNodeBegin(L"FontBBox", true);
for (int nIndex = 0; nIndex < 4; nIndex++)
{
Object oArrayItem;
pBBox->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt())
{
std::wstring wsValue = L"value" + std::to_wstring(nIndex);
oXmlWriter.WriteAttribute(wsValue, oArrayItem.GetInt());
}
oArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"FontBBox", true);
}
}
oDictItem.Free();
// ItalicAngle
oFontDescriptor.DictLookup("ItalicAngle", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"ItalicAngle", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"ItalicAngle", true);
}
oDictItem.Free();
// Ascent
oFontDescriptor.DictLookup("Ascent", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Ascent", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Ascent", true);
}
oDictItem.Free();
// Leading
oFontDescriptor.DictLookup("Leading", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Leading", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Leading", true);
}
oDictItem.Free();
// CapHeight
oFontDescriptor.DictLookup("CapHeight", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"CapHeight", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"CapHeight", true);
}
oDictItem.Free();
// XHeight
oFontDescriptor.DictLookup("XHeight", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"XHeight", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"XHeight", true);
}
oDictItem.Free();
// StemV
oFontDescriptor.DictLookup("StemV", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"StemV", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"StemV", true);
}
oDictItem.Free();
// StemH
oFontDescriptor.DictLookup("StemH", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"StemH", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"StemH", true);
}
oDictItem.Free();
// Descent
oFontDescriptor.DictLookup("Descent", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Descent", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Descent", true);
}
oDictItem.Free();
// AvgWidth
oFontDescriptor.DictLookup("AvgWidth", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"AvgWidth", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"AvgWidth", true);
}
oDictItem.Free();
// MaxWidth
oFontDescriptor.DictLookup("MaxWidth", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"MaxWidth", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"MaxWidth", true);
}
oDictItem.Free();
// MissingWidth
oFontDescriptor.DictLookup("MissingWidth", &oDictItem);
if (oDictItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"MissingWidth", true);
oXmlWriter.WriteAttribute(L"value", oDictItem.GetInt());
oXmlWriter.WriteNodeEnd(L"MissingWidth", true);
}
oDictItem.Free();
}
oFontDescriptor.Free();
oXmlWriter.WriteNodeEnd(L"FontDescriptor");
int nFirstChar = 0;
pFontDict->Search("FirstChar", &oDictItem);
if (oDictItem.IsInt()) nFirstChar = oDictItem.GetInt();
oDictItem.Free();
int nLastChar = 0;
pFontDict->Search("LastChar", &oDictItem);
if (oDictItem.IsInt()) nLastChar = oDictItem.GetInt();
oDictItem.Free();
Array *pWidths = NULL;
pFontDict->Search("Widths", &oDictItem);
if (oDictItem.IsArray())
{
oXmlWriter.WriteNodeBegin(L"Widths", true);
oXmlWriter.WriteAttribute(L"FirstChar", nFirstChar);
oXmlWriter.WriteAttribute(L"LastChar", nLastChar);
oXmlWriter.WriteNodeEnd(L"Widths", true, false);
Array *pWidths = oDictItem.GetArray();
int nWidthsCount = pWidths->GetCount();
for (int nIndex = 0; nIndex < nWidthsCount; nIndex++)
{
Object oArrayItem;
pWidths->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Width", true);
oXmlWriter.WriteAttribute(L"value", oArrayItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Width", true);
}
oArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"Widths");
}
oDictItem.Free();
oXmlWriter.WriteNodeEnd(L"PDF-resources");
}
oFontObject.Free();
oXmlWriter.SaveToFile(wsEncodingPath);
}
else if (fontCIDType0 == eFontType || fontCIDType0C == eFontType || fontCIDType0COT == eFontType || fontCIDType2 == eFontType || fontCIDType2OT == eFontType)
{
// Ïèøåì ôàéë ñ êîäèðîâêîé CMap
std::wstring wsCMapPath = wsSplitFileName + L".cmap";
if (pFont->IsCIDFont())
{
GrCIDFont *pCIDFont = (GrCIDFont *)pFont;
if (NULL != pCIDFont->GetCMap())
pCIDFont->GetCMap()->ToXml(wsCMapPath);
}
CXmlWriter oXmlWriter;
Ref *pRef = pFont->GetID();
Object oRefObject, oFontObject;
oRefObject.InitRef(pRef->nNum, pRef->nGen);
oRefObject.Fetch(m_pXref, &oFontObject);
oRefObject.Free();
if (oFontObject.IsDict())
{
Dict *pFontDict = oFontObject.GetDict();
oXmlWriter.WriteNodeBegin(L"PDF-resources");
Object oDictItem;
pFontDict->Search("BaseFont", &oDictItem);
if (oDictItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"Type0", true);
oXmlWriter.WriteAttribute(L"value", AStringToWString(oDictItem.GetName()));
oXmlWriter.WriteNodeEnd(L"Type0", true, false);
}
else
{
oXmlWriter.WriteNodeBegin(L"Type0");
}
oDictItem.Free();
pFontDict->Search("ToUnicode", &oDictItem);
if (oDictItem.IsStream())
{
oXmlWriter.WriteNodeBegin(L"ToUnicode");
StringExt *seBuffer = new StringExt();
oDictItem.StreamReset();
int nChar = 0;
while ((nChar = oDictItem.StreamGetChar()) != EOF)
{
seBuffer->Append(nChar);
}
oDictItem.StreamClose();
CBase64 oBase64;
oBase64.Encode((unsigned char *)seBuffer->GetBuffer(), seBuffer->GetLength());
oXmlWriter.WriteString(AStringToWString(oBase64.GetCString()));
oXmlWriter.WriteNodeEnd(L"ToUnicode");
}
oDictItem.Free();
pFontDict->Search("Encoding", &oDictItem);
if (oDictItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"Encoding", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oDictItem.GetName()));
oXmlWriter.WriteNodeEnd(L"Encoding", true, true);
}
else if (oDictItem.IsStream())
{
oXmlWriter.WriteNodeBegin(L"Encoding");
Dict *pEncodingDict = oDictItem.StreamGetDict();
if (NULL != pEncodingDict)
{
Object oEncItem;
pEncodingDict->Search("CMapName", &oEncItem);
if (oEncItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"CMapName", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oEncItem.GetName()));
oXmlWriter.WriteNodeEnd(L"CMapName", true, true);
}
oEncItem.Free();
pEncodingDict->Search("CIDSystemInfo", &oEncItem);
if (oEncItem.IsDict())
{
Dict *pCIDInfo = oEncItem.GetDict();
if (NULL != pCIDInfo)
{
oXmlWriter.WriteNodeBegin(L"CIDSystemInfo");
Object oCIDInfoItem;
pCIDInfo->Search("Registry", &oCIDInfoItem);
if (oCIDInfoItem.IsString())
{
oXmlWriter.WriteNodeBegin(L"Registry", true);
oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.GetString()->GetBuffer()));
oXmlWriter.WriteNodeEnd(L"Registry", true, true);
}
oCIDInfoItem.Free();
pCIDInfo->Search("Ordering", &oCIDInfoItem);
if (oCIDInfoItem.IsString())
{
oXmlWriter.WriteNodeBegin(L"Ordering", true);
oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.GetString()->GetBuffer()));
oXmlWriter.WriteNodeEnd(L"Ordering", true, true);
}
oCIDInfoItem.Free();
pCIDInfo->Search("Supplement", &oCIDInfoItem);
if (oCIDInfoItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Supplement", true);
oXmlWriter.WriteAttribute(L"integer", oCIDInfoItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Supplement", true, true);
}
oCIDInfoItem.Free();
oXmlWriter.WriteNodeEnd(L"CIDSystemInfo");
}
}
oEncItem.Free();
pEncodingDict->Search("WMode", &oEncItem);
if (oEncItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"WMode", true);
oXmlWriter.WriteAttribute(L"integer", oEncItem.GetInt());
oXmlWriter.WriteNodeEnd(L"WMode", true, true);
}
oEncItem.Free();
pEncodingDict->Search("UseCMap", &oEncItem);
if (oEncItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"UseCMap", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oEncItem.GetName()));
oXmlWriter.WriteNodeEnd(L"UseCMap", true, true);
}
else if (oEncItem.IsStream())
{
oXmlWriter.WriteNodeBegin(L"UseCMap");
StringExt *seBuffer = new StringExt();
oEncItem.StreamReset();
int nChar = 0;
while ((nChar = oEncItem.StreamGetChar()) != EOF)
{
seBuffer->Append(nChar);
}
oEncItem.StreamClose();
CBase64 oBase64;
oBase64.Encode((unsigned char *)seBuffer->GetBuffer(), seBuffer->GetLength());
oXmlWriter.WriteString(AStringToWString(oBase64.GetCString()));
oXmlWriter.WriteNodeEnd(L"UseCMap");
}
oEncItem.Free();
}
oXmlWriter.WriteNodeBegin(L"Stream");
StringExt *seBuffer = new StringExt();
oDictItem.StreamReset();
int nChar = 0;
while ((nChar = oDictItem.StreamGetChar()) != EOF)
{
seBuffer->Append(nChar);
}
oDictItem.StreamClose();
CBase64 oBase64;
oBase64.Encode((unsigned char *)seBuffer->GetBuffer(), seBuffer->GetLength());
oXmlWriter.WriteString(AStringToWString(oBase64.GetCString()));
oXmlWriter.WriteNodeEnd(L"Stream");
oXmlWriter.WriteNodeEnd(L"Encoding");
}
oDictItem.Free();
pFontDict->Search("DescendantFonts", &oDictItem);
if (oDictItem.IsArray())
{
Array *pArray = oDictItem.GetArray();
if (1 == pArray->GetCount())
{
Object oDescFont;
pArray->Get(0, &oDescFont);
if (oDescFont.IsDict())
{
Dict *pDescFont = oDescFont.GetDict();
if (NULL != pDescFont)
{
oXmlWriter.WriteNodeBegin(L"DescendantFonts");
Object oFontItem;
pDescFont->Search("Subtype", &oFontItem);
if (oFontItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"Subtype", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oFontItem.GetName()));
oXmlWriter.WriteNodeEnd(L"Subtype", true, true);
}
oFontItem.Free();
pDescFont->Search("BaseFont", &oFontItem);
if (oFontItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"BaseFont", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oFontItem.GetName()));
oXmlWriter.WriteNodeEnd(L"BaseFont", true, true);
}
oFontItem.Free();
pDescFont->Search("CIDSystemInfo", &oFontItem);
if (oFontItem.IsDict())
{
Dict *pCIDInfo = oFontItem.GetDict();
if (NULL != pCIDInfo)
{
oXmlWriter.WriteNodeBegin(L"CIDSystemInfo");
Object oCIDInfoItem;
pCIDInfo->Search("Registry", &oCIDInfoItem);
if (oCIDInfoItem.IsString())
{
oXmlWriter.WriteNodeBegin(L"Registry", true);
oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.GetString()->GetBuffer()));
oXmlWriter.WriteNodeEnd(L"Registry", true, true);
}
oCIDInfoItem.Free();
pCIDInfo->Search("Ordering", &oCIDInfoItem);
if (oCIDInfoItem.IsString())
{
oXmlWriter.WriteNodeBegin(L"Ordering", true);
oXmlWriter.WriteAttribute(L"string", AStringToWString(oCIDInfoItem.GetString()->GetBuffer()));
oXmlWriter.WriteNodeEnd(L"Ordering", true, true);
}
oCIDInfoItem.Free();
pCIDInfo->Search("Supplement", &oCIDInfoItem);
if (oCIDInfoItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Supplement", true);
oXmlWriter.WriteAttribute(L"integer", oCIDInfoItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Supplement", true, true);
}
oCIDInfoItem.Free();
oXmlWriter.WriteNodeEnd(L"CIDSystemInfo");
}
}
oFontItem.Free();
pDescFont->Search("FontDescriptor", &oFontItem);
if (oFontItem.IsDict())
{
Dict *pFontDescriptor = oFontItem.GetDict();
if (NULL != pFontDescriptor)
{
oXmlWriter.WriteNodeBegin(L"FontDescriptor");
Object oItemFD;
pFontDescriptor->Search("FontName", &oItemFD);
if (oItemFD.IsName())
{
oXmlWriter.WriteNodeBegin(L"FontName", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oItemFD.GetName()));
oXmlWriter.WriteNodeEnd(L"FontName", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("FontStretch", &oItemFD);
if (oItemFD.IsName())
{
oXmlWriter.WriteNodeBegin(L"FontStretch", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oItemFD.GetName()));
oXmlWriter.WriteNodeEnd(L"FontStretch", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("FontWeight", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"FontWeight", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"FontWeight", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("Flags", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Flags", true);
oXmlWriter.WriteAttribute(L"integer", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"Flags", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("FontBBox", &oItemFD);
if (oItemFD.IsArray())
{
Array *pBBox = oItemFD.GetArray();
if (NULL != pBBox && 4 == pBBox->GetCount())
{
oXmlWriter.WriteNodeBegin(L"FontBBox", true);
for (int nIndex = 0; nIndex < 4; nIndex++)
{
Object oArrayItem;
pBBox->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt())
{
std::wstring wsValue = L"value" + std::to_wstring(nIndex);
oXmlWriter.WriteAttribute(wsValue, oArrayItem.GetInt());
}
oArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"FontBBox", true);
}
}
oItemFD.Free();
pFontDescriptor->Search("ItalicAngle", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"ItalicAngle", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"ItalicAngle", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("Ascent", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Ascent", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"Ascent", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("Descent", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Descent", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"Descent", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("Leading", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Leading", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"Leading", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("CapHeight", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"CapHeight", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"CapHeight", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("XHeight", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"XHeight", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"XHeight", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("StemV", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"StemV", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"StemV", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("StemH", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"StemH", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"StemH", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("AvgWidth", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"AvgWidth", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"AvgWidth", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("MaxWidth", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"MaxWidth", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"MaxWidth", true, true);
}
oItemFD.Free();
pFontDescriptor->Search("MissingWidth", &oItemFD);
if (oItemFD.IsInt())
{
oXmlWriter.WriteNodeBegin(L"MissingWidth", true);
oXmlWriter.WriteAttribute(L"number", oItemFD.GetInt());
oXmlWriter.WriteNodeEnd(L"MissingWidth", true, true);
}
oItemFD.Free();
// TODO: Òóò íàäî ðåàëèçîâàòü ÷òåíè ïîëåé /Style, /Lang, /FD, /CIDSet
oXmlWriter.WriteNodeEnd(L"FontDescriptor");
}
}
oFontItem.Free();
pDescFont->Search("DW", &oFontItem);
if (oFontItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"DW", true);
oXmlWriter.WriteAttribute(L"integer", oFontItem.GetInt());
oXmlWriter.WriteNodeEnd(L"DW", true, true);
}
oFontItem.Free();
pDescFont->Search("W", &oFontItem);
if (oFontItem.IsArray())
{
Array *pArray = oFontItem.GetArray();
if (NULL != pArray)
{
oXmlWriter.WriteNodeBegin(L"W");
for (int nIndex = 0; nIndex < pArray->GetCount(); nIndex++)
{
Object oArrayItem;
pArray->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Int", true);
oXmlWriter.WriteAttribute(L"value", oArrayItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Int", true, true);
}
else if (oArrayItem.IsArray())
{
Array *pWArray = oArrayItem.GetArray();
if (NULL != pWArray)
{
oXmlWriter.WriteNodeBegin(L"Array");
for (int nWIndex = 0; nWIndex < pWArray->GetCount(); nWIndex++)
{
Object oWArrayItem;
pWArray->Get(nWIndex, &oWArrayItem);
if (oWArrayItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Int", true);
oXmlWriter.WriteAttribute(L"value", oWArrayItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Int", true, true);
}
oWArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"Array");
}
}
oArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"W");
}
}
oFontItem.Free();
pDescFont->Search("DW2", &oFontItem);
if (oFontItem.IsArray())
{
Array *pArray = oFontItem.GetArray();
if (NULL != pArray && 2 == pArray->GetCount())
{
oXmlWriter.WriteNodeBegin(L"DW2", true);
Object oArrayItem;
pArray->Get(0, &oArrayItem);
if (oArrayItem.IsInt())
{
oXmlWriter.WriteAttribute(L"value0", oArrayItem.GetInt());
}
oArrayItem.Free();
pArray->Get(1, &oArrayItem);
if (oArrayItem.IsInt())
{
oXmlWriter.WriteAttribute(L"value1", oArrayItem.GetInt());
}
oArrayItem.Free();
oXmlWriter.WriteNodeEnd(L"DW2", true, true);
}
}
oFontItem.Free();
pDescFont->Search("W2", &oFontItem);
if (oFontItem.IsArray())
{
Array *pArray = oFontItem.GetArray();
if (NULL != pArray)
{
oXmlWriter.WriteNodeBegin(L"W2");
for (int nIndex = 0; nIndex < pArray->GetCount(); nIndex++)
{
Object oArrayItem;
pArray->Get(nIndex, &oArrayItem);
if (oArrayItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Int", true);
oXmlWriter.WriteAttribute(L"value", oArrayItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Int", true, true);
}
else if (oArrayItem.IsArray())
{
Array *pWArray = oArrayItem.GetArray();
if (NULL != pWArray)
{
oXmlWriter.WriteNodeBegin(L"Array");
for (int nWIndex = 0; nWIndex < pWArray->GetCount(); nWIndex++)
{
Object oWArrayItem;
pWArray->Get(nWIndex, &oWArrayItem);
if (oWArrayItem.IsInt())
{
oXmlWriter.WriteNodeBegin(L"Int", true);
oXmlWriter.WriteAttribute(L"value", oWArrayItem.GetInt());
oXmlWriter.WriteNodeEnd(L"Int", true, true);
}
oWArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"Array");
}
}
oArrayItem.Free();
}
oXmlWriter.WriteNodeEnd(L"W2");
}
}
oFontItem.Free();
pDescFont->Search("CIDToGIDMap", &oFontItem);
if (oFontItem.IsName())
{
oXmlWriter.WriteNodeBegin(L"CIDToGIDMap", true);
oXmlWriter.WriteAttribute(L"name", AStringToWString(oFontItem.GetName()));
oXmlWriter.WriteNodeEnd(L"CIDToGIDMap", true, true);
}
else if (oFontItem.IsStream())
{
oXmlWriter.WriteNodeBegin(L"CIDToGIDMap");
StringExt *seBuffer = new StringExt();
oFontItem.StreamReset();
int nChar = 0;
while ((nChar = oFontItem.StreamGetChar()) != EOF)
{
seBuffer->Append(nChar);
}
oFontItem.StreamClose();
CBase64 oBase64;
oBase64.Encode((unsigned char *)seBuffer->GetBuffer(), seBuffer->GetLength());
oXmlWriter.WriteString(AStringToWString(oBase64.GetCString()));
oXmlWriter.WriteNodeEnd(L"CIDToGIDMap");
}
oFontItem.Free();
oXmlWriter.WriteNodeEnd(L"DescendantFonts");
}
}
oDescFont.Free();
}
}
oDictItem.Free();
oXmlWriter.WriteNodeEnd(L"Type0");
oXmlWriter.WriteNodeEnd(L"PDF-resources");
}
oFontObject.Free();
oXmlWriter.SaveToFile(wsEncodingPath);
}
}
// Îáðåæåì èíäåêñ ó FontName, åñëè îí åñòü
if (wsFontName.length() > 7)
{
bool bIsIndex = true;
if ('+' != wsFontName.at(6))
bIsIndex = false;
if (bIsIndex)
{
for (int nIndex = 0; nIndex < 6; nIndex++)
{
int nChar = wsFontName.at(nIndex);
if (nChar < 'A' || nChar > 'Z')
{
bIsIndex = false;
break;
}
}
}
if (bIsIndex)
{
wsFontName.erase(0, 7);
}
}
pEntry->wsFilePath = wsFileName;
pEntry->wsFontName = wsFontName;
pEntry->pCodeToGID = pCodeToGID;
pEntry->pCodeToUnicode = pCodeToUnicode;
pEntry->unLenGID = (unsigned int)nLen;
pEntry->unLenUnicode = (unsigned int)nToUnicodeLen;
pEntry->bAvailable = true;
}
else if (NULL != pEntry)
{
wsFileName = pEntry->wsFilePath;
wsFontName = pEntry->wsFontName;
}
if (L"" != wsFileName)
{
m_pRenderer->put_FontPath(wsFileName);
m_pRenderer->put_FontName(wsFontName);
}
}
void RendererOutputDev::Stroke(GrState *pGState)
{
if (m_bTransparentGroup)
return;
DoPath(pGState, pGState->GetPath(), pGState->GetPageHeight(), pGState->GetCTM());
m_pRenderer->DrawPath(c_nStroke);
m_pRenderer->EndCommand(c_nPathType);
}
void RendererOutputDev::Fill(GrState *pGState)
{
if (m_bTransparentGroup)
return;
DoPath(pGState, pGState->GetPath(), pGState->GetPageHeight(), pGState->GetCTM());
m_pRenderer->DrawPath(c_nWindingFillMode);
m_pRenderer->EndCommand(c_nPathType);
}
void RendererOutputDev::EoFill(GrState *pGState)
{
if (m_bTransparentGroup)
return;
DoPath(pGState, pGState->GetPath(), pGState->GetPageHeight(), pGState->GetCTM());
m_pRenderer->DrawPath(c_nEvenOddFillMode);
m_pRenderer->EndCommand(c_nPathType);
}
void RendererOutputDev::FillStroke(GrState *pGState)
{
if (m_bTransparentGroup)
return;
DoPath(pGState, pGState->GetPath(), pGState->GetPageHeight(), pGState->GetCTM());
m_pRenderer->DrawPath(c_nStroke | c_nWindingFillMode);
m_pRenderer->EndCommand(c_nPathType);
}
void RendererOutputDev::EoFillStroke(GrState *pGState)
{
if (m_bTransparentGroup)
return;
DoPath(pGState, pGState->GetPath(), pGState->GetPageHeight(), pGState->GetCTM());
m_pRenderer->DrawPath(c_nStroke | c_nEvenOddFillMode);
m_pRenderer->EndCommand(c_nPathType);
}
void RendererOutputDev::TilingPatternFill(GrState *pGState, Object *pStream, int nPaintType, Dict *pResourcesDict, double *pMatrix, double *pBBox, int nX0, int nY0, int nX1, int nY1, double dXStep, double dYStep)
{
}
void RendererOutputDev::StartTilingFill(GrState *pGState)
{
m_pRenderer->BeginCommand(c_nComplexFigureType);
m_bTiling = true;
}
void RendererOutputDev::EndTilingFill()
{
m_pRenderer->EndCommand(c_nComplexFigureType);
m_bTiling = false;
}
bool RendererOutputDev::FunctionShadedFill(GrState *pGState, GrFunctionShading *pShading)
{
return false;
}
bool RendererOutputDev::AxialShadedFill(GrState *pGState, GrAxialShading *pShading)
{
// TODO: Ðåàëèçîâàòü ëèíåéíûé ãðàäèåíò
return false;
//m_pRenderer->BeginCommand(c_nPDFGradientType);
//double arrMatrix[6];
//double *pCTM = pGState->GetCTM();
//arrMatrix[0] = pCTM[0];
//arrMatrix[1] = -pCTM[1];
//arrMatrix[2] = pCTM[2];
//arrMatrix[3] = -pCTM[3];
//arrMatrix[4] = pCTM[4];
//arrMatrix[5] = -pCTM[5] + pGState->GetPageHeight();
//double dShiftX = 0, dShiftY = 0;
//DoTransform(arrMatrix, &dShiftX, &dShiftY);
//double dFirstX, dFirstY, dSecondX, dSecondY;
//pShading->GetCoords(&dFirstX, &dFirstY, &dSecondX, &dSecondY);
//bool bExtendFirst = pShading->GetExtendStart();
//bool bExtendSecond = pShading->GetExtendEnd();
//GrColorSpace *pColorSpace = pGState->GetFillColorSpace();
//LONG lOldType;
//m_pRenderer->get_BrushType(&lOldType);
////m_pRenderer->put_B
//NSStructures::CBrush oBrush;
//oBrush.Rect.X = PDFCoordsToMM(dFirstX + dShiftX);
//oBrush.Rect.Y = PDFCoordsToMM(dFirstY + dShiftY);
//oBrush.Rect.Width = PDFCoordsToMM(dSecondX - dFirstX);
//oBrush.Rect.Height = PDFCoordsToMM(dSecondY - dFirstY);
//oBrush.Type = 2;
//oBrush.TextureMode = bExtendFirst ? 1 : 0 + bExtendSecond ? 2 : 0;
//BSTR bsXml = oBrush.ToXmlString().AllocSysString();
//m_pRenderer->SetBrush(bsXml);
//::SysFreeString(bsXml);
//double dXMin, dYMin, dXMax, dYMax;
//pGState->GetUserClipBBox(&dXMin, &dYMin, &dXMax, &dYMax);
//oBrush.Type = 2;
//oBrush.TextureMode = 5;
//m_pRenderer->BrushBounds(PDFCoordsToMM(dXMin + dShiftX), PDFCoordsToMM(dYMin + dShiftY), PDFCoordsToMM(dXMax - dXMin), PDFCoordsToMM(dYMax - dYMin));
//Aggplus::BrushType::
//m_pRenderer->put_BrushType(2);
//m_pRenderer->put_BrushTextureMode(Aggplus::);
//bsXml = oBrush.ToXmlString().AllocSysString();
//m_pRenderer->SetBrush(bsXml);
//::SysFreeString(bsXml);
//// Ïðèñûëàåì 16 öâåòîâ
//double dT0 = pShading->GetDomain0();
//double dT1 = pShading->GetDomain1();
//GrColor oColor;
//for (int nIndex = 0; nIndex < 16; nIndex++)
//{
// double dT = dT0 + nIndex * (dT1 - dT0) / 15;
// pShading->GetColor(dT, &oColor);
// oBrush.Color1 = pColorSpace->GetDwordColor(&oColor);
// oBrush.Type = 2;
// oBrush.TextureMode = 10;
// bsXml = oBrush.ToXmlString().AllocSysString();
// m_pRenderer->SetBrush(bsXml);
// ::SysFreeString(bsXml);
//}
//m_pRenderer->EndCommand(c_nPDFGradientType);
//UpdateFillColor(pGState);
//UpdateFillOpacity(pGState);
//m_pRenderer->put_BrushType(lOldType);
//return true;
}
bool RendererOutputDev::RadialShadedFill(GrState *pGState, GrRadialShading *pShading)
{
// TODO: Ðåàëèçîâàòü ðàäèàëüíûé ãðàäèåíò
return false;
//m_pRenderer->BeginCommand(c_nPDFGradientType);
//double arrMatrix[6];
//double *pCTM = pGState->GetCTM();
//arrMatrix[0] = pCTM[0];
//arrMatrix[1] = -pCTM[1];
//arrMatrix[2] = pCTM[2];
//arrMatrix[3] = -pCTM[3];
//arrMatrix[4] = pCTM[4];
//arrMatrix[5] = -pCTM[5] + pGState->GetPageHeight();
//double dShiftX = 0, dShiftY = 0;
//DoTransform(arrMatrix, &dShiftX, &dShiftY);
//double dFirstX, dFirstY, dFirstRad, dSecondX, dSecondY, dSecondRad;
//pShading->GetCoords(&dFirstX, &dFirstY, &dFirstRad, &dSecondX, &dSecondY, &dSecondRad);
//bool bExtendFirst = pShading->GetExtendFirst();
//bool bExtendSecond = pShading->GetExtendSecond();
//LONG lOldType;
//m_pRenderer->get_BrushType(&lOldType);
//NSStructures::CBrush oBrush;
//oBrush.Rect.X = PDFCoordsToMM(dFirstX + dShiftX);
//oBrush.Rect.Y = PDFCoordsToMM(dFirstY + dShiftY);
//oBrush.Rect.Width = PDFCoordsToMM(dFirstRad);
//oBrush.Rect.Height = PDFCoordsToMM(dFirstRad);
//oBrush.Type = 1;
//oBrush.TextureMode = bExtendFirst ? 1 : 0;
//BSTR bsXml = oBrush.ToXmlString().AllocSysString();
//m_pRenderer->SetBrush(bsXml);
//::SysFreeString(bsXml);
//oBrush.Rect.X = PDFCoordsToMM(dSecondX + dShiftX);
//oBrush.Rect.Y = PDFCoordsToMM(dSecondY + dShiftY);
//oBrush.Rect.Width = PDFCoordsToMM(dSecondRad);
//oBrush.Rect.Height = PDFCoordsToMM(dSecondRad);
//oBrush.Type = 1;
//oBrush.TextureMode = bExtendSecond ? 1 : 0;
//bsXml = oBrush.ToXmlString().AllocSysString();
//m_pRenderer->SetBrush(bsXml);
//::SysFreeString(bsXml);
//double dXMin, dYMin, dXMax, dYMax;
//pGState->GetUserClipBBox(&dXMin, &dYMin, &dXMax, &dYMax);
//oBrush.Rect.X = PDFCoordsToMM(dXMin + dShiftX);
//oBrush.Rect.Y = PDFCoordsToMM(dYMin + dShiftY);
//oBrush.Rect.Width = PDFCoordsToMM(dXMax - dXMin);
//oBrush.Rect.Height = PDFCoordsToMM(dYMax - dYMin);
//oBrush.Type = 1;
//oBrush.TextureMode = 5;
//bsXml = oBrush.ToXmlString().AllocSysString();
//m_pRenderer->SetBrush(bsXml);
//::SysFreeString(bsXml);
//// Ïðèñûëàåì 15 öâåòîâ
//double dT0 = pShading->GetDomain0();
//double dT1 = pShading->GetDomain1();
//GrColor oColor;
//GrColorSpace *pColorSpace = pGState->GetFillColorSpace();
//for (int nIndex = 0; nIndex < 15; nIndex++)
//{
// double dT = dT0 + nIndex * (dT1 - dT0) / 14;
// pShading->GetColor(dT, &oColor);
// oBrush.Color1 = pColorSpace->GetDwordColor(&oColor);
// oBrush.Type = 1;
// oBrush.TextureMode = 10;
// bsXml = oBrush.ToXmlString().AllocSysString();
// m_pRenderer->SetBrush(bsXml);
// ::SysFreeString(bsXml);
//}
//m_pRenderer->EndCommand(c_nPDFGradientType);
//UpdateFillColor(pGState);
//UpdateFillOpacity(pGState);
//m_pRenderer->put_BrushType(lOldType);
//return true;
}
void RendererOutputDev::StartShadedFill(GrState *pGState)
{
m_pRenderer->BeginCommand(c_nComplexFigureType);
}
void RendererOutputDev::EndShadedFill()
{
m_pRenderer->EndCommand(c_nComplexFigureType);
}
void RendererOutputDev::StartTilingFillIteration()
{
m_pRenderer->BeginCommand(c_nPDFTilingFillIteration);
}
void RendererOutputDev::EndTilingFillIteration()
{
m_pRenderer->EndCommand(c_nPDFTilingFillIteration);
}
void RendererOutputDev::StartSimpleTilingFill(GrState *pGState, int nX0, int nY0, int nX1, int nY1, double dStepX, double dStepY, double dXMin, double dYMin, double dXMax, double dYMax, double* pMatrix)
{
this->ClipAttack(pGState);
m_pRenderer->BeginCommand(c_nPDFTilingFill);
CXmlWriter oWriter;
oWriter.WriteNodeBegin(L"htmltiling", true);
oWriter.WriteAttribute(L"x", nX0);
oWriter.WriteAttribute(L"y", nY0);
oWriter.WriteAttribute(L"countx", nX1 - nX0);
oWriter.WriteAttribute(L"county", nY1 - nY0);
oWriter.WriteAttribute(L"stepx", dStepX);
oWriter.WriteAttribute(L"stepy", dStepY);
oWriter.WriteNodeEnd(L"htmltiling", true, false);
oWriter.WriteNodeBegin(L"bbox", true);
oWriter.WriteAttribute(L"x", dXMin);
oWriter.WriteAttribute(L"y", dYMin);
oWriter.WriteAttribute(L"r", dXMax);
oWriter.WriteAttribute(L"b", dYMax);
oWriter.WriteNodeEnd(L"bbox", true, true);
oWriter.WriteNodeBegin(L"transform", true);
oWriter.WriteAttribute(L"m1", pMatrix[0]);
oWriter.WriteAttribute(L"m2", pMatrix[1]);
oWriter.WriteAttribute(L"m3", pMatrix[2]);
oWriter.WriteAttribute(L"m4", pMatrix[3]);
oWriter.WriteAttribute(L"m5", pMatrix[4]);
oWriter.WriteAttribute(L"m6", pMatrix[5]);
oWriter.WriteNodeEnd(L"transform", true, true);
oWriter.WriteNodeEnd(L"htmltiling", false);
// TODO: m_pRenderer->SetAdditionalParam(L"TilingHtmlPattern", oWriter.GetXmlString());
}
void RendererOutputDev::EndSimpleTilingFill()
{
m_pRenderer->EndCommand(c_nPDFTilingFill);
}
void RendererOutputDev::Clip(GrState *pGState)
{
UpdateClip(pGState);
}
void RendererOutputDev::EoClip(GrState *pGState)
{
UpdateClip(pGState);
}
void RendererOutputDev::ClipToStrokePath(GrState *pGState)
{
UpdateClip(pGState);
}
void RendererOutputDev::ClipToPath(GrState *pGState, GrPath *pPath, double *pMatrix, bool bEO)
{
if (m_bTransparentGroup)
return;
int nClipFlag = bEO ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding;
nClipFlag |= c_nClipRegionIntersect;
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(nClipFlag);
DoPath(pGState, pPath, pGState->GetPageHeight(), pMatrix);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
}
void RendererOutputDev::ClipToText(std::wstring& wsFontName, std::wstring& wsFontPath, double dFontSize, int nFontStyle, double *pMatrix, std::wstring& wsText, double dX, double dY, double dWidth, double dHeight, double dBaseLineOffset)
{
if (m_bTransparentGroup)
return;
m_pRenderer->put_FontName(wsFontName);
m_pRenderer->put_FontPath(wsFontPath);
m_pRenderer->put_FontSize(dFontSize);
m_pRenderer->put_FontStyle((long)nFontStyle);
double dShiftX = 0, dShiftY = 0;
DoTransform(pMatrix, &dShiftX, &dShiftY, true);
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionUnion);
m_pRenderer->PathCommandEnd();
m_pRenderer->put_FontStringGID(true);
m_pRenderer->PathCommandTextEx(wsText, L"", PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight), PDFCoordsToMM(dBaseLineOffset), 0);
m_pRenderer->EndCommand(c_nClipType);
}
void RendererOutputDev::BeginStringOperator(GrState *pGState)
{
if (m_bTransparentGroup)
return;
m_pRenderer->BeginCommand(c_nTextType);
int nRenderMode = pGState->GetRenderMode();
// Îáðàáîòêà Clip
if (nRenderMode >= 4)
{
if (m_pBufferTextClip)
delete m_pBufferTextClip;
m_pBufferTextClip = new GrTextClip();
}
// Îáðàáîòêà Stroke
if (1 == nRenderMode || 2 == nRenderMode || 5 == nRenderMode || 6 == nRenderMode)
{
//Painter::CPen oPen;
//m_pRenderer->put_PenSize( PDFCoordsToMM( pGState->GetFontSize() ) * 0.05 );
//m_pRenderer->put_PenAlpha( 255 );
//oPen.SetColor( m_oPen.GetColor() );
//BSTR bsPen = oPen.ToXmlString().AllocSysString();
//m_pRenderer->SetPen( bsPen );
//::SysFreeString( bsPen );
}
}
void RendererOutputDev::EndStringOperator(GrState *pGState)
{
if (m_bTransparentGroup)
return;
int nRenderMode = pGState->GetRenderMode();
// Äîáàâëÿåì â Clipping Path òåêñò
if (nRenderMode >= 4)
{
if (m_pBufferTextClip)
pGState->GetClip()->AppendTextClip(m_pBufferTextClip);
for (int nIndex = 0; nIndex < m_pBufferTextClip->GetTextsCount(); nIndex++)
{
WString wsFontName, wsFontPath;
int nFontStyle;
double dFontSize = 10, dX = 0, dY = 0, dWidth = 0, dHeight = 0, dBaseLineOffset = 0;
WString wsText = m_pBufferTextClip->GetText(nIndex, &dX, &dY, &dWidth, &dHeight, &dBaseLineOffset, &wsFontName, &wsFontPath, &dFontSize, &nFontStyle);
double *pMatrix = m_pBufferTextClip->GetMatrix(nIndex);
ClipToText(std::wstring(wsFontName), std::wstring(wsFontPath), dFontSize, nFontStyle, pMatrix, std::wstring(wsText), dX, dY, dWidth, dHeight, dBaseLineOffset);
}
UpdateFont(pGState);
}
// Âîçâðàùàåì ïàðàìåòðû äëÿ Stroke
if (1 == nRenderMode || 2 == nRenderMode || 5 == nRenderMode || 6 == nRenderMode)
{
//BSTR bsPen = m_oPen.ToXmlString().AllocSysString();
//m_pRenderer->SetPen( bsPen );
//::SysFreeString( bsPen );
}
m_pRenderer->EndCommand(c_nTextType);
}
void RendererOutputDev::DrawString(GrState *pGState, StringExt *seString)
{
if (m_bTransparentGroup)
return;
// Ïðîâåðÿåì íàëè÷èå ñïèñêà ñî øðèôòàìè
if (NULL == m_pFontList)
return;
// Ïðîâåðÿåì íàëè÷èå òåêóùåãî øðèôòà
TFontEntry oEntry;
if (!m_pFontList->GetFont(pGState->GetFont()->GetID(), &oEntry))
return;
int nRendererMode = pGState->GetRenderMode();
if (3 == nRendererMode) // Íåâèäèìûé òåêñ
return;
double *pCTM = pGState->GetCTM();
double *pTm = pGState->GetTextMatrix();
GrFont *pFont = pGState->GetFont();
std::wstring wsUnicodeText, wsGidText;
for (int nIndex = 0; nIndex < seString->GetLength(); nIndex++)
{
char nChar = seString->GetAt(nIndex);
if (NULL != oEntry.pCodeToUnicode)
{
unsigned short unUnicode = oEntry.pCodeToUnicode[nChar];
wsUnicodeText += (wchar_t(unUnicode));
}
if (NULL != oEntry.pCodeToGID)
{
unsigned short unGID;
if (0 != (unGID = oEntry.pCodeToGID[nChar]))
wsGidText += (wchar_t(unGID));
}
else
{
int nCurCode = (0 == nChar ? 65534 : nChar);
wsGidText += (wchar_t(nCurCode));
}
}
m_pRenderer->CommandDrawTextEx(wsUnicodeText, wsGidText, PDFCoordsToMM(100), PDFCoordsToMM(100), 0, PDFCoordsToMM(0), PDFCoordsToMM(0), 0);
}
void RendererOutputDev::DrawChar(GrState *pGState, double dX, double dY, double dDx, double dDy, double dOriginX, double dOriginY, CharCode nCode, int nBytesCount, Unicode *pUnicode, int nUnicodeLen)
{
if (m_bTransparentGroup)
return;
// Ïðîâåðÿåì íàëè÷èå ñïèñêà ñî øðèôòàìè
if (NULL == m_pFontList)
return;
// Ïðîâåðÿåì íàëè÷èå òåêóùåãî øðèôòà
TFontEntry oEntry;
if (!m_pFontList->GetFont(pGState->GetFont()->GetID(), &oEntry))
return;
int nRenderMode = pGState->GetRenderMode();
if (3 == nRenderMode) // Íåâèäèìûé òåêñò
{
return;
}
double *pCTM = pGState->GetCTM();
double *pTm = pGState->GetTextMatrix();
GrFont *pFont = pGState->GetFont();
//double dTfs = pGState->GetFontSize();
//double dTh = pGState->GetHorizScaling();
//double dTrise = pGState->GetRise();
//double *pFontBBox = pGState->GetFont()->GetFontBBox();
//double dAcsentFactor = ( ( fabs(pFontBBox[1]) + fabs(pFontBBox[3]) ) - ( pFont->GetAscent() + fabs( pFont->GetDescent() ) ) ) / 2 + pFont->GetAscent();
double pNewTm[6], arrMatrix[6];
//double dKoef = 0;//( pFont->GetAscent() - fabs( pFont->GetDescent() ) ) * dTfs;
double dTextScale = min(sqrt(pTm[2] * pTm[2] + pTm[3] * pTm[3]), sqrt(pTm[0] * pTm[0] + pTm[1] * pTm[1]));
double dITextScale = 1 / dTextScale;
//pTm[0] *= dITextScale;
//pTm[1] *= dITextScale;
//pTm[2] *= dITextScale;
//pTm[3] *= dITextScale;
//double dOldSize = m_oFont.Size;
//m_oFont.Size *= dTextScale;
double dOldSize = 10.0;
m_pRenderer->get_FontSize(&dOldSize);
m_pRenderer->put_FontSize(dOldSize * dTextScale);
pNewTm[0] = pTm[0] * dITextScale;
pNewTm[1] = pTm[1] * dITextScale;
pNewTm[2] = -pTm[2] * dITextScale;
pNewTm[3] = -pTm[3] * dITextScale;
//pNewTm[0] = pTm[0];
//pNewTm[1] = pTm[1];
//pNewTm[2] = -pTm[2];
//pNewTm[3] = -pTm[3];
pNewTm[4] = dX;//+ pTm[2] * dKoef;
pNewTm[5] = dY;//+ pTm[3] * dKoef;
arrMatrix[0] = pNewTm[0] * pCTM[0] + pNewTm[1] * pCTM[2];
arrMatrix[1] = -(pNewTm[0] * pCTM[1] + pNewTm[1] * pCTM[3]);
arrMatrix[2] = pNewTm[2] * pCTM[0] + pNewTm[3] * pCTM[2];
arrMatrix[3] = -(pNewTm[2] * pCTM[1] + pNewTm[3] * pCTM[3]);
arrMatrix[4] = pNewTm[4] * pCTM[0] + pNewTm[5] * pCTM[2] + pCTM[4];
arrMatrix[5] = -(pNewTm[4] * pCTM[1] + pNewTm[5] * pCTM[3] + pCTM[5]) + pGState->GetPageHeight();
//double dAscentShiftX = arrMatrix[2] * pFont->GetDescent();
//double dAscentShiftY = arrMatrix[3] * pFont->GetDescent();
//arrMatrix[4] += dAscentShiftX;
//arrMatrix[5] += dAscentShiftY;
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
// Çäåñü ìû ïîñûëàåì êîîðäèíàòû òåêñòà â ïóíêòàõ
double dPageHeight = pGState->GetPageHeight();
std::wstring wsUnicodeText;
if (NULL != oEntry.pCodeToUnicode && nCode < oEntry.unLenUnicode)
{
unsigned short unUnicode = oEntry.pCodeToUnicode[nCode];
wsUnicodeText = (wchar_t(unUnicode));
}
else
{
if (pGState->GetFont()->IsCIDFont())
{
// Çíà÷èò êîäèðîâêà áûëà Identity-H èëè Identity-V, ÷òî îçíà÷àåò, ÷òî èõîäíûå êîäû è åñòü þíèêîäíûå çíà÷åíèÿ
wsUnicodeText = (wchar_t(nCode));
}
else
{
// Äîãîâîðèëèñü, ÷òî åñëè íåëüçÿ òî÷íî ñîñòàâèòü þíèêîäíûå çíà÷åíèÿ, òîãäà îòäàåì NULL
wsUnicodeText = L"";
}
}
std::wstring wsGidText = L"";
if (NULL != oEntry.pCodeToGID && nCode < oEntry.unLenGID)
{
unsigned short unGID;
if (0 == (unGID = oEntry.pCodeToGID[nCode]))
wsGidText = L"";
else
wsGidText = wchar_t(unGID);
}
else
{
int nCurCode = (0 == nCode ? 65534 : nCode);
wsGidText = wchar_t(nCurCode);
}
std::wstring wsSrcCodeText;
if (c_nPDFWriter == m_lRendererType)
{
int nCurCode = (0 == nCode ? 65534 : nCode);
if (pGState->GetFont()->IsCIDFont())
{
// Ìû ïîñûëàåì è ñàì CID è âíóòðåííèé Code ñ åãî äëèííîé
CXmlWriter oWriter;
oWriter.WriteNodeBegin(L"PDF-Text", true);
oWriter.WriteAttribute(L"cid", nCurCode);
oWriter.WriteAttribute(L"code", (unsigned short)(pUnicode[0]));
oWriter.WriteAttribute(L"len", nUnicodeLen);
oWriter.WriteNodeEnd(L"PDF-Text", true, true);
wsSrcCodeText = oWriter.GetXmlString();
}
else
{
// Ìû ïîñûëàåì è ñàì CID è âíóòðåííèé Code ñ åãî äëèííîé
CXmlWriter oWriter;
oWriter.WriteNodeBegin(L"PDF-Text", true);
oWriter.WriteAttribute(L"code", nCurCode);
oWriter.WriteNodeEnd(L"PDF-Text", true, true);
wsSrcCodeText = oWriter.GetXmlString();
}
}
else
{
wsSrcCodeText = L"";
}
// TODO: Â òåêùåì âàðèàíòå ðåíäåðåðà óáðàí wsSrcCodeText, îí íóæåí äëÿ ïåðåçàïèñè PDF, êàê áóäåò äîáàâëåíà ôóíêöèÿ èçìåíèòü çäåñü.
float fAscent = pGState->GetFontSize();
if (nRenderMode == 0 || nRenderMode == 2 || nRenderMode == 4 || nRenderMode == 6)
{
m_pRenderer->CommandDrawTextEx(wsUnicodeText, wsGidText, PDFCoordsToMM(0 + dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy), PDFCoordsToMM(0), 0);
}
if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6)
{
m_pRenderer->BeginCommand(c_nStrokeTextType);
m_pRenderer->PathCommandEnd();
//m_pRenderer->PathCommandText( bsText, PDFCoordsToMM( 0 + dShiftX ), PDFCoordsToMM( /*-fabs(pFont->GetFontBBox()[3]) * dTfs*/ + dShiftY ), PDFCoordsToMM( 0 ), PDFCoordsToMM( 0 ), PDFCoordsToMM( 0 ) );
// Âðåìåííî
//m_pRenderer->PathCommandTextEx( bsText, PDFCoordsToMM( 0 + dShiftX ), PDFCoordsToMM( /*-fabs(pFont->GetFontBBox()[3]) * dTfs*/ + dShiftY ), PDFCoordsToMM( 0 ), PDFCoordsToMM( 0 ), PDFCoordsToMM( 0 ), 0, bsStringGID );
//m_pRenderer->PathCommandTextEx( bsUnicodeText, bsGIDText, bsSrcCodeText, PDFCoordsToMM( 0 + dShiftX ), PDFCoordsToMM( /*-fabs(pFont->GetFontBBox()[3]) * dTfs*/0 + dShiftY ), PDFCoordsToMM( dDx ), PDFCoordsToMM( dDy ), PDFCoordsToMM( 0 ), 0 );
//-----------
//m_pRenderer->PathCommandText( bsUnicodeText, PDFCoordsToMM( 0 + dShiftX ), PDFCoordsToMM( /*-fabs(pFont->GetFontBBox()[3]) * dTfs*/ + dShiftY ), PDFCoordsToMM( dDx ), PDFCoordsToMM( dDy ), PDFCoordsToMM( 0 ) );
//m_pRenderer->DrawPath( c_nStroke );
m_pRenderer->EndCommand(c_nStrokeTextType);
}
if (4 <= nRenderMode)
{
std::wstring wsTempFontName, wsTempFontPath;
double dTempFontSize;
long lTempFontStyle;
m_pRenderer->get_FontName(&wsTempFontName);
m_pRenderer->get_FontPath(&wsTempFontPath);
m_pRenderer->get_FontSize(&dTempFontSize);
m_pRenderer->get_FontStyle(&lTempFontStyle);
m_pBufferTextClip->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsGidText, 0 + dShiftX, /*-fabs(pFont->GetFontBBox()[3]) * dTfs*/ + dShiftY, 0, 0, 0);
}
m_pRenderer->put_FontSize(dOldSize);
}
bool RendererOutputDev::BeginType3Char(GrState *pGState, double dX, double dY, double dDx, double dDy, CharCode nCode, Unicode *pUnicode, int nUnicodeLen)
{
return false;
}
void RendererOutputDev::EndType3Char(GrState *pGState)
{
return;
}
void RendererOutputDev::Type3D0(GrState *pGState, double dWx, double dWy)
{
return;
}
void RendererOutputDev::Type3D1(GrState *pGState, double dWx, double dWy, double dBLx, double dBLy, double dTRx, double dTRy)
{
return;
}
void RendererOutputDev::DrawImageMask(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, bool bInvert, bool bInlineImage)
{
if (pGState->GetFillColorSpace()->IsNonMarking())
{
return;
}
double dPageHeight = pGState->GetPageHeight();
int nBufferSize = 4 * nWidth * nHeight;
if (nBufferSize < 1)
return;
unsigned char *pBufferPtr = new unsigned char[nBufferSize];
if (!pBufferPtr)
return;
Aggplus::CImage oImage;
oImage.Create(pBufferPtr, nWidth, nHeight, 4 * nWidth);
// Ïèøåì äàííûå â pBufferPtr
ImageStream *pImageStream = new ImageStream(pStream, nWidth, 1, 1);
pImageStream->Reset();
unsigned char unAlpha = m_bTransparentGroup ? 255.0 * pGState->GetFillOpacity() : 255;
unsigned char unPixel = 0;
int nInvert = (bInvert ? 1 : 0);
for (int nY = nHeight - 1; nY >= 0; nY--)
{
unsigned char *pMask = NULL;
int nX = 0;
for (nX = 0, pMask = pImageStream->GetNextLine(); nX < nWidth; nX++)
{
int nIndex = 4 * (nX + nY * nWidth);
unsigned char unPixel = *pMask++ ^ nInvert;
pBufferPtr[nIndex + 0] = unPixel ? 255 : 0;
pBufferPtr[nIndex + 1] = unPixel ? 255 : 0;
pBufferPtr[nIndex + 2] = unPixel ? 255 : 0;
pBufferPtr[nIndex + 3] = unPixel ? 0 : unAlpha;
}
}
delete pImageStream;
double arrMatrix[6];
double *pCTM = pGState->GetCTM();
// Èñõîäíîå ïðåäîáðàçîâàíèå
// |1 0 0| |pCTM[0] pCTM[1] 0|
// arrMattrix = |0 -1 0| * |pCTM[2] pCTM[3] 0|
// |0 1 1| |pCTM[4] pCTM[5] 1|
arrMatrix[0] = pCTM[0];
arrMatrix[1] = -pCTM[1];
arrMatrix[2] = -pCTM[2];
arrMatrix[3] = -(-pCTM[3]);
arrMatrix[4] = pCTM[2] + pCTM[4];
arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight;
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
}
void RendererOutputDev::DrawImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, int *pMaskColors, bool bInlineImg)
{
double dPageHeight = pGState->GetPageHeight();
int nBufferSize = 4 * nWidth * nHeight;
if (nBufferSize < 1)
return;
unsigned char *pBufferPtr = new unsigned char[nBufferSize];
if (!pBufferPtr)
return;
Aggplus::CImage oImage;
oImage.Create(pBufferPtr, nWidth, nHeight, 4 * nWidth);
// Ïèøåì äàííûå â pBufferPtr
ImageStream *pImageStream = new ImageStream(pStream, nWidth, pColorMap->GetComponentsCount(), pColorMap->GetBitsPerComponent());
pImageStream->Reset();
unsigned char unAlpha = m_bTransparentGroup ? 255.0 * pGState->GetFillOpacity() : 255;
unsigned char unPixel[32] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int nY = nHeight - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nX + nY * nWidth);
pImageStream->GetPixel(unPixel);
GrRGB oRGB;
pColorMap->GetRGB(unPixel, &oRGB);
pBufferPtr[nIndex + 0] = ColorToByte(oRGB.b);
pBufferPtr[nIndex + 1] = ColorToByte(oRGB.g);
pBufferPtr[nIndex + 2] = ColorToByte(oRGB.r);
pBufferPtr[nIndex + 3] = unAlpha;
}
}
delete pImageStream;
double arrMatrix[6];
double *pCTM = pGState->GetCTM();
// Èñõîäíîå ïðåäîáðàçîâàíèå
// |1 0 0| |pCTM[0] pCTM[1] 0|
// arrMatrix = |0 -1 0| * |pCTM[2] pCTM[3] 0|
// |0 1 1| |pCTM[4] pCTM[5] 1|
arrMatrix[0] = pCTM[0];
arrMatrix[1] = -pCTM[1];
arrMatrix[2] = -pCTM[2];
arrMatrix[3] = -(-pCTM[3]);
arrMatrix[4] = pCTM[2] + pCTM[4];
arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight;
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
}
void RendererOutputDev::DrawMaskedImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, bool bMaskInvert)
{
// Âîîáùå, ðàçìåðû ìàñêè è ñàìîé êàðòèíêè ìîãóò íå ñîâïàäàòü (â ýòîì ñëó÷àå ìû äîëæíû ñðåçàéçèòü äî ðàçìåðîâ êàðòèíêè)
// TO DO: Ñäåëàòü, êîãäà ïîÿâèòñÿ ôàéë
if (nWidth != nMaskWidth || nHeight != nMaskHeight)
DrawImage(pGState, pRef, pStream, nWidth, nHeight, pColorMap, NULL, false);
double dPageHeight = pGState->GetPageHeight();
int nBufferSize = 4 * nWidth * nHeight;
if (nBufferSize < 1)
return;
unsigned char *pBufferPtr = new unsigned char[nBufferSize];
if (!pBufferPtr)
return;
Aggplus::CImage oImage;
oImage.Create(pBufferPtr, nWidth, nHeight, 4 * nWidth);
// Ïèøåì äàííûå â pBufferPtr
ImageStream *pImageStream = new ImageStream(pStream, nWidth, pColorMap->GetComponentsCount(), pColorMap->GetBitsPerComponent());
ImageStream *pMask = new ImageStream(pMaskStream, nMaskWidth, 1, 1);
pMask->Reset();
pImageStream->Reset();
unsigned char unPixel[4] ={ 0, 0, 0, 0 };
unsigned char unMask = 0;
for (int nY = nHeight - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nX + nY * nWidth);
pImageStream->GetPixel(unPixel);
pMask->GetPixel(&unMask);
GrRGB oRGB;
pColorMap->GetRGB(unPixel, &oRGB);
pBufferPtr[nIndex + 0] = ColorToByte(oRGB.b);
pBufferPtr[nIndex + 1] = ColorToByte(oRGB.g);
pBufferPtr[nIndex + 2] = ColorToByte(oRGB.r);
if (unMask && !bMaskInvert)
pBufferPtr[nIndex + 3] = 0;
else
pBufferPtr[nIndex + 3] = 255;
}
}
delete pMask;
delete pImageStream;
double arrMatrix[6];
double *pCTM = pGState->GetCTM();
// Èñõîäíîå ïðåäîáðàçîâàíèå
// |1 0 0| |pCTM[0] pCTM[1] 0|
// arrMatrix = |0 -1 0| * |pCTM[2] pCTM[3] 0|
// |0 1 1| |pCTM[4] pCTM[5] 1|
arrMatrix[0] = pCTM[0];
arrMatrix[1] = -pCTM[1];
arrMatrix[2] = -pCTM[2];
arrMatrix[3] = -(-pCTM[3]);
arrMatrix[4] = pCTM[2] + pCTM[4];
arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight;
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
}
void RendererOutputDev::DrawSoftMaskedImage(GrState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight, GrImageColorMap *pColorMap, Stream *pMaskStream, int nMaskWidth, int nMaskHeight, GrImageColorMap *pMaskColorMap)
{
double dPageHeight = pGState->GetPageHeight();
int nBufferSize = 4 * nWidth * nHeight;
if (nBufferSize < 1)
return;
unsigned char *pBufferPtr = new unsigned char[nBufferSize];
if (!pBufferPtr)
return;
Aggplus::CImage oImage;
oImage.Create(pBufferPtr, nWidth, nHeight, 4 * nWidth);
// Ïèøåì äàííûå â pBufferPtr
ImageStream *pImageStream = new ImageStream(pStream, nWidth, pColorMap->GetComponentsCount(), pColorMap->GetBitsPerComponent());
pImageStream->Reset();
double dAlphaKoef = m_bTransparentGroup ? pGState->GetFillOpacity() : 1;
unsigned char unPixel[4] ={ 0, 0, 0, 0 };
for (int nY = nHeight - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nX + nY * nWidth);
pImageStream->GetPixel(unPixel);
GrRGB oRGB;
pColorMap->GetRGB(unPixel, &oRGB);
pBufferPtr[nIndex + 0] = ColorToByte(oRGB.b);
pBufferPtr[nIndex + 1] = ColorToByte(oRGB.g);
pBufferPtr[nIndex + 2] = ColorToByte(oRGB.r);
pBufferPtr[nIndex + 3] = 255;
}
}
delete pImageStream;
if (nWidth != nMaskWidth || nHeight != nMaskHeight)
{
// TO DO: Çäåñü ñäåëàí ýëåìåíòàðíûé âàðèàíò ìàñøòàáèðîâàíèÿ ìàñêè.
// Íàäî óëó÷øèòü àëãîðèòì.
bool bResize = true;
if (0 != nWidth && 0 != nMaskHeight && 0 != nHeight && 0 != nMaskWidth)
{
ImageStream *pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->GetComponentsCount(), pMaskColorMap->GetBitsPerComponent());
unsigned char *pAlpha = new unsigned char[nMaskWidth * nMaskHeight];
if (pMaskStream && pAlpha)
{
pSMaskStream->Reset();
unsigned char unAlpha = 0;
for (int nY = 0; nY < nMaskHeight; nY++)
{
for (int nX = 0; nX < nMaskWidth; nX++)
{
int nIndex = (nX + nY * nMaskWidth);
pSMaskStream->GetPixel(&unAlpha);
GrGray oGray;
pMaskColorMap->GetGray(&unAlpha, &oGray);
pAlpha[nIndex] = ColorToByte(oGray);
}
}
delete pSMaskStream;
double dScaleWidth = (double)nMaskWidth / (double)nWidth;
double dScaleHeight = (double)nMaskHeight / (double)nHeight;
for (int nY = nHeight - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nY * nWidth + nX);
int nNearestMatch = (((int)((nHeight - 1 - nY) * dScaleHeight) * nMaskWidth) + ((int)(nX * dScaleWidth)));
pBufferPtr[nIndex + 3] = (unsigned char)(pAlpha[nNearestMatch] * dAlphaKoef);
}
}
delete pAlpha;
}
else
{
if (pAlpha)
delete pAlpha;
if (pMaskStream)
delete pMaskStream;
bResize = false;
}
}
else
bResize = false;
if (!bResize)
{
for (int nY = nHeight - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nY * nWidth + nX);
pBufferPtr[nIndex + 3] = (unsigned char)(255.0 * dAlphaKoef);
}
}
}
}
else
{
ImageStream *pSMaskStream = new ImageStream(pMaskStream, nMaskWidth, pMaskColorMap->GetComponentsCount(), pMaskColorMap->GetBitsPerComponent());
pSMaskStream->Reset();
unsigned char unAlpha = 0;
for (int nY = nHeight - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nX + nY * nWidth);
pSMaskStream->GetPixel(&unAlpha);
GrGray oGray;
pMaskColorMap->GetGray(&unAlpha, &oGray);
pBufferPtr[nIndex + 3] = ColorToByte(oGray) * dAlphaKoef;
}
}
delete pSMaskStream;
}
double arrMatrix[6];
double *pCTM = pGState->GetCTM();
// Èñõîäíîå ïðåäîáðàçîâàíèå
// |1 0 0| |pCTM[0] pCTM[1] 0|
// arrMattrix = |0 -1 0| * |pCTM[2] pCTM[3] 0|
// |0 1 1| |pCTM[4] pCTM[5] 1|
arrMatrix[0] = pCTM[0];
arrMatrix[1] = -pCTM[1];
arrMatrix[2] = -pCTM[2];
arrMatrix[3] = -(-pCTM[3]);
arrMatrix[4] = pCTM[2] + pCTM[4];
arrMatrix[5] = -(pCTM[3] + pCTM[5]) + dPageHeight;
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY, true);
m_pRenderer->DrawImage(&oImage, 0 + dShiftX, 0 + dShiftY, PDFCoordsToMM(1), PDFCoordsToMM(1));
}
void RendererOutputDev::BeginTransparencyGroup(GrState *pGState, double *pBBox, GrColorSpace *pBlendingColorSpace, bool bIsolated, bool bKnockout, bool bForSoftMask)
{
m_bTransparentGroup = true;
m_bTransparentGroupSoftMask = bForSoftMask;
}
void RendererOutputDev::EndTransparencyGroup(GrState *pGState)
{
m_bTransparentGroup = false;
m_bTransparentGroupSoftMask = false;
if (m_pTransparentGroupSoftMask)
delete[]m_pTransparentGroupSoftMask;
m_pTransparentGroupSoftMask = NULL;
}
void RendererOutputDev::PaintTransparencyGroup(GrState *pGState, double *pBBox)
{
}
void RendererOutputDev::SetSoftMask(GrState *pGState, double *pBBox, bool bAlpha, Function *pTransferFunc, GrColor *pBackdropColor)
{
}
void RendererOutputDev::ClearSoftMask(GrState *pGState)
{
}
void RendererOutputDev::NewPDF(XRef *pXref)
{
m_pXref = pXref;
}
void RendererOutputDev::Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY)
{
*pdDeviceX = dUserX * pMatrix[0] + dUserY * pMatrix[2] + pMatrix[4];
*pdDeviceY = dUserX * pMatrix[1] + dUserY * pMatrix[3] + pMatrix[5];
}
void RendererOutputDev::DoPath(GrState *pGState, GrPath *pPath, double dPageHeight, double *pCTM)
{
if (m_bTransparentGroup)
return;
double arrMatrix[6];
//double *pCTM = pGState->GetCTM();
arrMatrix[0] = pCTM[0];
arrMatrix[1] = -pCTM[1];
arrMatrix[2] = pCTM[2];
arrMatrix[3] = -pCTM[3];
arrMatrix[4] = pCTM[4];
arrMatrix[5] = -pCTM[5] + dPageHeight;
double dShiftX = 0, dShiftY = 0;
DoTransform(arrMatrix, &dShiftX, &dShiftY);
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
int nSubPathCount = pPath->GetSubpathsCount();
for (int nSubPathIndex = 0; nSubPathIndex < nSubPathCount; ++nSubPathIndex)
{
GrSubpath *pSubpath = pPath->GetSubpath(nSubPathIndex);
int nPointsCount = pSubpath->GetPointsCount();
m_pRenderer->PathCommandMoveTo(PDFCoordsToMM(pSubpath->GetX(0) + dShiftX), PDFCoordsToMM(pSubpath->GetY(0) + dShiftY));
int nCurPointIndex = 1;
while (nCurPointIndex < nPointsCount)
{
if (pSubpath->GetCurve(nCurPointIndex))
{
m_pRenderer->PathCommandCurveTo(PDFCoordsToMM(pSubpath->GetX(nCurPointIndex) + dShiftX), PDFCoordsToMM(pSubpath->GetY(nCurPointIndex) + dShiftY), PDFCoordsToMM(pSubpath->GetX(nCurPointIndex + 1) + dShiftX), PDFCoordsToMM(pSubpath->GetY(nCurPointIndex + 1) + dShiftY), PDFCoordsToMM(pSubpath->GetX(nCurPointIndex + 2) + dShiftX), PDFCoordsToMM(pSubpath->GetY(nCurPointIndex + 2) + dShiftY));
nCurPointIndex += 3;
}
else
{
m_pRenderer->PathCommandLineTo(PDFCoordsToMM(pSubpath->GetX(nCurPointIndex) + dShiftX), PDFCoordsToMM(pSubpath->GetY(nCurPointIndex) + dShiftY));
++nCurPointIndex;
}
}
if (pSubpath->IsClosed())
{
m_pRenderer->PathCommandClose();
}
}
}
void RendererOutputDev::UpdateClip(GrState *pGState)
{
if (m_bTransparentGroup)
return;
if (m_bTiling)
return;
UpdateClipAttack(pGState);
}
void RendererOutputDev::UpdateClipAttack(GrState *pGState)
{
GrClip *pClip = pGState->GetClip();
int nPathIndex = -1;
//if ( m_pClip && m_pClip->IsEqual( pClip, nPathIndex ) )
//{
// return;
//}
if (-1 == nPathIndex)
{
m_pRenderer->BeginCommand(c_nResetClipType);
m_pRenderer->EndCommand(c_nResetClipType);
for (int nIndex = 0; nIndex < pClip->GetPathsCount(); nIndex++)
{
GrPath *pPath = pClip->GetPath(nIndex);
int nFlag = pClip->GetFlag(nIndex);
double *pMatrix = pClip->GetMatrix(nIndex);
int nClipFlag = GrClipEOFlag == nFlag ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding;
nClipFlag |= c_nClipRegionIntersect;
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(nClipFlag);
DoPath(pGState, pPath, pGState->GetPageHeight(), pMatrix);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
}
for (int nIndex = 0; nIndex < pClip->GetTextsCount(); nIndex++)
{
WString wsFontName, wsFontPath;
int lFontStyle;
double dFontSize = 10, dX = 0, dY = 0, dWidth = 0, dHeight = 0, dBaseLineOffset = 0;
WString wsText = pClip->GetText(nIndex, &dX, &dY, &dWidth, &dHeight, &dBaseLineOffset, &wsFontName, &wsFontPath, &dFontSize, &lFontStyle);
int nFlag = pClip->GetFlag(nIndex);
m_pRenderer->put_FontName(wsFontName);
m_pRenderer->put_FontPath(wsFontPath);
m_pRenderer->put_FontSize(dFontSize);
m_pRenderer->put_FontStyle(lFontStyle);
double dShiftX = 0, dShiftY = 0;
DoTransform(pClip->GetTextMatrix(nIndex), &dShiftX, &dShiftY, true);
int nFlags = 0;
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionUnion);
m_pRenderer->PathCommandEnd();
m_pRenderer->put_FontStringGID(true);
m_pRenderer->PathCommandTextEx(wsText, L"", PDFCoordsToMM(dX), PDFCoordsToMM(dY), PDFCoordsToMM(dWidth), PDFCoordsToMM(dHeight), PDFCoordsToMM(dBaseLineOffset), 0);
m_pRenderer->EndCommand(c_nClipType);
}
}
else
{
for (int nIndex = nPathIndex; nIndex < pClip->GetPathsCount(); nIndex++)
{
GrPath *pPath = pClip->GetPath(nIndex);
int nFlag = pClip->GetFlag(nIndex);
double *pMatrix = pClip->GetMatrix(nIndex);
int nClipFlag = GrClipEOFlag == nFlag ? c_nClipRegionTypeEvenOdd : c_nClipRegionTypeWinding;
nClipFlag |= c_nClipRegionIntersect;
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->put_ClipMode(nClipFlag);
DoPath(pGState, pPath, pGState->GetPageHeight(), pMatrix);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
}
}
if (m_pClip)
delete m_pClip;
m_pClip = pClip->Copy();
UpdateFont(pGState);
}
void RendererOutputDev::DoTransform(double *pMatrix, double *pdShiftX, double *pdShiftY, bool bText)
{
if (1 == pMatrix[0] && 0 == pMatrix[1] && 0 == pMatrix[2] && 1 == pMatrix[3] && !bText)
{
if (0 == pMatrix[4] && 0 == pMatrix[5])
{
m_pRenderer->ResetTransform();
m_arrMatrix[0] = 1; m_arrMatrix[1] = 0;
m_arrMatrix[2] = 0; m_arrMatrix[3] = 1;
m_arrMatrix[4] = 0; m_arrMatrix[5] = 0;
}
else
{
*pdShiftX = pMatrix[4];
*pdShiftY = pMatrix[5];
m_pRenderer->ResetTransform();
m_arrMatrix[0] = 1; m_arrMatrix[1] = 0;
m_arrMatrix[2] = 0; m_arrMatrix[3] = 1;
m_arrMatrix[4] = 0; m_arrMatrix[5] = 0;
}
}
else if (m_arrMatrix[0] == pMatrix[0] && m_arrMatrix[1] == pMatrix[1] && m_arrMatrix[2] == pMatrix[2] && m_arrMatrix[3] == pMatrix[3] && !bText)
{
double dNewX = pMatrix[4], dNewY = pMatrix[5];
double dIDet = 1 / (pMatrix[0] * pMatrix[3] - pMatrix[1] * pMatrix[2]);
*pdShiftX = ((dNewX - m_arrMatrix[4]) * m_arrMatrix[3] - (dNewY - m_arrMatrix[5]) * m_arrMatrix[1]) * dIDet;
*pdShiftY = ((dNewY - m_arrMatrix[5]) * m_arrMatrix[0] - (dNewX - m_arrMatrix[4]) * m_arrMatrix[2]) * dIDet;
}
else
{
m_pRenderer->SetTransform(pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3], PDFCoordsToMM(pMatrix[4]), PDFCoordsToMM(pMatrix[5]));
m_arrMatrix[0] = pMatrix[0]; m_arrMatrix[1] = pMatrix[1];
m_arrMatrix[2] = pMatrix[2]; m_arrMatrix[3] = pMatrix[3];
m_arrMatrix[4] = pMatrix[4]; m_arrMatrix[5] = pMatrix[5];
}
return;
}
}