mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
1546 lines
44 KiB
C
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 */
|
|
|