📄 docdecoder.cpp
字号:
int
CDocDecoder::iDepotOffset(int iIndex, int iBlockSize)
{
int iTmp1, iTmp2;
switch (iBlockSize) {
case BIG_BLOCK_SIZE:
return (iIndex + 1) * BIG_BLOCK_SIZE;
case SMALL_BLOCK_SIZE:
iTmp1 = iIndex / SIZE_RATIO;
iTmp2 = iIndex % SIZE_RATIO;
if (aiSmallBlockList == NULL ||
iSmallBlockListLen <= iTmp1) {
return 0;
}
return ((aiSmallBlockList[iTmp1] + 1) * SIZE_RATIO + iTmp2)
* SMALL_BLOCK_SIZE;
default:
return 0;
}
} /* end of iDepotOffset */
diagram_type *
CDocDecoder::pCreateDiagram(void)
{
diagram_type *pDiag;
/* Get the necessary memory */
pDiag = (diagram_type *)xmalloc(sizeof(diagram_type));
/* Initialisation */
pDiag->iXleft = 0;
pDiag->iYtop = 0;
/* Return success */
return pDiag;
} /* end of pCreateDiagram */
void
CDocDecoder::vDestroyDiagram(diagram_type *pDiag)
{
if (pDiag == NULL) {
return;
}
pDiag = (diagram_type *)xfree(pDiag);
} /* end of vDestroyDiagram */
void
CDocDecoder::vMove2NextLine(diagram_type *pDiag, draw_fontref tFontRef, int iFontsize)
{
pDiag->iXleft = 0;
//OUT
outbuf[outbuflen++]=0xa;
} /* end of vMove2NextLine */
void
CDocDecoder::vSubstring2Diagram(diagram_type *pDiag,
unsigned short *szString, int iStringLength, int iStringWidth,
int iColour, unsigned char ucFontstyle, draw_fontref tFontRef,
int iFontsize, int iMaxFontsize)
{
if (szString[0] == '\0' || iStringLength <= 0) {
return;
}
//OUT
memcpy(outbuf+outbuflen,szString,iStringLength*2);
outbuflen+=iStringLength;
pDiag->iXleft += iStringWidth;
} /* end of vSubstring2Diagram */
void
CDocDecoder::vSetLeftIndentation(diagram_type *pDiag, int iLeftIndentation)
{
int iX, iCount, iNbr;
unsigned short uc=FILLER_CHAR;
iX = iMilliPoints2DrawUnits(iLeftIndentation);
if (iX > pDiag->iXleft) {
iNbr = iDrawUnits2Char(iX - pDiag->iXleft);
pDiag->iXleft = iX;
for (iCount = 0; iCount < iNbr; iCount++)
{
//out
outbuf[outbuflen++]=uc;
}
}
} /* end of vSetLeftIndentation */
void
CDocDecoder::vEndOfParagraph2Diagram(diagram_type *pDiag,
draw_fontref tFontRef, int iFontsize)
{
if (pDiag->iXleft > 0) {
/* To the start of the line */
vMove2NextLine(pDiag, tFontRef, iFontsize);
}
/* Empty line */
vMove2NextLine(pDiag, tFontRef, iFontsize);
} /* end of vEndOfParagraph2Diagram */
void
CDocDecoder::vEmptyLine2Diagram(diagram_type *pDiag,
draw_fontref tFontRef, int iFontsize)
{
if (pDiag->iXleft > 0) {
/* To the start of the line */
vMove2NextLine(pDiag, tFontRef, iFontsize);
}
/* Empty line */
vMove2NextLine(pDiag, tFontRef, iFontsize);
} /* end of vEmptyLine2Diagram */
void
CDocDecoder::vEndOfPage2Diagram(diagram_type *pDiag,
draw_fontref tFontRef, int iFontsize)
{
vEndOfParagraph2Diagram(pDiag, tFontRef, iFontsize);
} /* end of vEndOfPage2Diagram */
bool
CDocDecoder::bAddBlocks(int iFirstOffset, int iTotalLength, bool bUsesUnicode,
int iStartBlock, const int *aiBBD, int iBBDLen)
{
text_block_type tTextBlock;
int iIndex, iTextOffset, iOffset, iToGo;
if (bUsesUnicode) {
/* One character equals two bytes */
iToGo = iTotalLength * 2;
} else {
/* One character equals one byte */
iToGo = iTotalLength;
}
iTextOffset = iFirstOffset;
iOffset = iFirstOffset;
for (iIndex = iStartBlock;
iIndex != END_OF_CHAIN && iToGo > 0;
iIndex = aiBBD[iIndex]) {
if (iIndex < 0 || iIndex >= iBBDLen) {
return false;
// werr(1, "The Big Block Depot is corrupt");
}
if (iOffset >= BIG_BLOCK_SIZE) {
iOffset -= BIG_BLOCK_SIZE;
continue;
}
tTextBlock.iFileOffset =
(iIndex + 1) * BIG_BLOCK_SIZE + iOffset;
tTextBlock.iTextOffset = iTextOffset;
tTextBlock.iLength = min(BIG_BLOCK_SIZE - iOffset, iToGo);
tTextBlock.bUsesUnicode = bUsesUnicode;
iOffset = 0;
if (!bAdd2TextBlockList(&tTextBlock)) {
return false;
}
iTextOffset += tTextBlock.iLength;
iToGo -= tTextBlock.iLength;
}
return iToGo == 0;
} /* end of bAddBlocks */
text_info_enum
CDocDecoder::eGet6DocumentText(unsigned char *pFile, bool bUsesUnicode, int iStartBlock,
const int *aiBBD, int iBBDLen, const unsigned char *aucHeader)
{
unsigned char *aucBuffer;
int iIndex, iOffset;
int iBeginTextInfo, iTextInfoLen;
int iOff, iType, iLen, iPieces, iTotLength;
iBeginTextInfo = (int)ulGetLong(0x160, aucHeader);
iTextInfoLen = (int)ulGetLong(0x164, aucHeader);
aucBuffer = (unsigned char *)xmalloc(iTextInfoLen);
if (!bReadBuffer(pFile, iStartBlock,
aiBBD, iBBDLen, BIG_BLOCK_SIZE,
aucBuffer, iBeginTextInfo, iTextInfoLen)) {
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_failure;
}
iOff = 0;
while (iOff < iTextInfoLen) {
iType = (int)ucGetByte(iOff, aucBuffer);
iOff++;
if (iType == 0) {
iOff++;
continue;
}
iLen = (int)usGetWord(iOff, aucBuffer);
iOff += 2;
if (iType == 1) {
iOff += iLen;
continue;
}
if (iType != 2) {
// werr(0, "Unknown type of 'fastsaved' format");
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_failure;
}
/* Type 2 */
iOff += 2;
iPieces = (iLen - 4) / 12;
for (iIndex = 0; iIndex < iPieces; iIndex++) {
iOffset = (int)ulGetLong(
iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
aucBuffer);
iTotLength = (int)ulGetLong(
iOff + (iIndex + 1) * 4,
aucBuffer) -
(int)ulGetLong(
iOff + iIndex * 4,
aucBuffer);
if (!bAddBlocks(iOffset, iTotLength, bUsesUnicode,
iStartBlock,
aiBBD, iBBDLen)) {
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_failure;
}
}
break;
}
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_success;
} /* end of eGet6DocumentText */
text_info_enum
CDocDecoder::eGet8DocumentText(unsigned char *pFile, const pps_info_type *pPPS,
const int *aiBBD, int iBBDLen, const int *aiSBD, int iSBDLen,
const unsigned char *aucHeader)
{
const int *aiBlockDepot;
unsigned char *aucBuffer;
int iTableStartBlock, iTableSize, iBlockDepotLen, iBlockSize;
int iIndex, iOffset;
int iBeginTextInfo, iTextInfoLen;
int iOff, iType, iLen, iPieces, iTotLength;
bool bUsesUnicode;
unsigned short usDocStatus;
iBeginTextInfo = (int)ulGetLong(0x1a2, aucHeader);
iTextInfoLen = (int)ulGetLong(0x1a6, aucHeader);
/* Use 0Table or 1Table? */
usDocStatus = usGetWord(0x0a, aucHeader);
if (usDocStatus & BIT(9)) {
iTableStartBlock = pPPS->t1Table.iSb;
iTableSize = pPPS->t1Table.iSize;
} else {
iTableStartBlock = pPPS->t0Table.iSb;
iTableSize = pPPS->t0Table.iSize;
}
if (iTableStartBlock < 0) {
return text_failure;
}
if (iTableSize < MIN_SIZE_FOR_BBD_USE) {
/* Use the Small Block Depot */
aiBlockDepot = aiSBD;
iBlockDepotLen = iSBDLen;
iBlockSize = SMALL_BLOCK_SIZE;
} else {
/* Use the Big Block Depot */
aiBlockDepot = aiBBD;
iBlockDepotLen = iBBDLen;
iBlockSize = BIG_BLOCK_SIZE;
}
aucBuffer = (unsigned char *)xmalloc(iTextInfoLen);
if (!bReadBuffer(pFile, iTableStartBlock,
aiBlockDepot, iBlockDepotLen, iBlockSize,
aucBuffer, iBeginTextInfo, iTextInfoLen)) {
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_no_information;
}
iOff = 0;
while (iOff < iTextInfoLen) {
iType = (int)ucGetByte(iOff, aucBuffer);
iOff++;
if (iType == 0) {
iOff++;
continue;
}
if (iType == 1) {
iLen = (int)usGetWord(iOff, aucBuffer);
iOff += iLen + 2;
continue;
}
if (iType != 2) {
// werr(0, "Unknown type of 'fastsaved' format");
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_failure;
}
/* Type 2 */
iLen = (int)ulGetLong(iOff, aucBuffer);
iOff += 4;
iPieces = (iLen - 4) / 12;
for (iIndex = 0; iIndex < iPieces; iIndex++) {
iOffset = (int)ulGetLong(
iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
aucBuffer);
if ((iOffset & BIT(30)) == 0) {
bUsesUnicode = TRUE;
} else {
bUsesUnicode = false;
iOffset &= ~BIT(30);
iOffset /= 2;
}
iTotLength = (int)ulGetLong(
iOff + (iIndex + 1) * 4,
aucBuffer) -
(int)ulGetLong(
iOff + iIndex * 4,
aucBuffer);
if (!bAddBlocks(iOffset, iTotLength, bUsesUnicode,
pPPS->tWordDocument.iSb,
aiBBD, iBBDLen)) {
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_failure;
}
}
break;
}
aucBuffer = (unsigned char *)xfree(aucBuffer);
return text_success;
} /* end of eGet8DocumentText */
font_block_type *
CDocDecoder::pGetNextFontInfoListItem(const font_block_type *pCurr)
{
const font_desc_type *pRecord;
int iOffset;
if (pCurr == NULL)
return NULL;
iOffset = offsetof(font_desc_type, tInfo);
/* Many casts to prevent alignment warnings */
pRecord = (font_desc_type *)(void *)((char *)pCurr - iOffset);
if (pRecord->pNext == NULL) {
return NULL;
}
return &pRecord->pNext->tInfo;
} /* end of pGetNextFontInfoListItem */
bool
CDocDecoder::bReadBytes(unsigned char *aucBytes, size_t tMemb, long lOffset, unsigned char *inbuf)
{
memcpy(aucBytes,inbuf+lOffset,tMemb);
return true;
} /* end of bReadBytes */
bool
CDocDecoder::bReadBuffer(unsigned char *pFile, int iStartBlock,
const int *aiBlockDepot, int iBlockDepotLen, int iBlockSize,
unsigned char *aucBuffer, int iOffset, int iToRead)
{
int iIndex, iBegin, iLen;
if (iOffset < 0) {
return false;
}
for (iIndex = iStartBlock;
iIndex != END_OF_CHAIN && iToRead > 0;
iIndex = aiBlockDepot[iIndex]) {
if (iIndex < 0 || iIndex >= iBlockDepotLen) {
return false;
}
if (iOffset >= iBlockSize) {
iOffset -= iBlockSize;
continue;
}
iBegin = iDepotOffset(iIndex, iBlockSize) + iOffset;
iLen = min(iBlockSize - iOffset, iToRead);
iOffset = 0;
if (!bReadBytes(aucBuffer, iLen, iBegin, pFile)) {
// werr(0, "Read big block %d not possible", iBegin);
return false;
}
aucBuffer += iLen;
iToRead -= iLen;
}
return iToRead == 0;
} /* end of bReadBuffer */
int
CDocDecoder::iFindSplit(const unsigned short *szString, int iStringLen)
{
int iSplit;
iSplit = iStringLen - 1;
while (iSplit >= 1) {
if (szString[iSplit] == ' ' ||
(szString[iSplit] == '-' &&
szString[iSplit - 1] != ' ')) {
return iSplit;
}
iSplit--;
}
return -1;
} /* end of iFindSplit */
output_type *
CDocDecoder::pSplitList(output_type *pAnchor)
{
output_type *pCurr, *pLeftOver;
int iIndex;
for (pCurr = pAnchor; pCurr->pNext != NULL; pCurr = pCurr->pNext)
; /* EMPTY */
for (; pCurr != NULL; pCurr = pCurr->pPrev) {
iIndex = iFindSplit(pCurr->szStorage, pCurr->iNextFree);
if (iIndex >= 0) {
break;
}
}
if (pCurr == NULL) {
/* No split, no leftover */
return NULL;
}
/* Split over the iIndex-th character */
pLeftOver = (output_type *)xmalloc(sizeof(*pLeftOver));
pLeftOver->iStorageSize = pCurr->iNextFree - iIndex;
pLeftOver->szStorage = (unsigned short *)xmalloc(pLeftOver->iStorageSize*sizeof(unsigned short));
pLeftOver->iNextFree = pCurr->iNextFree - iIndex - 1;
shortncpy(pLeftOver->szStorage,
pCurr->szStorage + iIndex + 1, pLeftOver->iNextFree);
pLeftOver->szStorage[pLeftOver->iNextFree] = '\0';
pLeftOver->iColour = pCurr->iColour;
pLeftOver->ucFontstyle = pCurr->ucFontstyle;
pLeftOver->tFontRef = pCurr->tFontRef;
pLeftOver->ucFontsize = pCurr->ucFontsize;
pLeftOver->iStringWidth = 0;
pLeftOver->pPrev = NULL;
pLeftOver->pNext = pCurr->pNext;
if (pLeftOver->pNext != NULL) {
pLeftOver->pNext->pPrev = pLeftOver;
}
while (iIndex >= 0 && ISSPACE(pCurr->szStorage[iIndex])) {
iIndex--;
}
pCurr->iNextFree = iIndex + 1;
pCurr->szStorage[pCurr->iNextFree] = '\0';
pCurr->iStringWidth = 0;
pCurr->pNext = NULL;
return pLeftOver;
} /* end of pSplitList */
int
CDocDecoder::iInteger2Roman(int iNumber, bool bUpperCase,
unsigned short *szOutput)
{
unsigned short *outp, *p, *q;
int iNextVal, iValue;
unsigned short us[64];
if (iNumber <= 0 || iNumber >= 4000) {
szOutput[0] = '\0';
return 0;
}
outp = szOutput;
if(bUpperCase)
toUnicodeStr(us,(unsigned char *)"M\2D\5C\2L\5X\2V\5I");
else
toUnicodeStr(us,(unsigned char *)"m\2d\5c\2l\5x\2v\5i");
p =us;
iValue = 1000;
for (;;) {
while (iNumber >= iValue) {
*outp++ = *p;
iNumber -= iValue;
}
if (iNumber <= 0) {
*outp = '\0';
return (int)(outp - szOutput);
}
q = p + 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -