Files
core/ASCOfficePDFWriter/Encoder.h

1546 lines
44 KiB
C

#ifndef _ENCODER_H
#define _ENCODER_H
#include "Consts.h"
#include "Streams.h"
#include "Utils.h"
#include "EncoderConstants.h"
//-- Encoder -------------------------------------------------------------------------------------
#define ENCODER_SIG_BYTES 0x454E4344L
//-- Ïðåäîïðåäåëåííûå êîäèðîâêè ôîíòîâ -----------------------------------------------------------
#define ENCODING_FONT_SPECIFIC "FontSpecific"
#define ENCODING_STANDARD "StandardEncoding"
#define ENCODING_MAC_EXPERT "MacExpertEncoding"
#define ENCODING_MAC_ROMAN "MacRomanEncoding"
#define ENCODING_WIN_ANSI "WinAnsiEncoding"
#define ENCODING_ISO8859_2 "ISO8859-2"
#define ENCODING_ISO8859_3 "ISO8859-3"
#define ENCODING_ISO8859_4 "ISO8859-4"
#define ENCODING_ISO8859_5 "ISO8859-5"
#define ENCODING_ISO8859_6 "ISO8859-6"
#define ENCODING_ISO8859_7 "ISO8859-7"
#define ENCODING_ISO8859_8 "ISO8859-8"
#define ENCODING_ISO8859_9 "ISO8859-9"
#define ENCODING_ISO8859_10 "ISO8859-10"
#define ENCODING_ISO8859_11 "ISO8859-11"
#define ENCODING_ISO8859_13 "ISO8859-13"
#define ENCODING_ISO8859_14 "ISO8859-14"
#define ENCODING_ISO8859_15 "ISO8859-15"
#define ENCODING_ISO8859_16 "ISO8859-16"
#define ENCODING_CP1250 "CP1250"
#define ENCODING_CP1251 "CP1251"
#define ENCODING_CP1252 "CP1252"
#define ENCODING_CP1253 "CP1253"
#define ENCODING_CP1254 "CP1254"
#define ENCODING_CP1255 "CP1255"
#define ENCODING_CP1256 "CP1256"
#define ENCODING_CP1257 "CP1257"
#define ENCODING_CP1258 "CP1258"
#define ENCODING_KOI8_R "KOI8-R"
//-- Îïðåäåëåíèÿ äëÿ êîäèðîâêè ôîíòîâ ------------------------------------------------------------
typedef enum EEncodingType
{
StandrardEncoding = 0,
MacRomanEncoding,
WinAnsiEncoding,
FontSpecific,
EncodingEOF
} EncodingType;
typedef struct TParseTextRec
{
const BYTE *pText;
unsigned int nIndex;
unsigned int nLen;
ByteType eByteType;
} ParseTextRec;
typedef struct TEncoderRec *Encoder;
typedef ByteType (*EncoderByteTypeFunc) (Encoder pEncoder, ParseTextRec *pState);
typedef unsigned short (*EncoderToUnicodeFunc)(Encoder pEncoder, unsigned short nCode);
typedef unsigned long (*EncoderWriteFunc) (Encoder pEncoder, Stream pOut);
typedef unsigned long (*EncoderInitFunc) (Encoder pEncoder);
typedef void (*EncoderFreeFunc) (Encoder pEncoder);
typedef struct TEncoderRec
{
unsigned int nSigBytes;
char sName[LIMIT_MAX_NAME_LEN + 1];
MMgr oMMgr;
Error oError;
EncoderType eType;
EncoderByteTypeFunc pByteTypeFn;
EncoderToUnicodeFunc pToUnicodeFn;
EncoderWriteFunc pWriteFn;
EncoderFreeFunc pFreeFn;
EncoderInitFunc pInitFn;
//char aLangCode[3];
//char aCountryCode[3];
void *pAttr;
} EncoderRec;
typedef enum EBaseEncodings
{
BaseEncodingStandard,
BaseEncodingWinAnsi,
BaseEncodingMacExpert,
BaseEncodingMacRoman,
BaseEncodingFontSpecific,
BaseEncodingEOF
} BaseEncodings;
typedef struct TBuiltinEncodingData
{
const char *sEncodingName;
BaseEncodings eBaseEncoding;
const unsigned short *pnOverrideMap;
} BuiltinEncodingData;
static const BuiltinEncodingData c_aoBuiltInEncodings[] =
{
{
ENCODING_FONT_SPECIFIC,
BaseEncodingFontSpecific,
NULL
},
{
ENCODING_STANDARD,
BaseEncodingStandard,
NULL
},
{
ENCODING_MAC_EXPERT,
BaseEncodingMacExpert,
NULL
},
{
ENCODING_MAC_ROMAN,
BaseEncodingMacRoman,
NULL
},
{
ENCODING_WIN_ANSI,
BaseEncodingWinAnsi,
NULL
},
{
ENCODING_ISO8859_2,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_2
},
{
ENCODING_ISO8859_3,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_3
},
{
ENCODING_ISO8859_4,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_4
},
{
ENCODING_ISO8859_5,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_5
},
{
ENCODING_ISO8859_6,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_6
},
{
ENCODING_ISO8859_7,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_7
},
{
ENCODING_ISO8859_8,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_8
},
{
ENCODING_ISO8859_9,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_9
},
{
ENCODING_ISO8859_10,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_10
},
{
ENCODING_ISO8859_11,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_11
},
{
ENCODING_ISO8859_13,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_13
},
{
ENCODING_ISO8859_14,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_14
},
{
ENCODING_ISO8859_15,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_15
},
{
ENCODING_ISO8859_16,
BaseEncodingWinAnsi,
c_anUnicodeMapISO8859_16
},
{
ENCODING_CP1250,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1250
},
{
ENCODING_CP1251,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1251
},
{
ENCODING_CP1252,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1252
},
{
ENCODING_CP1253,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1253
},
{
ENCODING_CP1254,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1254
},
{
ENCODING_CP1255,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1255
},
{
ENCODING_CP1256,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1256
},
{
ENCODING_CP1257,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1257
},
{
ENCODING_CP1258,
BaseEncodingWinAnsi,
c_anUnicodeMapCP1258
},
{
ENCODING_KOI8_R,
BaseEncodingWinAnsi,
c_anUnicodeMapKOI8_R
},
{
NULL,
BaseEncodingEOF,
NULL
}
};
unsigned long EncoderValidate (Encoder pEncoder)
{
if ( !pEncoder || ENCODER_SIG_BYTES != pEncoder->nSigBytes )
return FALSE;
else
return TRUE;
}
void EncoderSetParseText (Encoder pEncoder, ParseTextRec *pState, const BYTE *pText, unsigned int nLen)
{
pState->pText = pText;
pState->nIndex = 0;
pState->nLen = nLen;
pState->eByteType = ByteTypeSingle;
}
ByteType EncoderByteType (Encoder pEncoder, ParseTextRec *pState)
{
if ( pEncoder->pByteTypeFn )
return pEncoder->pByteTypeFn( pEncoder, pState );
else
return ByteTypeSingle;
}
unsigned short EncoderToUnicode (Encoder pEncoder, unsigned short nCode)
{
return pEncoder->pToUnicodeFn( pEncoder, nCode );
}
void EncoderFree (Encoder pEncoder)
{
if ( !pEncoder )
return;
if ( pEncoder->pFreeFn )
pEncoder->pFreeFn( pEncoder );
FreeMem( pEncoder->oMMgr, pEncoder );
}
unsigned short EncoderToCode (Encoder pEncoder, unsigned short unUnicode)
{
// Èùåì êîä äëÿ çàäàííîãî þíèêîäíîãî çíà÷åíèÿ, åñëè òàêîãî â äàííîé êîäèðîâêå íåò âîçâðàùàåì çíà÷åíèå 0xFFFF.
for ( int nCode = 0; nCode < 256; nCode++ )
{
unsigned short unCurUnicode = EncoderToUnicode( pEncoder, nCode );
if ( unCurUnicode == unUnicode )
return nCode;
}
return 0xFFFF;
}
//-- BasicEncoder --------------------------------------------------------------------------------
#define BASIC_ENCODER_MAX_CHAR_INDEX 512 // Âîîáùå, ïî ñìûñëó, òóò äîëæíî áûòü 256, íî íåêîòîðûå
// PDF ôàéëû ñîäåðæàò è áîëüøîå 256 ñèìâîëîâ, ïîòîìó ÷òî
// ñèìâîëû êîäèðóþòñÿ â âîñüìåðè÷íîé ñèñòåìå èç 3-õ çíàêîâ.
// Ïîýòîìó ìàêñèìàëüíîå ÷èñëî ýëåìåíòîâ = 8^3 = 512
typedef struct TBasicEncoderAttrRec *BasicEncoderAttr;
typedef struct TBasicEncoderAttrRec
{
char sBaseEncoding[LIMIT_MAX_NAME_LEN + 1];
BYTE nFirstChar;
BYTE nLastChar;
unsigned short anUnicodeMap[BASIC_ENCODER_MAX_CHAR_INDEX];
char asGlyphNameMap[BASIC_ENCODER_MAX_CHAR_INDEX][LIMIT_MAX_NAME_LEN + 1];
BOOL bHasDifferences;
BYTE anDifferences[BASIC_ENCODER_MAX_CHAR_INDEX];
} BasicEncoderAttrRec;
//-- BasicEncoder - Âñïîìîãàòåëüíûå ôóíêöèè ------------------------------------------------------
const BuiltinEncodingData* BasicEncoderFindBuiltinData(const char *sEncodingName )
{
unsigned int nIndex = 0;
while ( c_aoBuiltInEncodings[nIndex].sEncodingName )
{
if ( 0 == UtilsStrCmp( c_aoBuiltInEncodings[nIndex].sEncodingName, sEncodingName ) )
break;
nIndex++;
}
return &c_aoBuiltInEncodings[nIndex];
}
const char* UnicodeToGlyphName (unsigned short nUnicode)
{
const UnicodeGlyphPair* pMap = c_aoUnicodeGlyphNameMap;
while ( pMap->nUnicode <= nUnicode)
{
if ( pMap->nUnicode == nUnicode )
return pMap->sGlyphName;
pMap++;
}
return c_aoUnicodeGlyphNameMap[0].sGlyphName;
}
unsigned short GlyphNameToUnicode (const char *sGlyphName)
{
const UnicodeGlyphPair *pMap = c_aoUnicodeGlyphNameMap;
while ( 0xFFFF != pMap->nUnicode )
{
if ( 0 == UtilsStrCmp( sGlyphName, pMap->sGlyphName ) )
return pMap->nUnicode;
pMap++;
}
return 0x0000;
}
void BasicEncoderCopyMap (Encoder pEncoder, const unsigned short *pnMap)
{
unsigned short *pnDst = ((BasicEncoderAttr)pEncoder->pAttr)->anUnicodeMap + BASIC_ENCODER_FIRST_CHAR;
for ( unsigned int nIndex = 0; nIndex <= BASIC_ENCODER_LAST_CHAR - BASIC_ENCODER_FIRST_CHAR; nIndex++)
*pnDst++ = *pnMap++;
}
unsigned long BasicEncoderOverrideMap (Encoder pEncoder, const unsigned short *pnMap)
{
BasicEncoderAttr pData = (BasicEncoderAttr)pEncoder->pAttr;
unsigned short *pnDst = NULL;
BYTE *pFlags = NULL;
if ( pData->bHasDifferences )
return SetError( pEncoder->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_OPERATION, 0);
pnDst = pData->anUnicodeMap + BASIC_ENCODER_FIRST_CHAR;
pFlags = pData->anDifferences + BASIC_ENCODER_FIRST_CHAR;
for ( unsigned int nIndex = 0; nIndex <= BASIC_ENCODER_LAST_CHAR - BASIC_ENCODER_FIRST_CHAR; nIndex++)
{
if ( *pnMap != *pnDst )
{
*pnDst = *pnMap;
*pFlags = 1;
}
pnMap++;
pnDst++;
pFlags++;
}
pData->bHasDifferences = TRUE;
return OK;
}
//-- BasicEncoder - Îñíîâíûå ôóíêöèè -------------------------------------------------------------
void BasicEncoderFree (Encoder pEncoder)
{
FreeMem( pEncoder->oMMgr, pEncoder->pAttr );
pEncoder->pAttr = NULL;
}
unsigned long BasicEncoderWrite (Encoder pEncoder, Stream pOut)
{
unsigned long nRet = OK;
BasicEncoderAttr pAttr = (BasicEncoderAttr)pEncoder->pAttr;
// Åñëè çàïèñàí ENCODING_FONT_SPECIFIC, òîãäà ó îáúåêòà îáúåêò Encoding íå ïèøåòñÿ BaseEncoding
BOOL bFontSpecific = FALSE;
if ( 0 == UtilsStrCmp( pAttr->sBaseEncoding, ENCODING_FONT_SPECIFIC ) )
bFontSpecific = TRUE;
// Åñëè Encoder èìååò ðàçëè÷íûå äàííûå, òîãäà îáúåêò Åncoding ïèøåòñÿ êàê
// Dictionary-object, â ïðîòèâíîì ñëó÷àåì ìû åãî ïèøåì êàê name-object.
if ( TRUE == pAttr->bHasDifferences )
{
if ( !bFontSpecific )
nRet = StreamWriteStr( pOut, "/Encoding <<\012/Type /Encoding\012/BaseEncoding ");
else
nRet = StreamWriteStr( pOut, "/Encoding <<\012/Type /Encoding");
if ( OK != nRet )
return nRet;
}
else
{
if ( !bFontSpecific )
nRet = StreamWriteStr( pOut, "/Encoding ");
else
return nRet;
if ( OK != nRet )
return nRet;
}
if ( !bFontSpecific )
{
nRet = StreamWriteEscapeName( pOut, pAttr->sBaseEncoding );
if ( OK != nRet )
return nRet;
}
nRet = StreamWriteStr( pOut, "\012" );
if ( OK != nRet )
return nRet;
/* write differences data */
if ( TRUE == pAttr->bHasDifferences )
{
nRet = StreamWriteStr( pOut, "/Differences [" );
if ( OK != nRet )
return nRet;
for ( int nIndex = pAttr->nFirstChar; nIndex <= pAttr->nLastChar; nIndex++)
{
if ( 1 == pAttr->anDifferences[nIndex] )
{
char sTemp[TEXT_DEFAULT_LEN];
char* pTemp = sTemp;
const char* sCharName = ( '\0' == pAttr->asGlyphNameMap[nIndex][0] ? UnicodeToGlyphName( pAttr->anUnicodeMap[nIndex] ) : pAttr->asGlyphNameMap[nIndex] );
pTemp = UtilsIToA( pTemp, nIndex, sTemp + TEMP_BUFFER_SIZE - 1);
*pTemp++ = ' ';
*pTemp++ = '/';
pTemp = (char*)UtilsStrCpy( pTemp, sCharName, sTemp + TEMP_BUFFER_SIZE - 1);
*pTemp++ = ' ';
*pTemp = 0;
nRet = StreamWriteStr( pOut, sTemp );
if ( OK != nRet )
return nRet;
}
}
nRet = StreamWriteStr( pOut, "]\012>>\012" );
}
return nRet;
}
unsigned short BasicEncoderToUnicode(Encoder pEncoder, unsigned short nCode)
{
BasicEncoderAttr pAttr = (BasicEncoderAttr)pEncoder->pAttr;
if ( nCode > 255 )
return 0;
return pAttr->anUnicodeMap[ nCode ];
}
Encoder BasicEncoderNew (MMgr oMMgr, const char *sEncodingName)
{
if ( NULL == oMMgr )
return NULL;
const BuiltinEncodingData *pData = BasicEncoderFindBuiltinData( sEncodingName );
if ( !pData->sEncodingName )
{
SetError( oMMgr->oError, AVS_OFFICEPDFWRITER_ERROR_INVALID_ENCODING_NAME, 0);
return NULL;
}
Encoder pEncoder = (Encoder)GetMem( oMMgr, sizeof(EncoderRec) );
if ( !pEncoder )
return NULL;
UtilsMemSet( pEncoder, 0, sizeof(EncoderRec) );
char *pEndPointer = pEncoder->sName + LIMIT_MAX_NAME_LEN;
UtilsStrCpy( pEncoder->sName, pData->sEncodingName, pEndPointer);
pEncoder->oMMgr = oMMgr;
pEncoder->oError = oMMgr->oError;
pEncoder->eType = EncoderTypeSingleByte;
pEncoder->pToUnicodeFn = BasicEncoderToUnicode;
pEncoder->pWriteFn = BasicEncoderWrite;
pEncoder->pFreeFn = BasicEncoderFree;
BasicEncoderAttr pEncoderAttr = (BasicEncoderAttr)GetMem( oMMgr, sizeof(BasicEncoderAttrRec) );
if ( !pEncoderAttr )
{
FreeMem( pEncoder->oMMgr, pEncoder );
return NULL;
}
pEncoder->nSigBytes = ENCODER_SIG_BYTES;
pEncoder->pAttr = pEncoderAttr;
UtilsMemSet( pEncoderAttr, 0, sizeof(BasicEncoderAttrRec) );
pEncoderAttr->nFirstChar = BASIC_ENCODER_FIRST_CHAR;
pEncoderAttr->nLastChar = BASIC_ENCODER_LAST_CHAR;
pEncoderAttr->bHasDifferences = FALSE;
pEndPointer = pEncoderAttr->sBaseEncoding + LIMIT_MAX_NAME_LEN;
switch ( pData->eBaseEncoding )
{
case BaseEncodingStandard:
UtilsStrCpy( pEncoderAttr->sBaseEncoding, ENCODING_STANDARD, pEndPointer);
BasicEncoderCopyMap( pEncoder, c_anUnicodeMapStandard);
break;
case BaseEncodingWinAnsi:
UtilsStrCpy( pEncoderAttr->sBaseEncoding, ENCODING_WIN_ANSI, pEndPointer);
BasicEncoderCopyMap( pEncoder, c_anUnicodeMapWinAnsi);
break;
case BaseEncodingMacRoman:
UtilsStrCpy( pEncoderAttr->sBaseEncoding, ENCODING_MAC_ROMAN, pEndPointer);
BasicEncoderCopyMap( pEncoder, c_anUnicodeMapMacRoman);
break;
case BaseEncodingMacExpert:
UtilsStrCpy( pEncoderAttr->sBaseEncoding, ENCODING_MAC_EXPERT, pEndPointer);
BasicEncoderCopyMap( pEncoder, c_anUnicodeMapMacExpert );
break;
default:
UtilsStrCpy( pEncoderAttr->sBaseEncoding, ENCODING_FONT_SPECIFIC, pEndPointer);
BasicEncoderCopyMap( pEncoder, c_anUnicodeMapFontSpecific);
}
if ( pData->pnOverrideMap )
BasicEncoderOverrideMap( pEncoder, pData->pnOverrideMap);
return pEncoder;
}
//-- CMapEncoderStream ---------------------------------------------------------------------------
struct CMapVectorEntry
{
BOOL bIsVector;
//union
//{
int nCID;
CMapVectorEntry *pVector;
//};
};
typedef struct TCIDtoCodeMap
{
char sCode[4];
int nLen;
} CIDtoCodeMap;
typedef struct TCMapEncoderStreamAttrRec *CMapEncoderStreamAttr;
typedef struct TCMapEncoderStreamAttrRec
{
char sName[LIMIT_MAX_NAME_LEN + 1];
int nType; // 0 - çíà÷èò èìÿ ïðåäîïðåäåëåííîå èìÿ â PDF, 1 - èìÿ - ýòî èäåíòåôèêàòîð êîäèðîâêè, à ñàìà êîäèðîâêà çàäàíà â pStream
char sCMapName[LIMIT_MAX_NAME_LEN + 1];
char sRegistry[LIMIT_MAX_NAME_LEN + 1];
char sOrdering[LIMIT_MAX_NAME_LEN + 1];
int nSupplement;
WritingMode eWritingMode;
union
{
char sName[LIMIT_MAX_NAME_LEN + 1];
Stream pStream;
} uUseCMap;
CIDtoCodeMap anCIDtoCode[65536]; // CID - âûñòóïàåò â ðîëè èíäåêñà
CMapVectorEntry *pVector;
Stream pStream;
} CMapEncoderStreamAttrRec;
void CMapEncoderStreamFreeVector (Encoder pEncoder, CMapVectorEntry *pVector)
{
if ( NULL == pVector )
return;
for ( int nIndex = 0; nIndex < 256; nIndex++ )
{
if ( pVector[nIndex].bIsVector && NULL != pVector[nIndex].pVector )
{
CMapEncoderStreamFreeVector( pEncoder, pVector[nIndex].pVector );
FreeMem( pEncoder->oMMgr, pVector[nIndex].pVector );
}
}
}
unsigned long CMapEncoderStreamWrite (Encoder pEncoder, Stream pOut)
{
if ( EncoderTypeDoubleByteStream != pEncoder->eType )
return OK;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
if ( 1 == pAttr->nType && StreamValidate( pAttr->pStream ) )
{
return StreamWriteToStream( pAttr->pStream, pOut, 0, NULL );
}
return OK;
}
void CMapEncoderStreamFree (Encoder pEncoder)
{
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
StreamFree( pAttr->uUseCMap.pStream );
StreamFree( pAttr->pStream );
CMapEncoderStreamFreeVector( pEncoder, pAttr->pVector );
FreeMem( pEncoder->oMMgr, pAttr->pVector );
FreeMem( pEncoder->oMMgr, pEncoder->pAttr );
pEncoder->pAttr = NULL;
}
//-- CMapEncoderStream - Îñíîâíûå ôóíêöèè --------------------------------------------------------
Encoder CMapEncoderStreamNew (MMgr oMMgr, int nType, char *sName, Stream pStream)
{
if ( NULL == oMMgr )
return NULL;
Encoder pEncoder = (Encoder)GetMem( oMMgr, sizeof(EncoderRec) );
if ( !pEncoder )
return NULL;
UtilsMemSet( pEncoder, 0, sizeof(EncoderRec) );
UtilsStrCpy( pEncoder->sName, sName, pEncoder->sName + LIMIT_MAX_NAME_LEN );
pEncoder->oMMgr = oMMgr;
pEncoder->oError = oMMgr->oError;
pEncoder->eType = EncoderTypeDoubleByteStream;
pEncoder->pByteTypeFn = NULL;
pEncoder->pToUnicodeFn = NULL;
pEncoder->pWriteFn = CMapEncoderStreamWrite;
pEncoder->pFreeFn = CMapEncoderStreamFree;
pEncoder->pInitFn = NULL;
pEncoder->nSigBytes = ENCODER_SIG_BYTES;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)GetMem( oMMgr, sizeof(CMapEncoderStreamAttrRec) );
if ( !pAttr )
{
FreeMem( oMMgr, pEncoder );
return NULL;
}
UtilsStrCpy( pAttr->sName, sName, pAttr->sName + LIMIT_MAX_NAME_LEN );
pAttr->nType = nType;
pAttr->pStream = pStream;
pAttr->pVector = (CMapVectorEntry *)GetMem( oMMgr, 256 * sizeof(CMapVectorEntry) );
if ( !pAttr->pVector )
{
FreeMem( oMMgr, pEncoder );
FreeMem( oMMgr, pAttr );
return NULL;
}
for ( int nIndex = 0; nIndex < 256; nIndex++ )
{
pAttr->pVector[nIndex].bIsVector = FALSE;
pAttr->pVector[nIndex].pVector = NULL;
pAttr->pVector[nIndex].nCID = 0;
}
pEncoder->pAttr = pAttr;
for ( int nIndex = 0; nIndex < 65536; nIndex++ )
{
pAttr->anCIDtoCode[nIndex].sCode[0] = 0;
pAttr->anCIDtoCode[nIndex].sCode[1] = 0;
pAttr->anCIDtoCode[nIndex].sCode[2] = 0;
pAttr->anCIDtoCode[nIndex].sCode[3] = 0;
pAttr->anCIDtoCode[nIndex].nLen = 0;
}
return pEncoder;
}
unsigned long CMapEncoderStreamSetAttrs (Encoder pEncoder, char *sCMapName, char *sRegistry, char *sOrdering, int nSupplement, WritingMode eMode, char *sUseCMap, Stream pUseCMap )
{
if ( EncoderTypeDoubleByteStream != pEncoder->eType )
return OK;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
UtilsStrCpy( pAttr->sCMapName, sCMapName, pAttr->sCMapName + LIMIT_MAX_NAME_LEN );
UtilsStrCpy( pAttr->sRegistry, sRegistry, pAttr->sRegistry + LIMIT_MAX_NAME_LEN );
UtilsStrCpy( pAttr->sOrdering, sOrdering, pAttr->sOrdering + LIMIT_MAX_NAME_LEN );
pAttr->nSupplement = nSupplement;
pAttr->eWritingMode = eMode;
UtilsStrCpy( pAttr->uUseCMap.sName, sUseCMap, pAttr->uUseCMap.sName + LIMIT_MAX_NAME_LEN );
pAttr->uUseCMap.pStream = pUseCMap;
return OK;
}
unsigned long CMapEncoderStreamLoadVector2 (Encoder pEncoder, XmlUtils::CXmlNode oNode, CMapVectorEntry **ppVector)
{
unsigned long nRet = OK;
if ( NULL == ppVector || NULL == *ppVector )
return OK;
CMapVectorEntry *pVector = *ppVector;
XmlUtils::CXmlNodes oNodes;
oNode.GetNodes( _T("Vector"), oNodes );
for ( int nIndex = 0; nIndex < oNodes.GetCount(); nIndex++ )
{
XmlUtils::CXmlNode oVector;
if ( oNodes.GetAt( nIndex, oVector ) )
{
CString sValue;
sValue = oVector.GetAttribute( _T("index") );
int nVectorIndex = XmlUtils::GetInteger( sValue );
sValue = oVector.GetAttribute( _T("isvector") );
BOOL bIsVector = ( 1 == XmlUtils::GetInteger( sValue ) ? TRUE : FALSE ) ;
sValue = oVector.GetAttribute( _T("cid") );
int nCID = XmlUtils::GetInteger( sValue );
if ( bIsVector )
{
pVector[nVectorIndex].bIsVector = TRUE;
pVector[nVectorIndex].pVector = (CMapVectorEntry *)GetMem( pEncoder->oMMgr, 256 * sizeof(CMapVectorEntry) );
if ( !pVector[nVectorIndex].pVector )
return AVS_OFFICEPDFREADER_ERROR_NOT_ENOUGH_MEMORY;
for ( int nVIndex = 0; nVIndex < 256; nVIndex++ )
{
pVector[nVectorIndex].pVector[nVIndex].pVector = NULL;
pVector[nVectorIndex].pVector[nVIndex].nCID = 0;
pVector[nVectorIndex].pVector[nVIndex].bIsVector = FALSE;
}
if ( OK != ( nRet = CMapEncoderStreamLoadVector2( pEncoder, oVector, &(pVector[nVectorIndex].pVector) ) ) )
return nRet;
}
else
{
pVector[nVectorIndex].nCID = nCID;
}
}
}
return OK;
}
unsigned long CMapEncoderStreamLoadVector (Encoder pEncoder, CString sCMapPath)
{
unsigned long nRet = OK;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
XmlUtils::CXmlNode oMainNode;
oMainNode.FromXmlFile( sCMapPath );
if ( _T("PDF-CMap") == oMainNode.GetName() )
{
CString sValue = oMainNode.GetAttribute( _T("name") );
if ( _T("Identity") != sValue && _T("Identity-H") != sValue && _T("Identity-V") != sValue )
{
if ( OK != ( nRet = CMapEncoderStreamLoadVector2( pEncoder, oMainNode, &(pAttr->pVector) ) ) )
return nRet;
}
else
{
// Åñëè pVector = NULL, ýòî áóäåò ïðèçíàê òîãî, ÷òî CMap = Identity
CMapEncoderStreamFreeVector( pEncoder, pAttr->pVector );
FreeMem( pEncoder->oMMgr, pAttr->pVector );
pAttr->pVector = NULL;
}
}
return OK;
}
int CMapEncoderStreamGetCID (Encoder pEncoder, char *sChar, int nLen, int *pnUsed)
{
unsigned long nRet = OK;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
CMapVectorEntry *pVector = NULL;
if ( NULL == ( pVector = pAttr->pVector ) )
{
// Identity CMap
*pnUsed = 2;
if ( nLen < 2 )
{
return 0;
}
return ((sChar[0] & 0xff) << 8) + (sChar[1] & 0xff);
}
int nUsedCount = 0;
while (1)
{
if ( nUsedCount >= nLen )
{
*pnUsed = nUsedCount;
return 0;
}
int nIndex = sChar[nUsedCount++] & 0xff;
if ( !pVector[nIndex].bIsVector )
{
*pnUsed = nUsedCount;
return pVector[nIndex].nCID;
}
pVector = pVector[nIndex].pVector;
}
}
void CMapEncoderStreamGetCodeByCID (Encoder pEncoder, int nCID, char **ppBuffer, int *pnLen)
{
unsigned long nRet = OK;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
nCID = min( 65536, max( 0, nCID ) );
char *pBuffer = *ppBuffer;
pBuffer[0] = pAttr->anCIDtoCode[nCID].sCode[0];
pBuffer[1] = pAttr->anCIDtoCode[nCID].sCode[1];
pBuffer[2] = pAttr->anCIDtoCode[nCID].sCode[2];
pBuffer[3] = pAttr->anCIDtoCode[nCID].sCode[3];
*(pnLen) = pAttr->anCIDtoCode[nCID].nLen;
}
void CMapEncoderStreamAddCIDtoCode (Encoder pEncoder, int nCID, char sBuffer[4], int nLen)
{
unsigned long nRet = OK;
CMapEncoderStreamAttr pAttr = (CMapEncoderStreamAttr)pEncoder->pAttr;
nCID = min( 65536, max( 0, nCID ) );
pAttr->anCIDtoCode[nCID].sCode[0] = sBuffer[0];
pAttr->anCIDtoCode[nCID].sCode[1] = sBuffer[1];
pAttr->anCIDtoCode[nCID].sCode[2] = sBuffer[2];
pAttr->anCIDtoCode[nCID].sCode[3] = sBuffer[3];
pAttr->anCIDtoCode[nCID].nLen = nLen;
}
//-- CMapEncoder ---------------------------------------------------------------------------------
typedef BOOL (*CMapEncoderByteTypeFunc) (Encoder pEncoder, BYTE nByte);
typedef struct TCIDRangeRec
{
unsigned short nFrom;
unsigned short nTo;
unsigned short nCID;
} CIDRangeRec;
typedef struct TUnicodeMapRec
{
unsigned short nCode;
unsigned short nUnicode;
} UnicodeMapRec;
typedef struct TCMapEncoderAttrRec *CMapEncoderAttr;
typedef struct TCMapEncoderAttrRec
{
unsigned short anUnicodeMap[256][256];
unsigned short anCIDMap[256][256];
unsigned short anJWWLineHead[MAX_JWW_NUM];
List pCMAPRange;
List pNotDefRange;
List pCodeSpaceRange;
WritingMode eWritingMode;
char sRegistry[LIMIT_MAX_NAME_LEN + 1];
char sOrdering[LIMIT_MAX_NAME_LEN + 1];
int nSuppliment;
CMapEncoderByteTypeFunc pIsLeadByteFn;
CMapEncoderByteTypeFunc pIsTrialByteFn;
int nUidOffset;
unsigned int anXUid[3];
// Èñïîëüçóåòñÿ òîëüêî äëÿ êîäèðîâîê òèïà EncoderTypeToUnicode
BYTE nFirstChar;
BYTE nLastChar;
} CMapEncoderAttrRec;
//-- CMAPEncoder - Âñïîìîãàòåëüíûå ôóíêöèè -------------------------------------------------------
ByteType CMapEncoderByteType (Encoder pEncoder, ParseTextRec *pState)
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
if ( pState->nIndex >= pState->nLen )
return ByteTypeUnknown;
if ( ByteTypeLead == pState->eByteType )
{
if ( pAttr->pIsTrialByteFn( pEncoder, pState->pText[ pState->nIndex ] ) )
pState->eByteType = ByteTypeTrial;
else
pState->eByteType = ByteTypeUnknown;
}
else
{
if ( pAttr->pIsLeadByteFn( pEncoder, pState->pText[ pState->nIndex ] ) )
pState->eByteType = ByteTypeLead;
else
pState->eByteType = ByteTypeSingle;
}
pState->nIndex++;
return pState->eByteType;
}
unsigned short CMapEncoderToUnicode (Encoder pEncoder, unsigned short nCode)
{
BYTE nLen = nCode;
BYTE nHei = nCode >> 8;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
return pAttr->anUnicodeMap[nLen][nHei];
}
unsigned short CMapEncoderToCID (Encoder pEncoder, unsigned short nCode)
{
BYTE nLen = nCode;
BYTE nHei = nCode >> 8;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
return pAttr->anCIDMap[nLen][nHei];
}
unsigned long CMapEncoderWriteHeader (Stream pOut)
{
unsigned long nRet = OK;
const char* sCMapHeader = "/CIDInit /ProcSet findresource begin\n"
"12 dict begin\n"
"begincmap\n";
nRet = StreamWriteStr( pOut, sCMapHeader );
return nRet;
}
unsigned long CMapEncoderWriteFooter (Stream pOut)
{
unsigned long nRet = OK;
const char* sCMapFooter = "endcmap\n"
"CMapName currentdict /CMap defineresource pop\n"
"end\n"
"end\n";
nRet = StreamWriteStr( pOut, sCMapFooter );
return nRet;
}
unsigned long CMapEncoderWriteCodeSpaceRange(Encoder pEncoder, Stream pOut)
{
// Ïîêà ìû òóò áóäåì ïèñàòü âñåãäà: <00> <FF>
// TO DO: Â áóäóùåì íàäî ñäåëàòü çàïèñü èç ïîëÿ pAttr->pCodeSpaceRange
unsigned long nRet = OK;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
const char* sBegin = "begincodespacerange";
const char* sEnd = "endcodespacerange";
int nLinesCount = 1;
if ( ( nRet = StreamWriteInt( pOut, nLinesCount ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteChar( pOut, ' ' ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteStr( pOut, sBegin ) ) )
return nRet;
if ( ( nRet = StreamWriteChar( pOut, '\n' ) ) != OK )
return nRet;
// Ýòî çíà÷èò, ÷òî ìû ñîáèðàåìñÿ çàêîäèðîâàòü ñèìâîëû íîìåðàìè îò 0 äî 255.
if ( ( nRet = StreamWriteStr( pOut, "<00> <FF>" ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteChar( pOut, '\n' ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteStr( pOut, sEnd ) ) )
return nRet;
if ( ( nRet = StreamWriteChar( pOut, '\n' ) ) != OK )
return nRet;
return nRet;
}
unsigned long CMapEncoderWriteBFChar (Encoder pEncoder, Stream pOut, int nCode, int nUnicode )
{
unsigned long nRet = OK;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
if ( ( nRet = StreamWriteChar( pOut, '<' ) ) != OK )
return nRet;
// Ïîñêîëüêó ìû â codespacerange ïèøåì êîäû îò 0 äî 255, òîãäà
// çäåñü êîäû äîëæíû áûòü äâóñèìâîëüíûìè(â øåñòíàäöàòèðè÷íîé ôîðìå)
if ( ( nRet = StreamWriteHex( pOut, nCode, 2 ) ) )
return nRet;
if ( ( nRet = StreamWriteStr( pOut, "> <" ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteHex( pOut, nUnicode, 4 ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteStr( pOut, ">\n" ) ) != OK )
return nRet;
return nRet;
}
unsigned long CMapEncoderWriteBFChars (Encoder pEncoder, Stream pOut, int nStartCode, int nLastCode)
{
unsigned long nRet = OK;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
int nCodesCount = nLastCode - nStartCode + 1;
if ( ( nRet = StreamWriteInt( pOut, nCodesCount ) ) != OK )
return nRet;
if ( ( nRet = StreamWriteStr( pOut, " beginbfchar\n") ) != OK )
return nRet;
for ( int nCode = nStartCode; nCode <= nLastCode; nCode++ )
{
unsigned short unUnicode = pEncoder->pToUnicodeFn( pEncoder, nCode );
CMapEncoderWriteBFChar( pEncoder, pOut, nCode, unUnicode );
}
if ( ( nRet = StreamWriteStr( pOut, "endbfchar\n") ) != OK )
return nRet;
return nRet;
}
unsigned long CMapEncoderWriteBFChars (Encoder pEncoder, Stream pOut)
{
unsigned long nRet = OK;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
if ( pAttr->nLastChar < 0 || pAttr->nFirstChar < 0 || EncoderTypeToUnicode != pEncoder->eType )
return AVS_OFFICEPDFWRITER_ERROR_INVALID_ENCODER_TYPE;
// Íà ñàìîì äåëå, ïðåäïîëàãàåì, ÷òî nStartCode = 1, ò.å. pAttr->nFirstChar = 0
int nStartCode = pAttr->nFirstChar + 1; // 0 êîä íå èñïîëüçóåòñÿ
int nLastCode = pAttr->nLastChar;
int nCodesCount = nLastCode - nStartCode + 1;
// Ïî÷åìó-òî âî ìíîãèõ CMap ôàéëàõ èäåò ðàçáèâêà ïî 100 ýëåìåíòîâ, ïîýòîìó ñäåëàåì òàêæå
if ( nCodesCount <= 100 )
{
nRet += CMapEncoderWriteBFChars( pEncoder, pOut, nStartCode, nLastCode );
}
else
{
nRet += CMapEncoderWriteBFChars( pEncoder, pOut, nStartCode, 100 );
if ( nCodesCount <= 200 )
{
nRet += CMapEncoderWriteBFChars( pEncoder, pOut, 101, nLastCode );
}
else
{
nRet += CMapEncoderWriteBFChars( pEncoder, pOut, 101, 200 );
nRet += CMapEncoderWriteBFChars( pEncoder, pOut, 201, nLastCode );
}
}
return nRet;
}
unsigned long CMapEncoderWriteInfo (Encoder pEncoder, Stream pOut)
{
unsigned long nRet = OK;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
// Íà ñàìîì äåëå, ïîêà ìû áóäåì ïðåäïîëàãàòü, ÷òî ó íàñ sRegistry = Adobe, sOrdering = UCS, nSupplement = 0
//if ( ( nRet = StreamWriteStr( pOut, "/CIDSystemInfo\n<< /Registry (" ) ) != OK )
// return nRet;
//if ( ( nRet = StreamWriteStr( pOut, pAttr->sRegistry ) ) != OK )
// return nRet;
//if ( ( nRet = StreamWriteStr( pOut, ")\n /Ordering (") ) != OK )
// return nRet;
//if ( ( nRet = StreamWriteStr( pOut, pAttr->sOrdering ) ) != OK )
// return nRet;
//if ( ( nRet = StreamWriteStr( pOut, ")\n /Supplement ") ) != OK )
// return nRet;
//if ( ( nRet = StreamWriteInt( pOut, pAttr->nSuppliment ) ) != OK )
// return nRet;
//if ( ( nRet = StreamWriteStr( pOut, "\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n") ) != OK )
// return nRet;
if ( ( nRet = StreamWriteStr( pOut, "/CIDSystemInfo\n<< /Registry (Adobe)\n /Ordering (UCS)\n /Supplement 0\n >> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n" ) ) != OK )
return nRet;
return nRet;
}
unsigned long CMapEncoderWrite (Encoder pEncoder, Stream pOut)
{
unsigned long nRet = OK;
// ToDo: ñäåëàòü çàïèñü
// Ïîêà ñäåëàåì ïðîñòóþ çàïèñü, êîòîðàÿ íåîáõîäèìà äëÿ ïîääåðæêè ToUnicode â øðèôòàõ
if ( ( nRet = CMapEncoderWriteHeader( pOut ) ) != OK )
return nRet;
if ( ( nRet = CMapEncoderWriteInfo( pEncoder, pOut ) ) != OK )
return nRet;
if ( ( nRet = CMapEncoderWriteCodeSpaceRange( pEncoder, pOut ) ) != OK )
return nRet;
if ( ( nRet = CMapEncoderWriteBFChars( pEncoder, pOut ) ) != OK )
return nRet;
if ( ( nRet = CMapEncoderWriteFooter( pOut ) ) != OK )
return nRet;
return nRet;
}
void CMapEncoderFree (Encoder pEncoder)
{
CIDRangeRec *pData = NULL;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
if ( pAttr && pAttr->pCMAPRange )
{
for ( unsigned int nIndex = 0; nIndex < pAttr->pCMAPRange->nCount; nIndex++)
{
pData = (CIDRangeRec*)ListItemAt( pAttr->pCMAPRange, nIndex );
FreeMem( pEncoder->oMMgr, pData);
}
ListFree( pAttr->pCMAPRange );
}
if ( pAttr && pAttr->pNotDefRange )
{
for ( unsigned int nIndex = 0; nIndex < pAttr->pNotDefRange->nCount; nIndex++)
{
pData = (CIDRangeRec*)ListItemAt( pAttr->pNotDefRange, nIndex );
FreeMem( pEncoder->oMMgr, pData );
}
ListFree( pAttr->pNotDefRange );
}
if ( pAttr && pAttr->pCodeSpaceRange )
{
for ( unsigned int nIndex = 0; nIndex < pAttr->pCodeSpaceRange->nCount; nIndex++)
{
pData = (CIDRangeRec*)ListItemAt( pAttr->pCodeSpaceRange, nIndex );
FreeMem( pEncoder->oMMgr, pData );
}
ListFree( pAttr->pCodeSpaceRange );
}
FreeMem( pEncoder->oMMgr, pEncoder->pAttr );
pEncoder->pAttr = NULL;
}
static unsigned long AddCIDRange (MMgr oMMgr, CIDRangeRec oRange, List pTarget)
{
unsigned long nRet = OK;
CIDRangeRec *pRange = (CIDRangeRec*)GetMem( oMMgr, sizeof(CIDRangeRec) );
if ( !pRange )
return oMMgr->oError->nErrorNo;
pRange->nFrom = oRange.nFrom;
pRange->nTo = oRange.nTo;
pRange->nCID = oRange.nCID;
if ( OK != ( nRet = ListAdd( pTarget, pRange ) ) )
{
FreeMem( oMMgr, pRange );
return nRet;
}
return OK;
}
//-- CMAPEncoder - Îñíîâíûå ôóíêöèè --------------------------------------------------------------
//  íà÷àëå, CMapEncoder ñîçäàåòñÿ êàê âèðòóàëüíûé îáúåêò.
// Êîãäà âûçâàåòñÿ ôóíêöèÿ InitFn, cmap-data çàãðóæàåòñÿ è
// ýòîò îáúåêò ñòàíîâèòñÿ äîñòóïíûì.
Encoder CMapEncoderNew (MMgr oMMgr, char *sName, EncoderInitFunc pInitFn)
{
if ( NULL == oMMgr )
return NULL;
Encoder pEncoder = (Encoder)GetMem( oMMgr, sizeof(EncoderRec) );
if ( !pEncoder )
return NULL;
UtilsMemSet( pEncoder, 0, sizeof(EncoderRec) );
UtilsStrCpy( pEncoder->sName, sName, pEncoder->sName + LIMIT_MAX_NAME_LEN );
pEncoder->oMMgr = oMMgr;
pEncoder->oError = oMMgr->oError;
pEncoder->eType = EncoderTypeUninitialized;
pEncoder->pByteTypeFn = CMapEncoderByteType;
pEncoder->pToUnicodeFn = CMapEncoderToUnicode;
pEncoder->pWriteFn = CMapEncoderWrite;
pEncoder->pFreeFn = CMapEncoderFree;
pEncoder->pInitFn = pInitFn;
pEncoder->nSigBytes = ENCODER_SIG_BYTES;
return pEncoder;
}
unsigned long CMapEncoderInitAttr (Encoder pEncoder)
{
if ( pEncoder->pAttr )
return AVS_OFFICEPDFWRITER_ERROR_INVALID_ENCODER;
CMapEncoderAttr pEncoderAttr = (CMapEncoderAttr)GetMem( pEncoder->oMMgr, sizeof(CMapEncoderAttrRec) );
if ( !pEncoderAttr)
return pEncoder->oError->nErrorNo;
UtilsMemSet( pEncoderAttr, 0, sizeof(CMapEncoderAttrRec) );
pEncoder->pAttr = pEncoderAttr;
pEncoderAttr->eWritingMode = WModeHorizontal;
for ( unsigned int nI = 0; nI <= 255; nI++)
{
for ( unsigned int nJ = 0; nJ <= 255; nJ++)
{
// íåîïðåäåëåííûå ñèìâîëû çàìåíÿþòñÿ êâàäðàòàìè
pEncoderAttr->anUnicodeMap[nI][nJ] = 0x25A1;
}
}
pEncoderAttr->pCMAPRange = ListNew( pEncoder->oMMgr, DEF_RANGE_TBL_NUM);
if ( !pEncoderAttr->pCMAPRange )
return pEncoder->oError->nErrorNo;
pEncoderAttr->pNotDefRange = ListNew( pEncoder->oMMgr, DEF_ITEMS_PER_BLOCK);
if ( !pEncoderAttr->pNotDefRange )
return pEncoder->oError->nErrorNo;
pEncoderAttr->pCodeSpaceRange = ListNew( pEncoder->oMMgr, DEF_ITEMS_PER_BLOCK);
if ( !pEncoderAttr->pCodeSpaceRange )
return pEncoder->oError->nErrorNo;
pEncoderAttr->nFirstChar = -1;
pEncoderAttr->nLastChar = -1;
return OK;
}
unsigned long CMapEncoderSetParseText (Encoder pEncoder, ParseTextRec *pState, const BYTE *sText, unsigned int nLen)
{
pState->pText = sText;
pState->nIndex = 0;
pState->nLen = nLen;
pState->eByteType = ByteTypeSingle;
return OK;
}
unsigned long CMapEncoderAddCMap (Encoder pEncoder, const CIDRangeRec *pRange)
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
// Êîïèðóåì îïðåäåëåííûé pdf_cid_range ìàññèâ â fRangeArray.
while ( 0xffff != pRange->nFrom && 0xffff != pRange->nTo )
{
unsigned short nCode = pRange->nFrom;
unsigned short nCID = pRange->nCID;
unsigned long nRet = OK;
while ( nCode <= pRange->nTo )
{
BYTE nLen = nCode;
BYTE nHei = nCode >> 8;
pAttr->anCIDMap[nLen][nHei] = nCID;
nCode++;
nCID++;
}
CIDRangeRec *pTempRange = (CIDRangeRec *)GetMem( pEncoder->oMMgr, sizeof(CIDRangeRec) );
if ( !pTempRange )
return pEncoder->oError->nErrorNo;
pTempRange->nFrom = pRange->nFrom;
pTempRange->nTo = pRange->nTo;
pTempRange->nCID = pRange->nCID;
if ( OK != ( nRet = ListAdd( pAttr->pCMAPRange, pTempRange ) ) )
{
FreeMem( pEncoder->oMMgr, pTempRange );
return nRet;
}
pRange++;
}
return OK;
}
unsigned long CMapEncoderAddNotDefRange (Encoder pEncoder, CIDRangeRec oRange)
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
return AddCIDRange( pEncoder->oMMgr, oRange, pAttr->pNotDefRange );
}
unsigned long CMapEncoderAddCodeSpaceRange (Encoder pEncoder, CIDRangeRec oRange)
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
return AddCIDRange( pEncoder->oMMgr, oRange, pAttr->pCodeSpaceRange );
}
void CMapEncoderSetUnicodeArray (Encoder pEncoder, const UnicodeMapRec *pArray)
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
if ( NULL != pArray )
{
while ( 0xffff != pArray->nUnicode )
{
BYTE nLen = pArray->nCode;
BYTE nHei = pArray->nCode >> 8;
pAttr->anUnicodeMap[nLen][nHei] = pArray->nUnicode;
pArray++;
}
BYTE nLen = pArray->nCode;
BYTE nHei = pArray->nCode >> 8;
pAttr->anUnicodeMap[nLen][nHei] = pArray->nUnicode;
}
}
unsigned long CMapEncoderAddJWWLineHead (Encoder pEncoder, const unsigned short *pnCode)
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
for (unsigned int nI = 0; nI < MAX_JWW_NUM; nI++ )
{
if ( 0 == *pnCode )
break;
for ( unsigned int nJ = 0; nJ < MAX_JWW_NUM; nJ++)
{
if ( *pnCode == pAttr->anJWWLineHead[nJ] )
break;
if ( 0 == pAttr->anJWWLineHead[nJ] )
{
pAttr->anJWWLineHead[nJ] = *pnCode;
break;
}
if ( MAX_JWW_NUM - 1 == nJ )
return SetError( pEncoder->oError, AVS_OFFICEPDFWRITER_ERROR_EXCEED_JWW_CODE_NUM_LIMIT, nI );
}
pnCode++;
}
return OK;
}
BOOL EncoderCheckJWWLineHead (Encoder pEncoder, const unsigned short nCode)
{
if ( !EncoderValidate( pEncoder ) )
return FALSE;
if ( EncoderTypeDoubleByteBuilt != pEncoder->eType )
return FALSE;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
for ( unsigned int nIndex = 0; nIndex < MAX_JWW_NUM; nIndex++)
{
if ( nCode == pAttr->anJWWLineHead[nIndex] )
return TRUE;
if ( 0 == pAttr->anJWWLineHead[nIndex] )
return FALSE;
}
return FALSE;
}
BOOL CMapEncoderUpdateUnicodeArray(Encoder pEncoder, unsigned short *pArray)
{
// Èñïîëüçóåòñÿ òîëüêî äëÿ êîäèðîâîê òèïà EncoderTypeToUnicode
if ( EncoderTypeToUnicode != pEncoder->eType )
return FALSE;
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
UnicodeMapRec* pResultArray = new UnicodeMapRec[257]; // 0-îé ñèìâîë + 255 ñèìâîëîâ êîäèðîâêè + 1 ñèìâîë 0xFFFF
if ( !pResultArray )
return FALSE;
int nIndex = 0;
pResultArray[0].nCode = 0;
pResultArray[0].nUnicode = 0x0000;
for ( nIndex = pAttr->nFirstChar + 1; nIndex <= pAttr->nLastChar; nIndex++ )
{
pResultArray[nIndex].nCode = nIndex;
pResultArray[nIndex].nUnicode = EncoderToUnicode( pEncoder, nIndex );
}
if ( NULL != pArray )
{
while( 0xFFFF != *pArray && nIndex < 256 )
{
if ( 0xFFFF == EncoderToCode( pEncoder, *pArray ) )
{
pResultArray[nIndex].nCode = nIndex;
pResultArray[nIndex].nUnicode = *pArray;
nIndex++;
}
pArray++;
}
}
if ( 255 < nIndex )
{
delete []pResultArray;
return FALSE;
}
else
{
pResultArray[nIndex].nCode = nIndex;
pResultArray[nIndex].nUnicode = 0xFFFF;
CMapEncoderSetUnicodeArray( pEncoder, pResultArray );
pAttr->nLastChar = nIndex - 1;
delete []pResultArray;
return TRUE;
}
}
//-- Äîïîëíèòåëüíûå âíåøíèå ôóíêöèè --------------------------------------------------------------
unsigned short EncoderGetUnicode (Encoder pEncoder, unsigned short nCode)
{
if ( !EncoderValidate( pEncoder ) )
return 0;
return EncoderToUnicode( pEncoder, nCode );
}
ByteType EncoderGetByteType (Encoder pEncoder, const char *sText, unsigned int nIndex)
{
ParseTextRec oParseState;
ByteType eType;
if ( !EncoderValidate( pEncoder ) )
return ByteTypeUnknown;
if ( EncoderTypeDoubleByteBuilt != pEncoder->eType )
return ByteTypeSingle;
EncoderSetParseText( pEncoder, &oParseState, (BYTE*)sText, nIndex + 1 );
for (;;)
{
eType = CMapEncoderByteType( pEncoder, &oParseState);
if ( 0 == nIndex )
break;
sText++;
if ( !(*sText) )
return ByteTypeUnknown;
nIndex--;
}
return eType;
}
EncoderType EncoderGetType (Encoder pEncoder)
{
if ( !EncoderValidate( pEncoder ) )
return EncoderTypeUnknown;
return pEncoder->eType;
}
WritingMode EncoderGetWritingMode(Encoder pEncoder)
{
if ( !EncoderValidate( pEncoder ) )
return WModeHorizontal;
if ( EncoderTypeDoubleByteBuilt == pEncoder->eType )
{
CMapEncoderAttr pAttr = (CMapEncoderAttr)pEncoder->pAttr;
return pAttr->eWritingMode;
}
return WModeHorizontal;
}
BOOL EncoderWCharToString (Encoder pEncoder, BSTR bsSrc, CString *psDst)
{
CStringW sSrc( bsSrc );
// Äàííàÿ ôóíêöèÿ ïðîâåðÿåò âñå ëè ñèìâîëû èç usSrc ïðèñóòñòâóþò â äàííîé êîäèðîâêå;
// åñëè ïðèñóòñòâóþò âñå, òîãäà â psDst çàïèñûâàåòñÿ ñòðîêà usSrc, â ñîîòâåòñòâèè ñ äàííîé êîäèðîâêîé.
CString sResult = _T("");
int nLen = sSrc.GetLength();
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned short unUnicodeChar = (unsigned short)sSrc.GetAt( nIndex );
unsigned short unCode = EncoderToCode( pEncoder, unUnicodeChar );
if ( 0xFFFF == unCode )
return FALSE;
else
sResult += wchar_t(unCode);
}
*psDst = sResult;
return TRUE;
}
#endif /* _ENCODER_H */