Files
core/ASCOfficePDFWriter/PdfWriterLib/FontCID.cpp
Elen.Subbotina 2276da418e правки под Linux после исправлений под iOs . BOOL -> bool (TRUE->true, FALSE->false)
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62078 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-20 23:57:10 +03:00

2015 lines
60 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "FontCID.h"
//----- CIDTypeFontDef вспомогательные функции ------------------------------------------------------
void CIDFontDefFreeWidth (FontDef pFontDef)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
for ( unsigned int nIndex = 0; nIndex < pAttr->pW->nCount; nIndex++)
{
CIDWidth *pW = (CIDWidth *)ListItemAt( pAttr->pW, nIndex);
FreeMem( pFontDef->oMMgr, pW);
}
ListFree( pAttr->pW );
pAttr->pW = NULL;
pFontDef->bValid = false;
}
void CIDFontDefFreeFunc (FontDef pFontDef)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
if ( pAttr->pFontData )
{
StreamFree( pAttr->pFontData );
pAttr->pFontData = NULL;
}
if ( pAttr->pCIDtoGIDMap )
{
StreamFree( pAttr->pCIDtoGIDMap );
pAttr->pCIDtoGIDMap = NULL;
}
CIDFontDefFreeWidth( pFontDef );
FreeMem( pFontDef->oMMgr, pAttr);
}
//----- CIDTypeFontDef основные функции -------------------------------------------------------------
FontDef CIDFontDefNew (MMgr oMMgr, char *sName, FontDefInitFunc pInitFn)
{
if ( !oMMgr )
return NULL;
FontDef pFontDef = (FontDef)GetMem( oMMgr, sizeof(FontDefRec) );
if ( !pFontDef )
return NULL;
UtilsMemSet( pFontDef, 0, sizeof(FontDefRec) );
pFontDef->nSigBytes = FONTDEF_SIG_BYTES;
UtilsStrCpy( pFontDef->sBaseFont, sName, pFontDef->sBaseFont + LIMIT_MAX_NAME_LEN);
pFontDef->oMMgr = oMMgr;
pFontDef->oError = oMMgr->oError;
pFontDef->eType = FontDefCID;
pFontDef->pFreeFn = CIDFontDefFreeFunc;
pFontDef->pInitFn = pInitFn;
pFontDef->bValid = false;
CIDFontDefAttr pFontDefAttr = (CIDFontDefAttr)GetMem( oMMgr, sizeof(CIDFontDefAttrRec) );
if ( !pFontDefAttr )
{
FreeMem( pFontDef->oMMgr, pFontDef );
return NULL;
}
pFontDef->pAttr = pFontDefAttr;
UtilsMemSet( (BYTE *)pFontDefAttr, 0, sizeof(CIDFontDefAttrRec) );
pFontDefAttr->pW = ListNew( oMMgr, DEF_CHAR_WIDTHS_NUM );
if ( !pFontDefAttr->pW )
{
FreeMem( pFontDef->oMMgr, pFontDef);
FreeMem( pFontDef->oMMgr, pFontDefAttr);
return NULL;
}
pFontDef->nMissingWidth = 500;
pFontDefAttr->nDW = 1000;
pFontDefAttr->anDW2[0] = 880;
pFontDefAttr->anDW2[1] = -1000;
pFontDefAttr->pW2 = ListNew( oMMgr, DEF_CHAR_WIDTHS_NUM );
if ( !pFontDefAttr->pW2 )
{
ListFree( pFontDefAttr->pW );
FreeMem( pFontDef->oMMgr, pFontDef);
FreeMem( pFontDef->oMMgr, pFontDefAttr);
return NULL;
}
pFontDefAttr->nCIDtoGIDtype = -1;
pFontDefAttr->pCIDtoGIDMap = NULL;
return pFontDef;
}
unsigned long CIDFontDefLoadFontData(FontDef pFontDef, std::wstring wsFilePath, CIDFontFileType eCIDType)
{
if ( !pFontDef || FontDefCID != pFontDef->eType )
return OK;
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
pAttr->eType = eCIDType;
if ( wsFilePath.length() < 1 )return S_OK;
CFile oFile;
if (oFile.OpenFile(std_string2string(wsFilePath)) != S_OK)
return AVS_OFFICEPDFWRITER_ERROR_FILE_OPEN_ERROR;
ULONG64 fileSize = oFile.GetFileSize();
BYTE *fileContent = new BYTE[fileSize];
if (!fileContent)
{
oFile.CloseFile();
return AVS_OFFICEPDFWRITER_ERROR_FILE_OPEN_ERROR;
}
oFile.ReadFile(fileContent, fileSize);
oFile.CloseFile();
if ( pAttr->pFontData )
StreamFree( pAttr->pFontData );
pAttr->pFontData = TempFileStreamNew( pFontDef->oMMgr );
if ( !pAttr->pFontData )
{
delete []fileContent;
return AVS_OFFICEPDFWRITER_ERROR_NOT_ENOUGH_MEMORY;
}
StreamWrite( pAttr->pFontData, fileContent, fileSize, true );
delete []fileContent;
return S_OK;
}
void CIDFontDefSetInfoSys (FontDef pFontDef, char *sRegistry, char *sOrdering, int nSupplement)
{
if ( !pFontDef || FontDefCID != pFontDef->eType )
return;
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
UtilsStrCpy( pAttr->sRegistry, sRegistry, pAttr->sRegistry + LIMIT_MAX_NAME_LEN );
UtilsStrCpy( pAttr->sOrdering, sOrdering, pAttr->sOrdering + LIMIT_MAX_NAME_LEN );
pAttr->nSupplement = nSupplement;
}
void CIDFontDefSetDW (FontDef pFontDef, int nDW)
{
if ( !pFontDef || FontDefCID != pFontDef->eType )
return;
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
pAttr->nDW = nDW;
}
void CIDFontDefSetDW2 (FontDef pFontDef, int anDW2[2])
{
if ( !pFontDef || FontDefCID != pFontDef->eType )
return;
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
pAttr->anDW2[0] = anDW2[0];
pAttr->anDW2[1] = anDW2[1];
}
short CIDFontDefGetCIDWidth (FontDef pFontDef, unsigned short nCid)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
for ( unsigned int nIndex = 0; nIndex < pAttr->pW->nCount; nIndex++)
{
CIDWidth *pW = (CIDWidth *)ListItemAt( pAttr->pW, nIndex);
if ( nCid >= pW->unCid_First && nCid <= pW->unCid_Last )
return pW->shWidth;
}
// Не найден в массиве PDF_CID
return pAttr->nDW;
}
unsigned long CIDFontDefAddWidth (FontDef pFontDef, const CIDWidth *pWidths)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
while ( 0xFFFF != pWidths->unCid_First )
{
CIDWidth *pCurWidth = (CIDWidth*)GetMem( pFontDef->oMMgr, sizeof (CIDWidth) );
unsigned long nRet = OK;
if ( !pCurWidth )
return pFontDef->oError->nErrorNo;
pCurWidth->unCid_First = pWidths->unCid_First;
pCurWidth->unCid_Last = pWidths->unCid_Last;
pCurWidth->shWidth = pWidths->shWidth;
if ( OK != ( nRet = ListAdd( pAttr->pW, pCurWidth ) ) )
{
FreeMem( pFontDef->oMMgr, pCurWidth);
return nRet;
}
pWidths++;
}
return OK;
}
unsigned long CIDFontDefAddWidth (FontDef pFontDef, CIDWidth oWidth)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
CIDWidth *pCurWidth = (CIDWidth*)GetMem( pFontDef->oMMgr, sizeof (CIDWidth) );
unsigned long nRet = OK;
if ( !pCurWidth )
return pFontDef->oError->nErrorNo;
pCurWidth->unCid_First = oWidth.unCid_First;
pCurWidth->unCid_Last = oWidth.unCid_Last;
pCurWidth->shWidth = oWidth.shWidth;
if ( OK != ( nRet = ListAdd( pAttr->pW, pCurWidth ) ) )
{
FreeMem( pFontDef->oMMgr, pCurWidth);
return nRet;
}
return OK;
}
unsigned long CIDFontDefAddWidth2 (FontDef pFontDef, const CIDWidth2 *pWidths)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
while ( 0xFFFF != pWidths->unCid_First )
{
CIDWidth2 *pCurWidth = (CIDWidth2*)GetMem( pFontDef->oMMgr, sizeof (CIDWidth2) );
unsigned long nRet = OK;
if ( !pCurWidth )
return pFontDef->oError->nErrorNo;
pCurWidth->unCid_First = pWidths->unCid_First;
pCurWidth->unCid_Last = pWidths->unCid_Last;
pCurWidth->shW = pWidths->shW;
pCurWidth->shVx = pWidths->shVx;
pCurWidth->shVy = pWidths->shVy;
if ( OK != ( nRet = ListAdd( pAttr->pW2, pCurWidth ) ) )
{
FreeMem( pFontDef->oMMgr, pCurWidth);
return nRet;
}
pWidths++;
}
return OK;
}
unsigned long CIDFontDefAddWidth2 (FontDef pFontDef, CIDWidth2 oWidths2)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
CIDWidth2 *pCurWidth = (CIDWidth2*)GetMem( pFontDef->oMMgr, sizeof (CIDWidth2) );
unsigned long nRet = OK;
if ( !pCurWidth )
return pFontDef->oError->nErrorNo;
pCurWidth->unCid_First = oWidths2.unCid_First;
pCurWidth->unCid_Last = oWidths2.unCid_Last;
pCurWidth->shW = oWidths2.shW;
pCurWidth->shVx = oWidths2.shVx;
pCurWidth->shVy = oWidths2.shVy;
if ( OK != ( nRet = ListAdd( pAttr->pW2, pCurWidth ) ) )
{
FreeMem( pFontDef->oMMgr, pCurWidth);
return nRet;
}
return OK;
}
unsigned long CIDFontDefSetCIDtoGID (FontDef pFontDef, char *sName)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
if ( !sName )
return OK;
pAttr->nCIDtoGIDtype = 0;
UtilsStrCpy( pAttr->sCIDtoGIDMap, sName, pAttr->sCIDtoGIDMap + LIMIT_MAX_NAME_LEN );
return OK;
}
unsigned long CIDFontDefSetCIDtoGID (FontDef pFontDef, BYTE *pBuffer, int nSize)
{
CIDFontDefAttr pAttr = (CIDFontDefAttr)pFontDef->pAttr;
if ( !pBuffer || 0 == nSize )
return OK;
if ( pAttr->pCIDtoGIDMap )
StreamFree( pAttr->pCIDtoGIDMap );
pAttr->nCIDtoGIDtype = 1;
pAttr->pCIDtoGIDMap = TempFileStreamNew( pFontDef->oMMgr );
if ( !pAttr->pCIDtoGIDMap )
return AVS_OFFICEPDFWRITER_ERROR_NOT_ENOUGH_MEMORY;
StreamSeek( pAttr->pCIDtoGIDMap, 0, SeekSet );
StreamWrite( pAttr->pCIDtoGIDMap, pBuffer, nSize, true );
return OK;
}
unsigned long CIDFontDefChangeStyle (FontDef pFontDef, bool bBold, bool bItalic)
{
if ( !pFontDef || !pFontDef->pAttr )
return AVS_OFFICEPDFWRITER_ERROR_INVALID_FONTDEF_DATA;
if ( bBold )
{
pFontDef->nStemV *= 2;
pFontDef->nFlags |= FONT_FOURCE_BOLD;
}
if ( bItalic )
{
pFontDef->nItalicAngle -= 11;
pFontDef->nFlags |= FONT_ITALIC;
}
return OK;
}
//----- CIDTypeFont вспомогательные функции ---------------------------------------------------------
static unsigned long CIDFontType2BeforeWriteFunc (Dict pObj)
{
FontAttr pFontAttr = (FontAttr)pObj->pAttr;
FontDef pDef = pFontAttr->pFontDef;
TTFontDefAttrRecPtr pDefAttr = (TTFontDefAttrRecPtr)pDef->pAttr;
unsigned long nRet = OK;
if ( pFontAttr->pMapStream )
pFontAttr->pMapStream->nFilter = pObj->nFilter;
if ( pFontAttr->pCMapStream )
pFontAttr->pCMapStream->nFilter = pObj->nFilter;
if ( !pFontAttr->pFontDef->pDescriptor )
{
Dict pDescriptor = DictNew( pObj->oMMgr );
if ( !pDescriptor )
return ErrorGetCode( pObj->oError );
if ( pDefAttr->bEmbedding )
{
Dict pFontData = DictStreamNew( pObj->oMMgr, pFontAttr->pXref );
if ( !pFontData )
return ErrorGetCode( pObj->oError );
if ( OK != TTFontDefSaveFontData( pFontAttr->pFontDef, pFontData->pStream ) )
return ErrorGetCode( pObj->oError );
nRet += DictAdd( pDescriptor, "FontFile2", pFontData );
nRet += DictAddNumber( pFontData, "Length1", pDefAttr->nLength1 );
nRet += DictAddNumber( pFontData, "Length2", 0);
nRet += DictAddNumber( pFontData, "Length3", 0);
pFontData->nFilter = pObj->nFilter;
if ( OK != nRet )
return ErrorGetCode( pObj->oError );
}
nRet += XrefAdd( pFontAttr->pXref, pDescriptor );
nRet += DictAddName( pDescriptor, "Type", "FontDescriptor" );
nRet += DictAddNumber( pDescriptor, "Ascent", pDef->nAscent );
nRet += DictAddNumber( pDescriptor, "Descent", pDef->nDescent );
nRet += DictAddNumber( pDescriptor, "Flags", pDef->nFlags );
Array oArray = BoxArrayNew( pObj->oMMgr, pDef->oFontBox );
nRet += DictAdd( pDescriptor, "FontBBox", oArray );
nRet += DictAddName( pDescriptor, "FontName", pDefAttr->sBaseFont );
nRet += DictAddNumber( pDescriptor, "ItalicAngle", pDef->nItalicAngle );
nRet += DictAddNumber( pDescriptor, "StemV", pDef->nStemV );
nRet += DictAddNumber( pDescriptor, "XHeight", pDef->nXHeight );
if ( OK != nRet )
return ErrorGetCode( pObj->oError );
pFontAttr->pFontDef->pDescriptor = pDescriptor;
}
if ( OK != ( nRet = DictAddName( pObj, "BaseFont", pDefAttr->sBaseFont ) ) )
return nRet;
if ( OK != ( nRet = DictAddName( pFontAttr->pDescendantFont, "BaseFont", pDefAttr->sBaseFont ) ) )
return nRet;
return DictAdd( pFontAttr->pDescendantFont, "FontDescriptor", pFontAttr->pFontDef->pDescriptor );
}
static FontDict CIDFontTypeNew (FontDict pParent, Xref pXref)
{
unsigned long nRet = OK;
FontAttr pAttr = (FontAttr)pParent->pAttr;
FontDef pFontDef = pAttr->pFontDef;
CIDFontDefAttr pFontDefAttr = (CIDFontDefAttr)pFontDef->pAttr;
EncoderRecPtr pEncoder = pAttr->pEncoder;
CMapEncoderStreamAttr pEncoderAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
FontDict pFont = DictNew( pParent->oMMgr );
if ( !pFont )
return NULL;
if ( OK != XrefAdd( pXref, pFont ) )
return NULL;
nRet += DictAddName( pFont, "Type", "Font" );
if ( cidType0 == pFontDefAttr->eType || cidType0C == pFontDefAttr->eType || cidType0COT == pFontDefAttr->eType )
nRet += DictAddName( pFont, "Subtype", "CIDFontType0" );
else// if ( cidType2 == pFontDefAttr->eType || cidType2OT == pFontDefAttr->eType )
nRet += DictAddName( pFont, "Subtype", "CIDFontType2" );
nRet += DictAddName( pFont, "BaseFont", pFontDef->sBaseFont );
nRet += DictAddNumber( pFont, "DW", pFontDefAttr->nDW );
if ( OK != nRet )
return NULL;
// Добавим элемент 'DW2'.
Array oArray = ArrayNew( pParent->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "DW2", oArray ) )
return NULL;
nRet += ArrayAddNumber( oArray, pFontDefAttr->anDW2[0]);
nRet += ArrayAddNumber( oArray, pFontDefAttr->anDW2[1]);
if ( OK != nRet )
return NULL;
if ( pFontDefAttr->pW->nCount > 0 )
{
// Добавим элемент 'W'.
oArray = ArrayNew( pParent->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "W", oArray ) )
return NULL;
unsigned short nSaveCid = 0;
Array oSubArray = NULL;
for ( unsigned int nIndex = 0; nIndex < pFontDefAttr->pW->nCount; nIndex++)
{
CIDWidth *pCurWidth = (CIDWidth *)ListItemAt( pFontDefAttr->pW, nIndex );
if ( pCurWidth->unCid_First != pCurWidth->unCid_Last )
{
// Формат с1 ... с2 w
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_First );
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_Last );
nRet += ArrayAddNumber( oArray, pCurWidth->shWidth );
continue;
}
if ( pCurWidth->unCid_First != nSaveCid + 1 || !oSubArray )
{
oSubArray = ArrayNew( pParent->oMMgr );
if ( !oSubArray )
return NULL;
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_First );
nRet += ArrayAdd( oArray, oSubArray );
}
nRet += ArrayAddNumber( oSubArray, pCurWidth->shWidth );
nSaveCid = pCurWidth->unCid_First;
if ( OK != nRet )
return NULL;
}
}
if ( pFontDefAttr->pW2->nCount > 0 )
{
// Добавим элемент 'W2'.
oArray = ArrayNew( pParent->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "W2", oArray ) )
return NULL;
unsigned short nSaveCid = 0;
Array oSubArray = NULL;
for ( unsigned int nIndex = 0; nIndex < pFontDefAttr->pW2->nCount; nIndex++)
{
CIDWidth2 *pCurWidth = (CIDWidth2 *)ListItemAt( pFontDefAttr->pW2, nIndex );
if ( pCurWidth->unCid_First != pCurWidth->unCid_Last )
{
// Формат с1 ... с2 W Vx Vy
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_First );
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_Last );
nRet += ArrayAddNumber( oArray, pCurWidth->shW );
nRet += ArrayAddNumber( oArray, pCurWidth->shVx );
nRet += ArrayAddNumber( oArray, pCurWidth->shVy );
continue;
}
if ( pCurWidth->unCid_First != nSaveCid + 1 || !oSubArray )
{
oSubArray = ArrayNew( pParent->oMMgr );
if ( !oSubArray )
return NULL;
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_First );
nRet += ArrayAdd( oArray, oSubArray );
}
nRet += ArrayAddNumber( oSubArray, pCurWidth->shW );
nRet += ArrayAddNumber( oSubArray, pCurWidth->shVx );
nRet += ArrayAddNumber( oSubArray, pCurWidth->shVy );
nSaveCid = pCurWidth->unCid_First;
if ( OK != nRet )
return NULL;
}
}
Dict pDescriptor = DictNew( pParent->oMMgr );
if ( !pDescriptor )
return NULL;
if ( OK != XrefAdd( pXref, pDescriptor ) )
return NULL;
if ( OK != DictAdd( pFont, "FontDescriptor", pDescriptor ) )
return NULL;
nRet += DictAddName( pDescriptor, "Type", "FontDescriptor");
nRet += DictAddName( pDescriptor, "FontName", pFontDef->sBaseFont );
nRet += DictAddNumber( pDescriptor, "Ascent", pFontDef->nAscent );
nRet += DictAddNumber( pDescriptor, "Descent", pFontDef->nDescent );
nRet += DictAddNumber( pDescriptor, "CapHeight", pFontDef->nCapHeight );
nRet += DictAddNumber( pDescriptor, "MissingWidth", pFontDef->nMissingWidth );
nRet += DictAddNumber( pDescriptor, "Flags", pFontDef->nFlags );
if ( OK != nRet )
return NULL;
oArray = BoxArrayNew( pParent->oMMgr, pFontDef->oFontBox );
if ( !oArray )
return NULL;
nRet += DictAdd( pDescriptor, "FontBBox", oArray );
nRet += DictAddNumber( pDescriptor, "ItalicAngle", pFontDef->nItalicAngle );
nRet += DictAddNumber( pDescriptor, "StemV", pFontDef->nStemV );
if ( pFontDefAttr->pFontData )
{
Dict pFontData = DictStreamNew( pParent->oMMgr, pXref );
if ( !pFontData )
return NULL;
if ( OK != StreamWriteToStream( pFontDefAttr->pFontData, pFontData->pStream, STREAM_FILTER_NONE, NULL ) )
return NULL;
if ( cidType0 == pFontDefAttr->eType )
nRet += DictAdd( pDescriptor, "FontFile", pFontData );
else if ( cidType0C == pFontDefAttr->eType )
{
nRet += DictAdd( pDescriptor, "FontFile3", pFontData );
nRet += DictAddName( pFontData, "Subtype", "CIDFontType0C" );
}
else if ( cidType2 == pFontDefAttr->eType )
{
nRet += DictAdd( pDescriptor, "FontFile2", pFontData );
}
else // if ( cidType0COT == pFontDefAttr->eType || cidType2OT == pFontDefAttr->eType )
{
nRet += DictAdd( pDescriptor, "FontFile3", pFontData );
nRet += DictAddName( pFontData, "Subtype", "OpenType" );
}
pFontData->nFilter = pFont->nFilter;
}
if ( OK != nRet )
return NULL;
if ( strlen( pFontDefAttr->sRegistry ) > 0 && strlen( pFontDefAttr->sOrdering ) > 0 )
{
Dict pCIDSystemInfo = DictNew( pParent->oMMgr );
if ( !pCIDSystemInfo )
return NULL;
if ( OK != DictAdd( pFont, "CIDSystemInfo", pCIDSystemInfo ) )
return NULL;
nRet += DictAdd( pCIDSystemInfo, "Registry", StringNew( pParent->oMMgr, pFontDefAttr->sRegistry, NULL ) );
nRet += DictAdd( pCIDSystemInfo, "Ordering", StringNew( pParent->oMMgr, pFontDefAttr->sOrdering, NULL ) );
nRet += DictAddNumber( pCIDSystemInfo, "Supplement", pFontDefAttr->nSupplement );
if ( OK != nRet )
return NULL;
}
if ( 0 == pFontDefAttr->nCIDtoGIDtype )
{
nRet += DictAddName( pFont, "CIDToGIDMap", pFontDefAttr->sCIDtoGIDMap );
}
else if ( 1 == pFontDefAttr->nCIDtoGIDtype )
{
Dict pCIDtoGID = DictStreamNew( pParent->oMMgr, pXref );
if ( !pCIDtoGID )
return NULL;
if ( OK != DictAdd( pFont, "CIDToGIDMap", pCIDtoGID ) )
return NULL;
if ( OK != StreamWriteToStream( pFontDefAttr->pCIDtoGIDMap, pCIDtoGID->pStream, STREAM_FILTER_NONE, NULL ) )
return NULL;
#ifdef FILTER_FLATE_DECODE_ENABLED
pCIDtoGID->nFilter |= STREAM_FILTER_FLATE_DECODE;
#endif
}
return pFont;
}
static FontDict CIDFontType0New (FontDict pParent, Xref pXref)
{
unsigned long nRet = OK;
FontAttr pAttr = (FontAttr)pParent->pAttr;
FontDef pFontDef = pAttr->pFontDef;
CIDFontDefAttr pFontDefAttr = (CIDFontDefAttr)pFontDef->pAttr;
EncoderRecPtr pEncoder = pAttr->pEncoder;
CMapEncoderAttr pEncoderAttr = (CMapEncoderAttr)pEncoder->pAttr;
FontDict pFont = DictNew( pParent->oMMgr );
if ( !pFont )
return NULL;
if ( OK != XrefAdd( pXref, pFont ) )
return NULL;
nRet += DictAddName( pFont, "Type", "Font" );
nRet += DictAddName( pFont, "Subtype", "CIDFontType0" );
nRet += DictAddNumber( pFont, "DW", pFontDefAttr->nDW );
nRet += DictAddName( pFont, "BaseFont", pFontDef->sBaseFont );
if ( OK != nRet )
return NULL;
// Добавим элемент 'DW2'.
Array oArray = ArrayNew( pParent->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "DW2", oArray ) )
return NULL;
nRet += ArrayAddNumber( oArray, pFontDefAttr->anDW2[0]);
nRet += ArrayAddNumber( oArray, pFontDefAttr->anDW2[1]);
if ( OK != nRet )
return NULL;
// Добавим элемент 'W'.
oArray = ArrayNew( pParent->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "W", oArray ) )
return NULL;
unsigned short nSaveCid = 0;
Array oSubArray = NULL;
for ( unsigned int nIndex = 0; nIndex < pFontDefAttr->pW->nCount; nIndex++)
{
CIDWidth *pCurWidth = (CIDWidth *)ListItemAt( pFontDefAttr->pW, nIndex );
if ( pCurWidth->unCid_First != pCurWidth->unCid_Last )
{
// Формат с1 ... с2 w
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_First );
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_Last );
nRet += ArrayAddNumber( oArray, pCurWidth->shWidth );
}
if ( pCurWidth->unCid_First != nSaveCid + 1 || !oSubArray )
{
oSubArray = ArrayNew( pParent->oMMgr );
if ( !oSubArray )
return NULL;
nRet += ArrayAddNumber( oArray, pCurWidth->unCid_First );
nRet += ArrayAdd( oArray, oSubArray );
}
nRet += ArrayAddNumber( oSubArray, pCurWidth->shWidth );
nSaveCid = pCurWidth->unCid_First;
if ( OK != nRet )
return NULL;
}
Dict pDescriptor = DictNew( pParent->oMMgr );
if ( !pDescriptor )
return NULL;
if ( OK != XrefAdd( pXref, pDescriptor ) )
return NULL;
if ( OK != DictAdd( pFont, "FontDescriptor", pDescriptor ) )
return NULL;
nRet += DictAddName( pDescriptor, "Type", "FontDescriptor");
nRet += DictAddName( pDescriptor, "FontName", pFontDef->sBaseFont );
nRet += DictAddNumber( pDescriptor, "Ascent", pFontDef->nAscent );
nRet += DictAddNumber( pDescriptor, "Descent", pFontDef->nDescent );
nRet += DictAddNumber( pDescriptor, "CapHeight", pFontDef->nCapHeight );
nRet += DictAddNumber( pDescriptor, "MissingWidth", pFontDef->nMissingWidth );
nRet += DictAddNumber( pDescriptor, "Flags", pFontDef->nFlags );
if ( OK != nRet )
return NULL;
oArray = BoxArrayNew( pParent->oMMgr, pFontDef->oFontBox );
if ( !oArray )
return NULL;
nRet += DictAdd( pDescriptor, "FontBBox", oArray );
nRet += DictAddNumber( pDescriptor, "ItalicAngle", pFontDef->nItalicAngle );
nRet += DictAddNumber( pDescriptor, "StemV", pFontDef->nStemV );
if ( OK != nRet )
return NULL;
Dict pCIDSystemInfo = DictNew( pParent->oMMgr );
if ( !pCIDSystemInfo )
return NULL;
if ( OK != DictAdd( pFont, "CIDSystemInfo", pCIDSystemInfo ) )
return NULL;
nRet += DictAdd( pCIDSystemInfo, "Registry", StringNew( pParent->oMMgr, pEncoderAttr->sRegistry, NULL ) );
nRet += DictAdd( pCIDSystemInfo, "Ordering", StringNew( pParent->oMMgr, pEncoderAttr->sOrdering, NULL ) );
nRet += DictAddNumber( pCIDSystemInfo, "Supplement", pEncoderAttr->nSuppliment );
if ( OK != nRet )
return NULL;
return pFont;
}
static FontDict CIDFontType2New (FontDict pParent, Xref pXref)
{
unsigned long nRet = OK;
FontAttr pAttr = (FontAttr)pParent->pAttr;
FontDef pFontDef = pAttr->pFontDef;
TTFontDefAttrRecPtr pFontDefAttr = (TTFontDefAttrRecPtr)pFontDef->pAttr;
EncoderRecPtr pEncoder = pAttr->pEncoder;
CMapEncoderAttr pEncoderAttr = (CMapEncoderAttr)pEncoder->pAttr;
unsigned short anTempMap[65536];
unsigned short nMax = 0;
FontDict pFont = DictNew( pParent->oMMgr );
if ( !pFont )
return NULL;
if ( OK != XrefAdd( pXref, pFont ) )
return NULL;
pParent->pBeforeWriteFn = CIDFontType2BeforeWriteFunc;
nRet += DictAddName( pFont, "Type", "Font");
nRet += DictAddName( pFont, "Subtype", "CIDFontType2");
nRet += DictAddNumber( pFont, "DW", pFontDef->nMissingWidth );
if ( OK != nRet )
return NULL;
// Добавим элемент 'DW2'.
Array oArray = ArrayNew( pFont->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "DW2", oArray ) )
return NULL;
nRet += ArrayAddNumber( oArray, pFontDef->oFontBox.fBottom );
nRet += ArrayAddNumber( oArray, pFontDef->oFontBox.fBottom - pFontDef->oFontBox.fTop );
UtilsMemSet( anTempMap, 0, sizeof(unsigned short) * 65536);
if ( OK != nRet )
return NULL;
for ( unsigned int nI = 0; nI < 256; nI++)
{
for ( unsigned int nJ = 0; nJ < 256; nJ++)
{
unsigned short nCid = pEncoderAttr->anCIDMap[nI][nJ];
if ( 0 != nCid )
{
unsigned short nUnicode = pEncoderAttr->anUnicodeMap[nI][nJ];
unsigned short nGid = TTFontDefGetGlyphID( pFontDef, nUnicode );
anTempMap[nCid] = nGid;
if ( nMax < nCid )
nMax = nCid;
}
}
}
if ( nMax > 0 )
{
short nDW = pFontDef->nMissingWidth;
unsigned short *pnTempMap = anTempMap;
Array oTempArray = NULL;
// Добавим элемент 'W'.
oArray = ArrayNew( pFont->oMMgr );
if ( !oArray )
return NULL;
if ( OK != DictAdd( pFont, "W", oArray ) )
return NULL;
for ( unsigned int nIndex = 0; nIndex < nMax; nIndex++, pnTempMap++)
{
int nWidth = TTFontDefGetGidWidth( pFontDef, *pnTempMap);
if ( nWidth != nDW )
{
if ( !oTempArray )
{
if ( OK != ( nRet = ArrayAddNumber( oArray, nIndex ) ) )
return NULL;
oTempArray = ArrayNew( pFont->oMMgr );
if ( !oTempArray )
return NULL;
if ( OK != ( nRet = ArrayAdd( oArray, oTempArray ) ) )
return NULL;
}
if ( OK != ( nRet = ArrayAddNumber( oTempArray, nWidth ) ) )
return NULL;
}
else
oTempArray = NULL;
}
// Создаем данные "CIDToGIDMap".
if ( pFontDefAttr->bEmbedding )
{
pAttr->pMapStream = DictStreamNew( pFont->oMMgr, pXref );
if ( !pAttr->pMapStream )
return NULL;
if ( OK != ( nRet = DictAdd( pFont, "CIDToGIDMap", pAttr->pMapStream ) ) )
return NULL;
for ( unsigned int nIndex = 0; nIndex < nMax; nIndex++)
{
BYTE anUnicodeTemp[2];
unsigned short nGid = anTempMap[nIndex];
anUnicodeTemp[0] = nGid >> 8;
anUnicodeTemp[1] = nGid;
UtilsMemCpy( (BYTE *)(anTempMap + nIndex), anUnicodeTemp, 2 );
}
if ( OK != ( nRet = StreamWrite( pAttr->pMapStream->pStream, (BYTE *)anTempMap, nMax * 2 ) ) )
return NULL;
}
}
else
{
SetError( pFont->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_FONTDEF_DATA, 0);
return 0;
}
Dict pCIDSystemInfo = DictNew( pParent->oMMgr );
if ( !pCIDSystemInfo )
return NULL;
if ( OK != DictAdd( pFont, "CIDSystemInfo", pCIDSystemInfo ) )
return NULL;
nRet += DictAdd( pCIDSystemInfo, "Registry", StringNew( pParent->oMMgr, pEncoderAttr->sRegistry, NULL ) );
nRet += DictAdd( pCIDSystemInfo, "Ordering", StringNew( pParent->oMMgr, pEncoderAttr->sOrdering, NULL ) );
nRet += DictAddNumber( pCIDSystemInfo, "Supplement", pEncoderAttr->nSuppliment );
if ( OK != nRet )
return NULL;
return pFont;
}
static TextWidth CIDTextWidth (FontDict pFont, const BYTE *pText, unsigned int nLen, unsigned int *pCIDs, unsigned int nLenCID)
{
TextWidth oTextWidth = {0, 0, 0, 0};
return oTextWidth;
FontAttr pAttr = (FontAttr)pFont->pAttr;
ParseTextRec oParseState;
EncoderRecPtr pEncoder = pAttr->pEncoder;
unsigned int nIndex = 0;
int nDW2 = 0;
BYTE nChar = 0;
if ( FontDefCID == pAttr->pFontDef->eType )
{
CIDFontDefAttr pCIDFontDefAttr = (CIDFontDefAttr)pAttr->pFontDef->pAttr;
nDW2 = pCIDFontDefAttr->anDW2[1];
}
else
{
nDW2 = pAttr->pFontDef->oFontBox.fBottom - pAttr->pFontDef->oFontBox.fTop;
}
EncoderSetParseText( pEncoder, &oParseState, pText, nLen);
while ( nIndex < nLen )
{
ByteType eBType = CMapEncoderByteType( pEncoder, &oParseState );
unsigned short nCid = 0;
unsigned short nUnicode = 0;
unsigned int nWidth = 0;
nChar = *pText++;
unsigned short nCode = nChar;
if ( ByteTypeLead == eBType )
{
nCode <<= 8;
nCode += *pText;
}
if ( ByteTypeTrial != eBType )
{
if ( WModeHorizontal == pAttr->eWritingMode )
{
if ( FontDefCID == pAttr->pFontDef->eType )
{
// cid-based font
nCid = CMapEncoderToCID( pEncoder, nCode );
nWidth = CIDFontDefGetCIDWidth( pAttr->pFontDef, nCid );
}
else
{
// unicode-based font
nUnicode = CMapEncoderToUnicode( pEncoder, nCode );
nWidth = TTFontDefGetCharWidth( pAttr->pFontDef, nUnicode );
}
}
else
{
nWidth = -nDW2;
}
oTextWidth.nNumchars++;
}
if ( IS_WHITE_SPACE(nCode) )
{
oTextWidth.nNumwords++;
oTextWidth.nNumspace++;
}
oTextWidth.nWidth += nWidth;
nIndex++;
}
if ( IS_WHITE_SPACE(nChar) )
; // ничего не делаем
else
oTextWidth.nNumwords++;
return oTextWidth;
}
static unsigned int CIDMeasureText (FontDict pFont, const BYTE *pText, unsigned int nLen, unsigned int *pCIDs, unsigned int nLenCID, float fWidth, float fFontSize, float fCharSpace, float fWordSpace, bool bWordWrap, float *pfRealWidth)
{
float fTempWidth = 0;
unsigned int nTempLen = 0;
FontAttr pAttr = (FontAttr)pFont->pAttr;
ByteType eLastBType = ByteTypeTrial;
EncoderRecPtr pEncoder = pAttr->pEncoder;
ParseTextRec oParseState;
int nDW2 = 0;
return 0;
if ( FontDefCID == pAttr->pFontDef->eType )
{
CIDFontDefAttr pCIDFontDefAttr = (CIDFontDefAttr)pAttr->pFontDef->pAttr;
nDW2 = pCIDFontDefAttr->anDW2[1];
}
else
{
nDW2 = pAttr->pFontDef->oFontBox.fBottom - pAttr->pFontDef->oFontBox.fTop;
}
EncoderSetParseText( pEncoder, &oParseState, pText, nLen);
for ( unsigned int nIndex = 0; nIndex < nLen; nIndex++)
{
BYTE nByte = *pText++;
BYTE nByte2 = *pText; // следующий байт
ByteType eBType = EncoderByteType( pEncoder, &oParseState );
unsigned short nUnicode = 0;
unsigned short nCode = nByte;
unsigned short nTempWidth = 0;
if ( ByteTypeLead == eBType )
{
nCode <<= 8;
nCode += nByte2;
}
if ( !bWordWrap )
{
if ( IS_WHITE_SPACE(nByte) )
{
nTempLen = nIndex + 1;
if ( pfRealWidth )
*pfRealWidth = fTempWidth;
}
else if ( ByteTypeSingle == eBType || ByteTypeLead == eBType )
{
nTempLen = nIndex;
if ( pfRealWidth )
*pfRealWidth = fTempWidth;
}
}
else
{
if ( IS_WHITE_SPACE(nByte) )
{
nTempLen = nIndex + 1;
if ( pfRealWidth )
*pfRealWidth = fTempWidth;
}
else if ( ByteTypeTrial == eLastBType || ( ByteTypeLead == eBType && ByteTypeSingle == eLastBType ) )
{
if ( !EncoderCheckJWWLineHead( pEncoder, nCode ) )
{
nTempLen = nIndex;
if ( pfRealWidth )
*pfRealWidth = fTempWidth;
}
}
}
if ( IS_WHITE_SPACE(nByte) )
{
fTempWidth += fWordSpace;
}
if ( ByteTypeTrial != eBType )
{
if ( WModeHorizontal == pAttr->eWritingMode )
{
if ( FontDefCID == pAttr->pFontDef->eType )
{
// cid-based font
unsigned short nCid = CMapEncoderToCID( pEncoder, nCode );
nTempWidth = CIDFontDefGetCIDWidth( pAttr->pFontDef, nCid );
}
else
{
// unicode-based font
nUnicode = CMapEncoderToUnicode( pEncoder, nCode );
nTempWidth = TTFontDefGetCharWidth( pAttr->pFontDef, nUnicode );
}
}
else
{
nTempWidth = -nDW2;
}
if ( nIndex > 0 )
fTempWidth += fCharSpace;
}
fTempWidth += (double)nTempWidth * fFontSize / 1000;
if ( fTempWidth > fWidth || 0x0A == nByte )
return nTempLen;
if ( IS_WHITE_SPACE(nByte) )
eLastBType = ByteTypeTrial;
else
eLastBType = eBType;
}
if ( pfRealWidth )
*pfRealWidth = fTempWidth;
return nLen;
}
static TextWidth CIDTextWidth2 (FontDict pFont, const BYTE *pText, unsigned int nLen, unsigned int *pCIDs, unsigned int nLenCID)
{
TextWidth oTextWidth = {0, 0, 0, 0};
FontAttr pAttr = (FontAttr)pFont->pAttr;
if ( 0 == nLenCID || NULL == pCIDs )
return oTextWidth;
ParseTextRec oParseState;
EncoderRecPtr pEncoder = pAttr->pEncoder;
CIDFontDefAttr pCIDFontDefAttr = (CIDFontDefAttr)pAttr->pFontDef->pAttr;
int nDW2 = pCIDFontDefAttr->anDW2[1];
int nIndex = 0;
while ( nIndex < nLenCID )
{
int nWidth = 0;
if ( WModeHorizontal == pAttr->eWritingMode )
{
nWidth = CIDFontDefGetCIDWidth( pAttr->pFontDef, pCIDs[nIndex] );
}
else
{
nWidth = -nDW2;
}
oTextWidth.nNumchars++;
if ( IS_WHITE_SPACE(pCIDs[nIndex]) )
{
oTextWidth.nNumwords++;
oTextWidth.nNumspace++;
}
oTextWidth.nWidth += nWidth;
nIndex++;
}
return oTextWidth;
}
static unsigned int CIDMeasureText2 (FontDict pFont, const BYTE *pText, unsigned int nLen, unsigned int *pCIDs, unsigned int nLenCID, float fWidth, float fFontSize, float fCharSpace, float fWordSpace, bool bWordWrap, float *pfRealWidth)
{
// TO DO : Релизовать данную функцию
return 0;
//float fTempWidth = 0;
//unsigned int nTempLen = 0;
//FontAttr pAttr = (FontAttr)pFont->pAttr;
//ByteType eLastBType = ByteTypeTrial;
//EncoderRecPtr pEncoder = pAttr->pEncoder;
//ParseTextRec oParseState;
//int nDW2 = 0;
//if ( FontDefCID == pAttr->pFontDef->eType )
//{
// CIDFontDefAttr pCIDFontDefAttr = (CIDFontDefAttr)pAttr->pFontDef->pAttr;
// nDW2 = pCIDFontDefAttr->anDW2[1];
//}
//else
//{
// nDW2 = pAttr->pFontDef->oFontBox.fBottom - pAttr->pFontDef->oFontBox.fTop;
//}
//EncoderSetParseText( pEncoder, &oParseState, pText, nLen);
//for ( unsigned int nIndex = 0; nIndex < nLen; nIndex++)
//{
// BYTE nByte = *pText++;
// BYTE nByte2 = *pText; // следующий байт
// ByteType eBType = EncoderByteType( pEncoder, &oParseState );
// unsigned short nUnicode = 0;
// unsigned short nCode = nByte;
// unsigned short nTempWidth = 0;
// if ( ByteTypeLead == eBType )
// {
// nCode <<= 8;
// nCode += nByte2;
// }
// if ( !bWordWrap )
// {
// if ( IS_WHITE_SPACE(nByte) )
// {
// nTempLen = nIndex + 1;
// if ( pfRealWidth )
// *pfRealWidth = fTempWidth;
// }
// else if ( ByteTypeSingle == eBType || ByteTypeLead == eBType )
// {
// nTempLen = nIndex;
// if ( pfRealWidth )
// *pfRealWidth = fTempWidth;
// }
// }
// else
// {
// if ( IS_WHITE_SPACE(nByte) )
// {
// nTempLen = nIndex + 1;
// if ( pfRealWidth )
// *pfRealWidth = fTempWidth;
// }
// else if ( ByteTypeTrial == eLastBType || ( ByteTypeLead == eBType && ByteTypeSingle == eLastBType ) )
// {
// if ( !EncoderCheckJWWLineHead( pEncoder, nCode ) )
// {
// nTempLen = nIndex;
// if ( pfRealWidth )
// *pfRealWidth = fTempWidth;
// }
// }
// }
// if ( IS_WHITE_SPACE(nByte) )
// {
// fTempWidth += fWordSpace;
// }
// if ( ByteTypeTrial != eBType )
// {
// if ( WModeHorizontal == pAttr->eWritingMode )
// {
// if ( FontDefCID == pAttr->pFontDef->eType )
// {
// // cid-based font
// unsigned short nCid = CMapEncoderToCID( pEncoder, nCode );
// nTempWidth = CIDFontDefGetCIDWidth( pAttr->pFontDef, nCid );
// }
// else
// {
// // unicode-based font
// nUnicode = CMapEncoderToUnicode( pEncoder, nCode );
// nTempWidth = TTFontDefGetCharWidth( pAttr->pFontDef, nUnicode );
// }
// }
// else
// {
// nTempWidth = -nDW2;
// }
// if ( nIndex > 0 )
// fTempWidth += fCharSpace;
// }
// fTempWidth += (double)nTempWidth * fFontSize / 1000;
// if ( fTempWidth > fWidth || 0x0A == nByte )
// return nTempLen;
// if ( IS_WHITE_SPACE(nByte) )
// eLastBType = ByteTypeTrial;
// else
// eLastBType = eBType;
//}
//if ( pfRealWidth )
// *pfRealWidth = fTempWidth;
//return nLen;
}
static char* UINT16ToHex (char *sStr, unsigned short nValue, char *pEndPointer)
{
BYTE anTemp[2];
char nChar = 0;
if (pEndPointer - sStr < 7)
return sStr;
UtilsMemCpy( anTemp, (BYTE *)&nValue, 2);
unsigned short nTempValue = (unsigned short)((unsigned short)anTemp[0] << 8 | (unsigned short)anTemp[1]);
UtilsMemCpy( anTemp, (BYTE *)&nTempValue, 2);
*sStr++ = '<';
if ( 0 != anTemp[0] )
{
nChar = anTemp[0] >> 4;
if ( nChar <= 9 )
nChar += 0x30;
else
nChar += 0x41 - 10;
*sStr++ = nChar;
nChar = anTemp[0] & 0x0f;
if ( nChar <= 9 )
nChar += 0x30;
else
nChar += 0x41 - 10;
*sStr++ = nChar;
}
nChar = anTemp[1] >> 4;
if ( nChar <= 9 )
nChar += 0x30;
else
nChar += 0x41 - 10;
*sStr++ = nChar;
nChar = anTemp[1] & 0x0f;
if ( nChar <= 9 )
nChar += 0x30;
else
nChar += 0x41 - 10;
*sStr++ = nChar;
*sStr++ = '>';
*sStr = 0;
return sStr;
}
static Dict CreateCMap (EncoderRecPtr pEncoder, Xref pXref)
{
unsigned long nRet = OK;
Dict pCMap = DictStreamNew( pEncoder->oMMgr, pXref );
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
char sBuffer[TEMP_BUFFER_SIZE];
char *pBufPointer;
char *pEndBufPointer = sBuffer + TEMP_BUFFER_SIZE - 1;
if ( !pCMap )
return NULL;
nRet += DictAddName( pCMap, "Type", "CMap");
nRet += DictAddName( pCMap, "CMapName", pEncoder->sName );
Dict pSysInfo = DictNew( pEncoder->oMMgr );
if ( !pSysInfo )
return NULL;
if ( OK != DictAdd( pCMap, "CIDSystemInfo", pSysInfo ) )
return NULL;
nRet += DictAdd( pSysInfo, "Registry", StringNew( pEncoder->oMMgr, pAttr->sRegistry, NULL ) );
nRet += DictAdd( pSysInfo, "Ordering", StringNew( pEncoder->oMMgr, pAttr->sOrdering, NULL ) );
nRet += DictAddNumber( pSysInfo, "Supplement", pAttr->nSuppliment );
nRet += DictAddNumber( pCMap, "WMode", (unsigned int)pAttr->eWritingMode );
// создаем CMap данные из закодированных данных
nRet += StreamWriteStr( pCMap->pStream, "%!PS-Adobe-3.0 Resource-CMap\r\n" );
nRet += StreamWriteStr( pCMap->pStream, "%%DocumentNeededResources: ProcSet (CIDInit)\r\n" );
nRet += StreamWriteStr( pCMap->pStream, "%%IncludeResource: ProcSet (CIDInit)\r\n" );
pBufPointer = (char*)UtilsStrCpy( sBuffer, "%%BeginResource: CMap (", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pEncoder->sName, pEndBufPointer);
UtilsStrCpy( pBufPointer, ")\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
pBufPointer = (char*)UtilsStrCpy( sBuffer, "%%Title: (", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pEncoder->sName, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pAttr->sRegistry, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pAttr->sOrdering, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UtilsIToA( pBufPointer, pAttr->nSuppliment, pEndBufPointer);
UtilsStrCpy( pBufPointer, ")\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
nRet += StreamWriteStr( pCMap->pStream, "%%Version: 1.0\r\n");
nRet += StreamWriteStr( pCMap->pStream, "%%EndComments\r\n");
nRet += StreamWriteStr( pCMap->pStream, "/CIDInit /ProcSet findresource begin\r\n\r\n");
// Спецификации файлов Adobe CMap и CIDFont рекомендуют выделить мето для
// 5 дополнительных элементов в данной директории.
nRet += StreamWriteStr( pCMap->pStream, "12 dict begin\r\n\r\n");
nRet += StreamWriteStr( pCMap->pStream, "begincmap\r\n\r\n");
nRet += StreamWriteStr( pCMap->pStream, "/CIDSystemInfo 3 dict dup begin\r\n");
pBufPointer = (char*)UtilsStrCpy( sBuffer, " /Registry (", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pAttr->sRegistry, pEndBufPointer);
UtilsStrCpy( pBufPointer, ") def\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
pBufPointer = (char*)UtilsStrCpy( sBuffer, " /Ordering (", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pAttr->sOrdering, pEndBufPointer);
UtilsStrCpy( pBufPointer, ") def\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
pBufPointer = (char*)UtilsStrCpy( sBuffer, " /Supplement ", pEndBufPointer);
pBufPointer = UtilsIToA( pBufPointer, pAttr->nSuppliment, pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, " def\r\n", pEndBufPointer);
UtilsStrCpy( pBufPointer, "end def\r\n\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
pBufPointer = (char*)UtilsStrCpy( sBuffer, "/CMapName /", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, pEncoder->sName, pEndBufPointer);
UtilsStrCpy( pBufPointer, " def\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
nRet += StreamWriteStr( pCMap->pStream, "/CMapVersion 1.0 def\r\n");
nRet += StreamWriteStr( pCMap->pStream, "/CMapType 1 def\r\n\r\n");
if ( pAttr->nUidOffset >= 0 )
{
pBufPointer = (char*)UtilsStrCpy( sBuffer, "/UIDOffset ", pEndBufPointer);
pBufPointer = UtilsIToA( pBufPointer, pAttr->nUidOffset, pEndBufPointer);
UtilsStrCpy( pBufPointer, " def\r\n\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
}
pBufPointer = (char*)UtilsStrCpy( sBuffer, "/XUID [", pEndBufPointer);
pBufPointer = UtilsIToA( pBufPointer, pAttr->anXUid[0], pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UtilsIToA( pBufPointer, pAttr->anXUid[1], pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UtilsIToA( pBufPointer, pAttr->anXUid[2], pEndBufPointer);
UtilsStrCpy( pBufPointer, "] def\r\n\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
pBufPointer = (char*)UtilsStrCpy( sBuffer, "/WMode ", pEndBufPointer);
pBufPointer = UtilsIToA( pBufPointer, (unsigned int)pAttr->eWritingMode, pEndBufPointer);
UtilsStrCpy( pBufPointer, " def\r\n\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
// add code-space-range
pBufPointer = UtilsIToA( sBuffer, pAttr->pCodeSpaceRange->nCount, pEndBufPointer);
UtilsStrCpy( pBufPointer, " begincodespacerange\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
for ( unsigned int nIndex = 0; nIndex < pAttr->pCodeSpaceRange->nCount; nIndex++)
{
CIDRangeRec *pRange = (CIDRangeRec*)ListItemAt( pAttr->pCodeSpaceRange, nIndex);
pBufPointer = UINT16ToHex( sBuffer, pRange->nFrom, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UINT16ToHex( pBufPointer, pRange->nTo, pEndBufPointer);
UtilsStrCpy( pBufPointer, "\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
if ( OK != nRet )
return NULL;
}
UtilsStrCpy( sBuffer, "endcodespacerange\r\n\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
if ( OK != nRet )
return NULL;
// add not-def-range
pBufPointer = UtilsIToA( sBuffer, pAttr->pNotDefRange->nCount, pEndBufPointer);
UtilsStrCpy( pBufPointer, " beginnotdefrange\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
for ( unsigned int nIndex = 0; nIndex < pAttr->pNotDefRange->nCount; nIndex++)
{
CIDRangeRec *pRange = (CIDRangeRec*)ListItemAt( pAttr->pNotDefRange, nIndex );
pBufPointer = UINT16ToHex( sBuffer, pRange->nFrom, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UINT16ToHex( pBufPointer, pRange->nTo, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UtilsIToA( pBufPointer, pRange->nCID, pEndBufPointer);
UtilsStrCpy( pBufPointer, "\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
if ( OK != nRet )
return NULL;
}
UtilsStrCpy( sBuffer, "endnotdefrange\r\n\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
if ( OK != nRet )
return NULL;
// add cid-range
unsigned int nPhase = pAttr->pCMAPRange->nCount / 100;
unsigned int nOdd = pAttr->pCMAPRange->nCount % 100;
if ( nPhase > 0 )
pBufPointer = UtilsIToA( sBuffer, 100, pEndBufPointer);
else
pBufPointer = UtilsIToA( sBuffer, nOdd, pEndBufPointer);
UtilsStrCpy( pBufPointer, " begincidrange\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
for ( unsigned int nIndex = 0; nIndex < pAttr->pCMAPRange->nCount; nIndex++)
{
CIDRangeRec *pRange = (CIDRangeRec*)ListItemAt( pAttr->pCMAPRange, nIndex );
pBufPointer = UINT16ToHex( sBuffer, pRange->nFrom, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UINT16ToHex( pBufPointer, pRange->nTo, pEndBufPointer);
*pBufPointer++ = ' ';
pBufPointer = UtilsIToA( pBufPointer, pRange->nCID, pEndBufPointer);
UtilsStrCpy( pBufPointer, "\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
if ( 0 == (nIndex + 1) %100 )
{
nPhase--;
pBufPointer = (char*)UtilsStrCpy( sBuffer, "endcidrange\r\n\r\n", pEndBufPointer);
if ( nPhase > 0 )
pBufPointer = UtilsIToA( pBufPointer, 100, pEndBufPointer);
else
pBufPointer = UtilsIToA( pBufPointer, nOdd, pEndBufPointer);
UtilsStrCpy( pBufPointer, " begincidrange\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer );
}
if ( OK != nRet )
return NULL;
}
if ( nOdd > 0 )
pBufPointer = (char*)UtilsStrCpy( sBuffer, "endcidrange\r\n", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, "endcmap\r\n", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, "CMapName currentdict /CMap defineresource pop\r\n", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, "end\r\n", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, "end\r\n\r\n", pEndBufPointer);
pBufPointer = (char*)UtilsStrCpy( pBufPointer, "%%EndResource\r\n", pEndBufPointer);
UtilsStrCpy( pBufPointer, "%%EOF\r\n", pEndBufPointer);
nRet += StreamWriteStr( pCMap->pStream, sBuffer);
if ( OK != nRet )
return NULL;
return pCMap;
}
static unsigned long CIDBeforeWrite (Dict pObj)
{
//unsigned long nRet = OK;
//if ( ( nRet = CreateDescriptor( pObj ) ) != OK )
// return nRet;
//if ( ( nRet = CreateToUnicode( pObj ) ) != OK )
// return nRet;
return OK;
}
static unsigned long CIDOnWrite (Dict pObj, StreamRecPtr pStream)
{
return OK;
// FontAttr pAttr = (FontAttr)pObj->pAttr;
//if ( true == pAttr->oExternWidths.bUse )
//{
// unsigned long nRet = OK;
// char sBuffer[TEMP_BUFFER_SIZE];
// char *pEndPointer = sBuffer + TEMP_BUFFER_SIZE - 1;
// char *pBufPointer;
// pBufPointer = (char*)UtilsStrCpy( sBuffer, "/FirstChar ", pEndPointer);
// pBufPointer = UtilsIToA( pBufPointer, pAttr->oExternWidths.nFirstChar, pEndPointer);
// UtilsStrCpy( pBufPointer, "\012", pEndPointer);
// if ( OK != ( nRet = StreamWriteStr( pStream, sBuffer ) ) )
// return nRet;
// pBufPointer = (char*)UtilsStrCpy( sBuffer, "/LastChar ", pEndPointer);
// pBufPointer = UtilsIToA( pBufPointer, pAttr->oExternWidths.nLastChar, pEndPointer);
// UtilsStrCpy( pBufPointer, "\012", pEndPointer);
// if ( OK != ( nRet = StreamWriteStr( pStream, sBuffer ) ) )
// return nRet;
// char buf[128];
// char *pbuf = buf;
// char *eptr = buf + 127;
// if ( OK != ( nRet = StreamWriteEscapeName( pStream, "Widths" ) ) )
// return nRet;
// if ( OK != ( nRet = StreamWriteStr( pStream, " [\012" ) ) )
// return nRet;
// for ( unsigned int nIndex = 0; nIndex <= pAttr->oExternWidths.nLastChar - pAttr->oExternWidths.nFirstChar; nIndex++)
// {
// pbuf = UtilsIToA ( pbuf, pAttr->oExternWidths.anWidths[nIndex], eptr);
// *pbuf++ = ' ';
// if ( 0 == (nIndex + 1) % 16 )
// {
// UtilsStrCpy(pbuf, "\012", eptr );
// if ( OK != ( nRet = StreamWriteStr( pStream, buf ) ) )
// return nRet;
// pbuf = buf;
// }
// }
// UtilsStrCpy( pbuf, "]\012", eptr );
// if ( OK != ( nRet = StreamWriteStr( pStream, buf ) ) )
// return nRet;
// if ( pAttr->pEncoder )
// nRet += pAttr->pEncoder->pWriteFn( pAttr->pEncoder, pStream );
// return nRet;
//}
//if ( (NULL == pAttr->pToUnicode) || (ToUnicodeBuilt != pAttr->pToUnicode->eType) )
//{
// BasicEncoderAttr pEncoderAttr = (BasicEncoderAttr)pAttr->pEncoder->pAttr;
// unsigned long nRet = OK;
// char sBuffer[TEMP_BUFFER_SIZE];
// char *pEndPointer = sBuffer + TEMP_BUFFER_SIZE - 1;
// char *pBufPointer;
// pBufPointer = (char*)UtilsStrCpy( sBuffer, "/FirstChar ", pEndPointer);
// pBufPointer = UtilsIToA( pBufPointer, pEncoderAttr->nFirstChar, pEndPointer);
// UtilsStrCpy( pBufPointer, "\012", pEndPointer);
// if ( OK != ( nRet = StreamWriteStr( pStream, sBuffer ) ) )
// return nRet;
// pBufPointer = (char*)UtilsStrCpy( sBuffer, "/LastChar ", pEndPointer);
// pBufPointer = UtilsIToA( pBufPointer, pEncoderAttr->nLastChar, pEndPointer);
// UtilsStrCpy( pBufPointer, "\012", pEndPointer);
// if ( OK != ( nRet = StreamWriteStr( pStream, sBuffer ) ) )
// return nRet;
// char buf[128];
// char *pbuf = buf;
// char *eptr = buf + 127;
// if ( OK != ( nRet = StreamWriteEscapeName( pStream, "Widths" ) ) )
// return nRet;
// if ( OK != ( nRet = StreamWriteStr( pStream, " [\012" ) ) )
// return nRet;
// for ( unsigned int nIndex = pEncoderAttr->nFirstChar; nIndex <= pEncoderAttr->nLastChar; nIndex++)
// {
// pbuf = UtilsIToA ( pbuf, pAttr->anWidths[nIndex], eptr);
// *pbuf++ = ' ';
// if ( 0 == (nIndex + 1) % 16 )
// {
// UtilsStrCpy(pbuf, "\012", eptr );
// if ( OK != ( nRet = StreamWriteStr( pStream, buf ) ) )
// return nRet;
// pbuf = buf;
// }
// }
// UtilsStrCpy( pbuf, "]\012", eptr );
// if ( OK != ( nRet = StreamWriteStr( pStream, buf ) ) )
// return nRet;
// return pAttr->pEncoder->pWriteFn( pAttr->pEncoder, pStream );
//}
//else
//{
// unsigned long nRet = OK;
// // Значит кодировка у нас задана в ToUnicode
// FontDef pDef = pAttr->pFontDef;
// ToUnicodeBuiltAttr pToUnicodeAttr = (ToUnicodeBuiltAttr)pAttr->pToUnicode->pAttr;
// char sBuffer[TEMP_BUFFER_SIZE];
// char *pEndPointer = sBuffer + TEMP_BUFFER_SIZE - 1;
// char *pBufPointer;
// pBufPointer = (char*)UtilsStrCpy( sBuffer, "/FirstChar ", pEndPointer);
// pBufPointer = UtilsIToA( pBufPointer, pToUnicodeAttr->nFirstChar, pEndPointer);
// UtilsStrCpy( pBufPointer, "\012", pEndPointer);
// if ( OK != ( nRet = StreamWriteStr( pStream, sBuffer ) ) )
// return nRet;
// pBufPointer = (char*)UtilsStrCpy( sBuffer, "/LastChar ", pEndPointer);
// pBufPointer = UtilsIToA( pBufPointer, pToUnicodeAttr->nLastChar, pEndPointer);
// UtilsStrCpy( pBufPointer, "\012", pEndPointer);
// if ( OK != ( nRet = StreamWriteStr( pStream, sBuffer ) ) )
// return nRet;
// char buf[128];
// char *pbuf = buf;
// char *eptr = buf + 127;
// if ( OK != ( nRet = StreamWriteEscapeName( pStream, "Widths" ) ) )
// return nRet;
// if ( OK != ( nRet = StreamWriteStr( pStream, " [\012" ) ) )
// return nRet;
// int nCodesCount;
// for ( nCodesCount = 0; nCodesCount < 256 && pToUnicodeAttr->anUnicodeMap[nCodesCount][0] != 0xffff; nCodesCount++ );
// for ( unsigned int nIndex = 0; nIndex < nCodesCount; nIndex++ )
// {
// unsigned short unUnicode = pAttr->pToUnicode->pToUnicodeFn( pAttr->pToUnicode, nIndex );
// short nCharWidth = 0;
// nCharWidth = TTFontDefGetCharWidth( pDef, unUnicode );
// pbuf = UtilsIToA ( pbuf, nCharWidth, eptr);
// *pbuf++ = ' ';
// if ( 0 == (nIndex + 1) % 16 )
// {
// UtilsStrCpy(pbuf, "\012", eptr );
// if ( OK != ( nRet = StreamWriteStr( pStream, buf ) ) )
// return nRet;
// pbuf = buf;
// }
// }
// UtilsStrCpy( pbuf, "]\012", eptr );
// if ( OK != ( nRet = StreamWriteStr( pStream, buf ) ) )
// return nRet;
// if ( NULL != pAttr->pEncoder )
// pAttr->pEncoder->pWriteFn( pAttr->pEncoder, pStream );
//}
//return OK;
}
static void CIDOnFree (Dict pObj)
{
FontAttr pAttr = (FontAttr)pObj->pAttr;
if ( pAttr )
{
if ( pAttr->anWidths )
FreeMem( pObj->oMMgr, pAttr->anWidths );
if ( pAttr->oExternWidths.anWidths )
FreeMem( pObj->oMMgr, pAttr->oExternWidths.anWidths );
FreeMem( pObj->oMMgr, pAttr );
}
}
//----- CIDTypeFont основные функции ----------------------------------------------------------------
FontDict Type0FontNew (MMgr oMMgr, FontDef pFontDef, EncoderRecPtr pEncoder, Xref pXref, PToUnicode pToUnicode/* = NULL*/)
{
unsigned long nRet = OK;
Dict pFont = DictNew( oMMgr );
if ( !pFont )
return NULL;
pFont->pHeader.nObjClass |= OSUBCLASS_FONT;
// проверяем типы фонта и кодировки
if ( EncoderTypeDoubleByteBuilt != pEncoder->eType )
{
SetError( pFont->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_ENCODER_TYPE, 0);
return NULL;
}
if ( FontDefCID != pFontDef->eType && FontDefTrueType != pFontDef->eType )
{
SetError( pFont->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_FONTDEF_TYPE, 0);
return NULL;
}
FontAttr pAttr = (FontAttr)GetMem( oMMgr, sizeof(FontAttrRec) );
if ( !pAttr )
{
DictFree( pFont );
return NULL;
}
pFont->pHeader.nObjClass |= OSUBCLASS_FONT;
pFont->pWriteFn = NULL;
pFont->pFreeFn = CIDOnFree;
pFont->pAttr = pAttr;
CMapEncoderAttr pEncoderAttr = (CMapEncoderAttr)pEncoder->pAttr;
UtilsMemSet( pAttr, 0, sizeof(FontAttrRec) );
pAttr->eWritingMode = pEncoderAttr->eWritingMode;
pAttr->pTextWidthFn = CIDTextWidth;
pAttr->pMeasureTextFn = CIDMeasureText;
pAttr->pFontDef = pFontDef;
pAttr->pEncoder = pEncoder;
pAttr->pToUnicode = pToUnicode;
pAttr->pXref = pXref;
pAttr->oExternWidths.bUse = false;
pAttr->oExternWidths.nLastChar = 0;
pAttr->oExternWidths.nFirstChar = 0;
pAttr->oExternWidths.anWidths = NULL;
if ( OK != XrefAdd( pXref, pFont ) )
return NULL;
nRet += DictAddName( pFont, "Type", "Font");
nRet += DictAddName( pFont, "BaseFont", pFontDef->sBaseFont );
nRet += DictAddName( pFont, "Subtype", "Type0");
if ( FontDefCID == pFontDef->eType )
{
nRet += DictAddName( pFont, "Encoding", pEncoder->sName );
}
else
{
pAttr->pCMapStream = CreateCMap( pEncoder, pXref );
if ( pAttr->pCMapStream )
{
nRet += DictAdd( pFont, "Encoding", pAttr->pCMapStream );
}
else
return NULL;
}
if ( OK != nRet )
return NULL;
Array oDescendantFonts = ArrayNew( oMMgr );
if ( !oDescendantFonts )
return NULL;
if ( OK != DictAdd( pFont, "DescendantFonts", oDescendantFonts ) )
return NULL;
if ( FontDefCID == pFontDef->eType )
{
pAttr->pDescendantFont = CIDFontType0New( pFont, pXref );
pAttr->eType = FontType0CID;
}
else
{
pAttr->pDescendantFont = CIDFontType2New( pFont, pXref );
pAttr->eType = FontType0TT;
}
if ( !pAttr->pDescendantFont )
return NULL;
else
if ( OK != ArrayAdd( oDescendantFonts, pAttr->pDescendantFont ) )
return NULL;
return pFont;
}
FontDict Type0FontNew2 (MMgr oMMgr, FontDef pFontDef, EncoderRecPtr pEncoder, Xref pXref, PToUnicode pToUnicode/* = NULL*/)
{
unsigned long nRet = OK;
Dict pFont = DictNew( oMMgr );
if ( !pFont )
return NULL;
pFont->pHeader.nObjClass |= OSUBCLASS_FONT;
// проверяем типы фонта и кодировки
if ( pEncoder && EncoderTypeDoubleByteStream != pEncoder->eType )
{
SetError( pFont->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_ENCODER_TYPE, 0);
return NULL;
}
if ( FontDefCID != pFontDef->eType )
{
SetError( pFont->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_FONTDEF_TYPE, 0);
return NULL;
}
FontAttr pAttr = (FontAttr)GetMem( oMMgr, sizeof(FontAttrRec) );
if ( !pAttr )
{
DictFree( pFont );
return NULL;
}
pFont->pHeader.nObjClass |= OSUBCLASS_FONT;
pFont->pBeforeWriteFn = CIDBeforeWrite;
pFont->pWriteFn = CIDOnWrite;
pFont->pFreeFn = CIDOnFree;
pFont->pAttr = pAttr;
UtilsMemSet( pAttr, 0, sizeof(FontAttrRec) );
// pAttr->eWritingMode = pEncoderAttr->eWritingMode;
pAttr->pTextWidthFn = CIDTextWidth2;
pAttr->pMeasureTextFn = CIDMeasureText2;
pAttr->pFontDef = pFontDef;
pAttr->pEncoder = pEncoder;
pAttr->pToUnicode = pToUnicode;
pAttr->pXref = pXref;
pAttr->oExternWidths.bUse = false;
pAttr->oExternWidths.nLastChar = 0;
pAttr->oExternWidths.nFirstChar = 0;
pAttr->oExternWidths.anWidths = NULL;
if ( OK != XrefAdd( pXref, pFont ) )
return NULL;
nRet += DictAddName( pFont, "Type", "Font");
nRet += DictAddName( pFont, "BaseFont", pFontDef->sBaseFont );
nRet += DictAddName( pFont, "Subtype", "Type0");
if ( NULL != pEncoder )
{
CMapEncoderStreamAttr pEncoderAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
if ( 0 == pEncoderAttr->nType )
{
nRet += DictAddName( pFont, "Encoding", pEncoder->sName );
}
else // if ( 1 == pEncoderAttr->nType )
{
Dict pEncoderData = DictStreamNew( oMMgr, pXref );
if ( !pEncoderData )
return NULL;
nRet += DictAdd( pFont, "Encoding", pEncoderData );
if ( OK != StreamWriteToStream( pEncoderAttr->pStream, pEncoderData->pStream, STREAM_FILTER_NONE, NULL ) )
return NULL;
#ifdef FILTER_FLATE_DECODE_ENABLED
pEncoderData->nFilter |= STREAM_FILTER_FLATE_DECODE;
#endif
nRet += DictAddName( pEncoderData, "Type", "CMap" );
if ( strlen( pEncoderAttr->sCMapName ) > 0 )
nRet += DictAddName( pEncoderData, "CMapName", pEncoderAttr->sCMapName );
if ( strlen( pEncoderAttr->sRegistry ) > 0 && strlen( pEncoderAttr->sOrdering ) > 0 )
{
Dict pInfo = DictNew( oMMgr );
nRet += DictAdd( pInfo, "Registry", StringNew( oMMgr, pEncoderAttr->sRegistry, NULL ) );
nRet += DictAdd( pInfo, "Ordering", StringNew( oMMgr, pEncoderAttr->sOrdering, NULL ) );
nRet += DictAddNumber( pInfo, "Supplement", pEncoderAttr->nSupplement );
nRet += DictAdd( pEncoderData, "CIDSystemInfo", pInfo );
}
nRet += DictAddNumber( pEncoderData, "WMode", (int)pEncoderAttr->eWritingMode );
if ( strlen( pEncoderAttr->uUseCMap.sName ) > 0 )
{
nRet += DictAddName( pEncoderData, "UseCMap", pEncoderAttr->uUseCMap.sName );
}
else if ( StreamValidate( pEncoderAttr->uUseCMap.pStream ) )
{
Dict pUseCMap = DictStreamNew( oMMgr, pXref );
if ( !pUseCMap )
return NULL;
if ( OK != StreamWriteToStream( pEncoderAttr->uUseCMap.pStream, pUseCMap->pStream, STREAM_FILTER_NONE, NULL ) )
return NULL;
#ifdef FILTER_FLATE_DECODE_ENABLED
pUseCMap->nFilter |= STREAM_FILTER_FLATE_DECODE;
#endif
nRet += DictAdd( pEncoderData, "UseCMap", pUseCMap );
}
}
}
Array oDescendantFonts = ArrayNew( oMMgr );
if ( !oDescendantFonts )
return NULL;
if ( OK != DictAdd( pFont, "DescendantFonts", oDescendantFonts ) )
return NULL;
pAttr->pDescendantFont = CIDFontTypeNew( pFont, pXref );
if ( !pAttr->pDescendantFont )
return NULL;
else
if ( OK != ArrayAdd( oDescendantFonts, pAttr->pDescendantFont ) )
return NULL;
if ( NULL != pToUnicode )
{
Dict pToUnicodeDict = DictStreamNew( oMMgr, pXref );
pToUnicode->pWriteFn( pToUnicode, pToUnicodeDict->pStream );
#ifdef FILTER_FLATE_DECODE_ENABLED
pToUnicodeDict->nFilter |= STREAM_FILTER_FLATE_DECODE;
#endif
nRet += DictAdd( pFont, "ToUnicode", pToUnicodeDict );
}
if ( OK != nRet )
return NULL;
return pFont;
}