Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1644 lines
43 KiB

#include "chrtns.h"
#include "chprtns.pro"
#define NULLHANDLE (HANDLE) NULL
#define SCCDEBUG 1 // MAC TESTING!!!
VOID SO_ENTRYMOD SOPutChar( wCh, dwUser1, dwUser2 )
WORD wCh;
DWORD dwUser1;
DWORD dwUser2;
{
WORD wChMap;
SetupWorld();
#ifndef DBCS
#ifdef SCCDEBUG
if( wCh & 0xfe00 )
{
#ifdef WINDOWS
MessageBox( (HWND)NULL, "Filter put a char larger than 512.", NULL, MB_ICONSTOP | MB_OK );
CHBailOut((WORD)-1);
#endif
#ifdef MAC
DebugStr("\pSOPutChar: value over 512");
#endif
}
#endif
#endif
#ifdef DBCS
if ( wCh & 0x8000 ) /* This is a Double Byte Character */
{
#ifdef WINDOWS
if ( IsDBCSLeadByte((BYTE)(wCh>>8)) == FALSE )
wCh = 1; /* Not supported on this system so map to unknown */
else
{
if( Chunker->CurChunkSize+1 >= SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
if( !Chunker->ChunkFinished )
{
*CHUNKBUFPTR++ = (BYTE) (wCh>>8);
*CHUNKBUFPTR++ = (BYTE) wCh;
Chunker->CurChunkSize += 2;
Chunker->dwChunkCountables++;
}
RestoreWorld();
return;
}
#else
wCh = 1; /* Will map to the unknown character */
#endif
}
#endif
wChMap = (BYTE) CharMap[wCh];
if( wChMap > 1 )
{
if( Chunker->CurChunkSize >= SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
if( !Chunker->ChunkFinished )
{
*CHUNKBUFPTR++ = (BYTE) wChMap;
Chunker->CurChunkSize++;
Chunker->dwChunkCountables++;
}
}
else if( wChMap == 1 ) // Unknown characters.
SOPutSpecialCharX( SO_CHUNKNOWN, SO_COUNTBIT, dwUser1, dwUser2 );
else
SOPutCharX( wCh, SO_COUNTBIT, dwUser1, dwUser2 );
RestoreWorld();
}
// Make sure this is kept up-to-date.
#define SO_SPECIALCHARSIZE 4
VOID SO_ENTRYMOD SOPutCharX( wCh, wType, dwUser1, dwUser2 )
WORD wCh;
WORD wType;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
wCh = (BYTE) CharMap[wCh];
if( Chunker->CurChunkSize+SO_SPECIALCHARSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
if( !Chunker->ChunkFinished )
{
*CHUNKBUFPTR++ = (BYTE) SO_BEGINTOKEN;
if( wCh == 1 )
{
*CHUNKBUFPTR++ = SO_SPECIALCHAR;
*CHUNKBUFPTR++ = (BYTE) wType;
*CHUNKBUFPTR++ = (BYTE) SO_CHUNKNOWN;
}
else
{
if( !wCh ) // This is the convoluted way we map a character
wCh = (BYTE) SO_BEGINTOKEN; // with the same value as SO_BEGINTOKEN.
*CHUNKBUFPTR++ = SO_CHARX;
*CHUNKBUFPTR++ = (BYTE) wType;
*CHUNKBUFPTR++ = (BYTE) wCh;
}
Chunker->CurChunkSize += SO_SPECIALCHARSIZE;
if( wType & SO_COUNTBIT )
Chunker->dwChunkCountables++;
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutSpecialCharX( wCh, wType, dwUser1, dwUser2 )
WORD wCh;
WORD wType;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_SPECIALCHARSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
if( !Chunker->ChunkFinished )
{
*CHUNKBUFPTR++ = (BYTE)SO_BEGINTOKEN;
*CHUNKBUFPTR++ = (BYTE)SO_SPECIALCHAR;
*CHUNKBUFPTR++ = (BYTE) wType;
*CHUNKBUFPTR++ = (BYTE) wCh;
Chunker->CurChunkSize += SO_SPECIALCHARSIZE;
if( wType & SO_COUNTBIT )
Chunker->dwChunkCountables++;
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutString( lpString, wSize, dwUser1, dwUser2 )
LPSTR lpString;
WORD wSize;
DWORD dwUser1;
DWORD dwUser2;
{
WORD i;
WORD wChMap;
DWORD wNewChunkSize;
SetupWorld();
if( Chunker->CurChunkSize+wSize > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
else if( !Chunker->ChunkFinished )
{
wNewChunkSize = Chunker->CurChunkSize + wSize;
for( i=0; i<wSize; i++ )
{
wChMap = (BYTE) CharMap[(BYTE) lpString[i] ];
if( wChMap > 1 )
{
Chunker->CurChunkSize++;
wNewChunkSize++;
Chunker->dwChunkCountables++;
*CHUNKBUFPTR++ = (BYTE) wChMap;
}
else
{
if( wNewChunkSize+SO_SPECIALCHARSIZE-1 > SO_CHUNK_LIMIT )
{
CHSetupNewChunk( GETHFILTER(dwUser2) );
return;
}
else // Chunk is getting even bigger than we thought.
wNewChunkSize += SO_SPECIALCHARSIZE-1;
Chunker->CurChunkSize += SO_SPECIALCHARSIZE-1;
*CHUNKBUFPTR++ = (BYTE)SO_BEGINTOKEN;
if( wChMap == 1 ) // Unknown characters.
{
*CHUNKBUFPTR++ = SO_SPECIALCHAR;
*CHUNKBUFPTR++ = SO_COUNTBIT;
*CHUNKBUFPTR++ = SO_CHUNKNOWN;
}
else
{
// wCh == 0: This is the convoluted way we map a character
// with the same value as SO_BEGINTOKEN.
*CHUNKBUFPTR++ = SO_CHARX;
*CHUNKBUFPTR++ = SO_COUNTBIT;
*CHUNKBUFPTR++ = (BYTE)SO_BEGINTOKEN;
}
}
}
}
RestoreWorld();
}
#define SO_TAGBEGINSIZE 6
VOID SO_ENTRYMOD SOTagBegin( dwTag, dwUser1, dwUser2 )
DWORD dwTag;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_TAGBEGINSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_TAGBEGIN, dwUser1, dwUser2 );
SOPutDWord( dwTag, dwUser1, dwUser2 );
RestoreWorld();
}
#define SO_TAGENDSIZE 2
VOID SO_ENTRYMOD SOTagEnd( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_TAGENDSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_TAGEND, dwUser1, dwUser2 );
RestoreWorld();
}
#define SO_CHARATTRSIZE 4
VOID SO_ENTRYMOD SOPutCharAttr( wAttr, wState, dwUser1, dwUser2 )
WORD wAttr;
WORD wState;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_CHARATTRSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_CHARATTR, dwUser1, dwUser2 );
SOPutSysChar( (BYTE) wAttr, dwUser1, dwUser2 );
SOPutSysChar( (BYTE) wState, dwUser1, dwUser2 );
RestoreWorld();
}
#define SO_CHARHEIGHTSIZE 4
VOID SO_ENTRYMOD SOPutCharHeight( wHeight, dwUser1, dwUser2 )
WORD wHeight;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_CHARHEIGHTSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_CHARHEIGHT, dwUser1, dwUser2 );
SOPutWord( wHeight, dwUser1, dwUser2 );
RestoreWorld();
}
#define SO_CHARFONTBYIDSIZE 6
VOID SO_ENTRYMOD SOPutCharFontById( dwId, dwUser1, dwUser2 )
DWORD dwId;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_CHARFONTBYIDSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_CHARFONTBYID, dwUser1, dwUser2 );
SOPutDWord( dwId, dwUser1, dwUser2 );
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutCharFontByName( wFontType, lpName, dwUser1, dwUser2 )
WORD wFontType;
LPSTR lpName;
DWORD dwUser1;
DWORD dwUser2;
{
DWORD dwId;
SetupWorld();
if( Chunker->pSection->hFontTable == NULLHANDLE )
SOStartFontTable( dwUser1, dwUser2 );
if( CHAddFontTableEntry( lpName, wFontType, &dwId, dwUser1, dwUser2 ) )
SOPutCharFontById( dwId, dwUser1, dwUser2 );
RestoreWorld();
}
#define SO_GOTOPOSITIONSIZE (sizeof(BYTE)+sizeof(BYTE)+sizeof(SOPAGEPOSITION))
VOID SO_ENTRYMOD SOGoToPosition( pPos, dwUser1, dwUser2 )
PSOPAGEPOSITION pPos;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_GOTOPOSITIONSIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
else if( !Chunker->ChunkFinished )
{
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_GOTOPOSITION, dwUser1, dwUser2 );
CHMemCopy( CHUNKBUFPTR, (LPSTR) pPos, sizeof(SOPAGEPOSITION) );
CHUNKBUFPTR += sizeof(SOPAGEPOSITION);
Chunker->CurChunkSize += sizeof(SOPAGEPOSITION);
}
RestoreWorld();
}
#define SO_DRAWLINESIZE (sizeof(BYTE)+sizeof(BYTE)+sizeof(SOPAGEPOSITION)+sizeof(SOCOLORREF)+sizeof(WORD)+sizeof(DWORD)+sizeof(DWORD))
VOID SO_ENTRYMOD SODrawLine( pPos, Color, wShading, dwWidth, dwHeight, dwUser1, dwUser2 )
PSOPAGEPOSITION pPos;
SOCOLORREF Color;
WORD wShading;
DWORD dwWidth;
DWORD dwHeight;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( Chunker->CurChunkSize+SO_DRAWLINESIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
else if( !Chunker->ChunkFinished )
{
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_DRAWLINE, dwUser1, dwUser2 );
CHMemCopy( CHUNKBUFPTR, (LPSTR) pPos, sizeof(SOPAGEPOSITION) );
CHUNKBUFPTR += sizeof(SOPAGEPOSITION);
Chunker->CurChunkSize += sizeof(SOPAGEPOSITION);
CHMemCopy( CHUNKBUFPTR, (LPSTR) &Color, sizeof(SOCOLORREF) );
CHUNKBUFPTR += sizeof(SOCOLORREF);
Chunker->CurChunkSize += sizeof(SOCOLORREF);
SOPutWord( wShading, dwUser1, dwUser2 );
SOPutDWord( dwWidth, dwUser1, dwUser2 );
SOPutDWord( dwHeight, dwUser1, dwUser2 );
}
RestoreWorld();
}
/*-------------------------------PARAGRAPH TOKENS---------------------------*/
int SOBeginParaAttrToken( TokenSize, TokenID, dwUser1, dwUser2 )
WORD TokenSize;
WORD TokenID;
DWORD dwUser1;
DWORD dwUser2;
{
LPSTR BufPtr;
DWORD ParaSize;
int AttrOffset;
BYTE FAR * src;
BYTE FAR * dest;
AttrOffset = -1;
if( Chunker->CurChunkSize + TokenSize > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
if( !Chunker->ChunkFinished )
{
ParaSize = Chunker->CurChunkSize - (Chunker->Doc.Text.CurParaOffset + Chunker->Doc.Text.AttrSize);
// Point the BufPtr to the beginning of the paragraph.
BufPtr = Chunker->CurChunkBuf + Chunker->Doc.Text.CurParaOffset + Chunker->Doc.Text.AttrSize;
// Shift paragraph to make room for token at beginning of paragraph.
src = BufPtr;
dest = BufPtr+TokenSize;
if (ParaSize != 0) UTmemmove(dest,src,ParaSize);
*BufPtr++ = (BYTE) SO_BEGINTOKEN;
*BufPtr++ = (BYTE) TokenID;
// Store the location of the indent values, so they can be updated if neccessary.
AttrOffset = Chunker->Doc.Text.CurParaOffset + Chunker->Doc.Text.AttrSize + 2;
Chunker->Doc.Text.AttrSize += TokenSize;
CHUNKBUFPTR += TokenSize;
Chunker->CurChunkSize += TokenSize;
}
return( AttrOffset );
}
#define SO_PARAALIGNTOKENSIZE ((2*sizeof(BYTE))+sizeof(WORD))
#define UPDATEPARAALIGN(t) CHMemCopy((LPSTR)(Chunker->CurChunkBuf+Chunker->Doc.Text.AlignOffset),(LPSTR)(WORD FAR *)&t,2)
VOID SO_ENTRYMOD SOUpdateParaAlign( wType, dwUser1, dwUser2 )
WORD wType;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
UPDATEPARAALIGN(wType);
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutParaAlign( wType, dwUser1, dwUser2 )
WORD wType;
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
SetupWorld();
Chunker->Doc.Text.AlignOffset = SOBeginParaAttrToken( SO_PARAALIGNTOKENSIZE, SO_PARAALIGN, dwUser1, dwUser2 );
if( Chunker->Doc.Text.AlignOffset > 0 )
{
UPDATEPARAALIGN(wType);
// Switch the function pointer to the UpdateParaIndents function.
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
(*(pFilter->VwRtns.SetSoRtn))( SOPUTPARAALIGN, SOUpdateParaAlign, pFilter->hProc );
UTGlobalUnlock( GETHFILTER( dwUser2 ));
}
RestoreWorld();
}
#define SO_PARAINDENTTOKENSIZE (2*sizeof(BYTE) + 3*sizeof(DWORD))
VOID CHUpdateParaIndents(dwLeft,dwRight,dwFirst)
DWORD dwLeft;
DWORD dwRight;
DWORD dwFirst;
{
LPSTR IndentValPtr;
// Put the values in the stream. The PutParaBreak function guarantees
// that the pointer will be on a WORD boundary.
IndentValPtr = (LPSTR) (Chunker->CurChunkBuf + Chunker->Doc.Text.IndentOffset);
CHMemCopy( IndentValPtr, (LPSTR) (DWORD FAR *)&dwLeft, 4 );
IndentValPtr += 4;
CHMemCopy( IndentValPtr, (LPSTR) (DWORD FAR *)&dwRight, 4 );
IndentValPtr += 4;
CHMemCopy( IndentValPtr, (LPSTR) (DWORD FAR *)&dwFirst, 4 );
}
VOID SO_ENTRYMOD SOUpdateParaIndents( dwLeft, dwRight, dwFirst, dwUser1, dwUser2 )
DWORD dwLeft;
DWORD dwRight;
DWORD dwFirst;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
CHUpdateParaIndents(dwLeft,dwRight,dwFirst);
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutParaIndents( dwLeft, dwRight, dwFirst, dwUser1, dwUser2 )
DWORD dwLeft;
DWORD dwRight;
DWORD dwFirst;
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
SetupWorld();
Chunker->Doc.Text.IndentOffset = SOBeginParaAttrToken( SO_PARAINDENTTOKENSIZE, SO_PARAINDENT, dwUser1, dwUser2 );
if( Chunker->Doc.Text.IndentOffset > 0 )
{
CHUpdateParaIndents(dwLeft,dwRight,dwFirst);
// Switch the function pointer to the UpdateParaIndents function.
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
(*(pFilter->VwRtns.SetSoRtn))( SOPUTPARAINDENTS, SOUpdateParaIndents, pFilter->hProc );
UTGlobalUnlock( GETHFILTER( dwUser2 ));
}
RestoreWorld();
}
#define SO_PARASPACINGTOKENSIZE (2*sizeof(BYTE) + sizeof(WORD) + 3*sizeof(DWORD))
VOID CHUpdateParaSpacing( wLineHeightType, dwLineHeight, dwSpaceBefore, dwSpaceAfter )
WORD wLineHeightType;
DWORD dwLineHeight;
DWORD dwSpaceBefore;
DWORD dwSpaceAfter;
{
LPSTR SpacingValPtr;
// Put the values in the stream. The PutParaBreak function guarantees
// that the pointer will be on a WORD boundary.
SpacingValPtr = (LPSTR) (Chunker->CurChunkBuf + Chunker->Doc.Text.SpacingOffset);
CHMemCopy( SpacingValPtr, (LPSTR) (WORD FAR *)&wLineHeightType, 2 );
SpacingValPtr += 2;
CHMemCopy( SpacingValPtr, (LPSTR) (DWORD FAR *)&dwLineHeight, 4 );
SpacingValPtr += 4;
CHMemCopy( SpacingValPtr, (LPSTR) (DWORD FAR *)&dwSpaceBefore, 4 );
SpacingValPtr += 4;
CHMemCopy( SpacingValPtr, (LPSTR) (DWORD FAR *)&dwSpaceAfter, 4 );
}
VOID SO_ENTRYMOD SOUpdateParaSpacing( wLineHeightType, dwLineHeight, dwSpaceBefore, dwSpaceAfter, dwUser1, dwUser2 )
WORD wLineHeightType;
DWORD dwLineHeight;
DWORD dwSpaceBefore;
DWORD dwSpaceAfter;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
CHUpdateParaSpacing( wLineHeightType, dwLineHeight, dwSpaceBefore, dwSpaceAfter );
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutParaSpacing( wLineHeightType, dwLineHeight, dwSpaceBefore, dwSpaceAfter, dwUser1, dwUser2 )
WORD wLineHeightType;
DWORD dwLineHeight;
DWORD dwSpaceBefore;
DWORD dwSpaceAfter;
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
SetupWorld();
Chunker->Doc.Text.SpacingOffset = SOBeginParaAttrToken( SO_PARASPACINGTOKENSIZE, SO_PARASPACING, dwUser1, dwUser2 );
if( Chunker->Doc.Text.SpacingOffset > 0 )
{
CHUpdateParaSpacing( wLineHeightType, dwLineHeight, dwSpaceBefore, dwSpaceAfter );
// Switch the function pointer to the UpdateParaSpacing function.
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
(*(pFilter->VwRtns.SetSoRtn))( SOPUTPARASPACING, SOUpdateParaSpacing, pFilter->hProc );
UTGlobalUnlock( GETHFILTER( dwUser2 ));
}
RestoreWorld();
}
#define SO_BEGINTABLESIZE (2*sizeof(BYTE)+sizeof(DWORD))
VOID SO_ENTRYMOD SOBeginTable( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
PSOTABLE pTable;
SetupWorld();
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
pFilter->VwRtns.SetSoRtn( SOBEGINTABLE, NULL, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOPUTTABLEROWFORMAT, SOPutTableRowFormat, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOPUTTABLECELLINFO, SOPutTableCellInfo, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOENDTABLE, SOEndTable, pFilter->hProc );
UTGlobalUnlock( GETHFILTER(dwUser2) );
if( Chunker->CurChunkSize+SO_BEGINTABLESIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
else
{
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_TABLE, dwUser1, dwUser2 );
SOPutDWord( (DWORD)Chunker->Doc.Text.wTablesPresent, dwUser1, dwUser2 );
if( !Chunker->ChunkFinished )
{
if( Chunker->pSection->Attr.Para.hRowInfo == NULLHANDLE )
{
Chunker->Doc.Text.dwRowBufSize = TABLEROWALLOCSIZE;
Chunker->Doc.Text.wTableBufSize = SOTABLESPERALLOC;
Chunker->Doc.Text.dwRowBufCount = 0;
Chunker->Doc.Text.wTablesPresent = 0;
Chunker->Doc.Text.dwPrevRowFormat = 0xffffffff;
Chunker->pSection->Attr.Para.hRowInfo = UTGlobalAlloc( TABLEROWALLOCSIZE );
Chunker->pSection->Attr.Para.hTables = UTGlobalAlloc( sizeof(SOTABLE) * SOTABLESPERALLOC );
if( Chunker->pSection->Attr.Para.hRowInfo == NULLHANDLE ||
Chunker->pSection->Attr.Para.hTables == NULLHANDLE )
{
CHBailOut(SCCCHERR_OUTOFMEMORY);
}
}
else if( Chunker->Doc.Text.wTablesPresent % SOTABLESPERALLOC == 0 )
{
Chunker->pSection->Attr.Para.hTables = CHGlobalRealloc( Chunker->pSection->Attr.Para.hTables,
sizeof(SOTABLE) * Chunker->Doc.Text.wTableBufSize,
sizeof(SOTABLE) * (Chunker->Doc.Text.wTableBufSize+SOTABLESPERALLOC) );
Chunker->Doc.Text.wTableBufSize += SOTABLESPERALLOC;
if( Chunker->pSection->Attr.Para.hTables == NULLHANDLE )
CHBailOut(SCCCHERR_OUTOFMEMORY);
}
Chunker->Doc.Text.dwCurTableId = (DWORD)Chunker->Doc.Text.wTablesPresent++;
pTable = (PSOTABLE)UTGlobalLock(Chunker->pSection->Attr.Para.hTables);
pTable += Chunker->Doc.Text.dwCurTableId;
pTable->dwFirstRowFormat = Chunker->Doc.Text.dwRowBufCount;
pTable->dwFlags = 0L;
UTGlobalUnlock(Chunker->pSection->Attr.Para.hTables);
Chunker->Doc.Text.wCurTableRow = 0;
Chunker->Doc.Text.wCurTableColumn = 0;
// CHResetParaSeek( GETHFILTER(dwUser2) );
CHResetParaAttributeFunctions( (PFILTER)UTGlobalLock(GETHFILTER(dwUser2)) );
UTGlobalUnlock(GETHFILTER(dwUser2));
Chunker->wFlags |= CH_TABLETEXT;
}
}
RestoreWorld();
}
#define SO_ENDTABLESIZE (2*sizeof(BYTE))
VOID SO_ENTRYMOD SOEndTable( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
HPSOTABLEROWFORMAT pRow;
SetupWorld();
if( Chunker->CurChunkSize+SO_ENDTABLESIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_TABLEEND, dwUser1, dwUser2 );
if( !Chunker->ChunkFinished )
{
Chunker->pSection->Attr.Para.wNumTables++;
pRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwRowFormatOffset);
pRow->dwFlags |= SOTABLEROW_END;
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
pFilter->VwRtns.SetSoRtn( SOBEGINTABLE, SOBeginTable, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOPUTTABLEROWFORMAT, NULL, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOPUTTABLECELLINFO, NULL, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOENDTABLE, NULL, pFilter->hProc );
UTGlobalUnlock( GETHFILTER(dwUser2) );
Chunker->wFlags &= ~CH_TABLETEXT;
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOBeginTableAgain( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
HPSOTABLEROWFORMAT pRow;
PFILTER pFilter;
SetupWorld();
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
pFilter->VwRtns.SetSoRtn( SOBEGINTABLE, NULL, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOENDTABLE, SOEndTableAgain, pFilter->hProc );
UTGlobalUnlock( GETHFILTER(dwUser2) );
if( Chunker->CurChunkSize+SO_BEGINTABLESIZE <= SO_CHUNK_LIMIT )
{
pRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwRowFormatOffset );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_TABLE, dwUser1, dwUser2 );
SOPutDWord( Chunker->Doc.Text.dwCurTableId, dwUser1, dwUser2 );
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
Chunker->Doc.Text.wCurTableRow = 0;
Chunker->Doc.Text.wCurTableColumn = 0;
CHResetParaSeek( GETHFILTER(dwUser2) );
CHResetParaAttributeFunctions( (PFILTER)UTGlobalLock(GETHFILTER(dwUser2)) );
UTGlobalUnlock(GETHFILTER(dwUser2));
Chunker->wFlags |= CH_TABLETEXT;
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOEndTableAgain( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
SetupWorld();
if( Chunker->CurChunkSize+SO_ENDTABLESIZE > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
SOPutSysChar( SO_BEGINTOKEN, dwUser1, dwUser2 );
SOPutSysChar( SO_TABLEEND, dwUser1, dwUser2 );
if( !Chunker->ChunkFinished )
{
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
pFilter->VwRtns.SetSoRtn( SOBEGINTABLE, SOBeginTableAgain, pFilter->hProc );
pFilter->VwRtns.SetSoRtn( SOENDTABLE, NULL, pFilter->hProc );
UTGlobalUnlock( GETHFILTER(dwUser2) );
Chunker->Doc.Text.dwCurTableId++;
Chunker->wFlags &= ~CH_TABLETEXT;
}
RestoreWorld();
}
HPSOTABLEROWFORMAT CHLockRowFormat( hBuf, dwOffset )
HANDLE hBuf;
DWORD dwOffset;
{
BYTE HUGE * lpBuf;
lpBuf = (BYTE HUGE *) UTGlobalLock(hBuf);
return( (HPSOTABLEROWFORMAT) (BYTE HUGE *)(lpBuf+dwOffset) );
}
VOID SO_ENTRYMOD SOPutTableRowFormat( lLeftOffset, wHeight, wHeightType, wCellMargin, wRowAlign, wNumCells, dwUser1, dwUser2 )
LONG lLeftOffset;
WORD wHeight;
WORD wHeightType;
WORD wCellMargin;
WORD wRowAlign;
WORD wNumCells;
DWORD dwUser1;
DWORD dwUser2;
{
WORD wFormatSize;
HPSOTABLEROWFORMAT pRow;
SetupWorld();
Chunker->Doc.Text.wCellsFormatted = 0;
Chunker->Doc.Text.wNumTableColumns = wNumCells;
// Test to see if this row has already been formatted. That could happen
// if processing was interrupted to align rows on a chunk boundary, or some
// deal like that.
if( Chunker->Doc.Text.bRowFormatted )
{
RestoreWorld();
return;
}
else
Chunker->Doc.Text.bRowFormatted = TRUE;
wFormatSize = sizeof(SOTABLEROWFORMAT) + wNumCells * sizeof(SOTABLECELLINFO);
if( Chunker->Doc.Text.dwRowBufCount + wFormatSize > Chunker->Doc.Text.dwRowBufSize )
{
DWORD dwOldSize = Chunker->Doc.Text.dwRowBufSize;
BYTE HUGE * pBuf;
Chunker->Doc.Text.dwRowBufSize += max( wFormatSize, TABLEROWALLOCSIZE );
#ifdef WINDOWS
// Prevent a row's format from straddling a segment boundary.
if( Chunker->Doc.Text.dwRowBufSize / 0x00010000 >
Chunker->Doc.Text.dwRowBufCount / 0x00010000 )
{
Chunker->Doc.Text.dwRowBufSize -= Chunker->Doc.Text.dwRowBufSize % 0x00010000;
Chunker->Doc.Text.dwRowBufCount = Chunker->Doc.Text.dwRowBufSize;
Chunker->Doc.Text.dwRowBufSize += wFormatSize;
// Change the previous row's format size.
pRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwRowFormatOffset );
pRow->wFormatSize = (WORD) (Chunker->Doc.Text.dwRowBufCount - Chunker->Doc.Text.dwRowFormatOffset);
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
}
#endif
// We need to expand the table buffer.
Chunker->pSection->Attr.Para.hRowInfo = CHGlobalRealloc( Chunker->pSection->Attr.Para.hRowInfo,
Chunker->Doc.Text.dwRowBufSize, Chunker->Doc.Text.dwRowBufSize );
if( Chunker->pSection->Attr.Para.hRowInfo == NULLHANDLE )
CHBailOut(SCCCHERR_OUTOFMEMORY);
// Zero-init the newly allocated memory.
pBuf = UTGlobalLock(Chunker->pSection->Attr.Para.hRowInfo);
#ifdef MAC
UTmemset(pBuf+dwOldSize, 0, Chunker->Doc.Text.dwRowBufSize-dwOldSize);
#endif
UTGlobalUnlock(Chunker->pSection->Attr.Para.hRowInfo);
}
// Set a flag in the previous row's format.
if( Chunker->Doc.Text.dwRowBufCount )
{
pRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwRowFormatOffset );
pRow->dwFlags |= SOTABLEROW_FORMATFOLLOWS;
if( pRow->wFormatSize == wFormatSize )
Chunker->Doc.Text.dwPrevRowFormat = Chunker->Doc.Text.dwRowFormatOffset;
else
Chunker->Doc.Text.dwPrevRowFormat = 0xffffffff;
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
}
Chunker->Doc.Text.dwRowFormatOffset = Chunker->Doc.Text.dwRowBufCount;
Chunker->Doc.Text.dwRowBufCount += wFormatSize;
pRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwRowFormatOffset);
pRow->lLeftOffset = lLeftOffset;
pRow->wRowHeight = wHeight;
pRow->wRowHeightType = wHeightType;
pRow->wCellMargin = wCellMargin;
pRow->wRowAlignment = wRowAlign;
pRow->wNumRows = 0;
pRow->dwFlags = 0L;
pRow->wFormatSize = wFormatSize;
pRow->wCellsPerRow = wNumCells;
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutTableCellInfo( pCellInfo, dwUser1, dwUser2 )
HPSOTABLECELLINFO pCellInfo;
DWORD dwUser1;
DWORD dwUser2;
{
HPSOTABLEROWFORMAT pRow;
SetupWorld();
if( Chunker->wFlags & CH_LOOKAHEAD )
{
pRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwRowFormatOffset );
pRow->CellFormats[Chunker->Doc.Text.wCellsFormatted++] = *pCellInfo;
if( Chunker->Doc.Text.wCellsFormatted == pRow->wCellsPerRow &&
Chunker->Doc.Text.dwPrevRowFormat != 0xffffffff )
{
HPSOTABLEROWFORMAT pPrevRow;
pPrevRow = CHLockRowFormat( Chunker->pSection->Attr.Para.hRowInfo, Chunker->Doc.Text.dwPrevRowFormat );
if( pPrevRow->wFormatSize == pRow->wFormatSize )
{
// Optimize away identical row formats.
WORD wSaveNumRows = pRow->wNumRows;
// We'll make our comparison easier by making
// some adjustments.
pRow->wNumRows = pPrevRow->wNumRows;
pPrevRow->dwFlags &= ~SOTABLEROW_FORMATFOLLOWS;
if( UTmemcmp(pPrevRow, pRow, pRow->wFormatSize) == 0 )
{
pPrevRow->wNumRows += wSaveNumRows;
UTmemset( (BYTE HUGE *)pRow, 0, pRow->wFormatSize );
Chunker->Doc.Text.dwRowFormatOffset = Chunker->Doc.Text.dwPrevRowFormat;
Chunker->Doc.Text.dwRowBufCount = Chunker->Doc.Text.dwRowFormatOffset + pPrevRow->wFormatSize;
Chunker->Doc.Text.dwPrevRowFormat = 0xffffffff;
}
else
{
pPrevRow->dwFlags |= SOTABLEROW_FORMATFOLLOWS;
pRow->wNumRows = wSaveNumRows;
}
}
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
}
UTGlobalUnlock( Chunker->pSection->Attr.Para.hRowInfo );
}
RestoreWorld();
}
#define SO_PAGEMARGINTOKENSIZE (2*sizeof(BYTE) + 2*sizeof(DWORD))
VOID CHUpdatePageMargins( dwLeft, dwRight )
DWORD dwLeft;
DWORD dwRight;
{
LPSTR MarginValPtr;
// Put the values in the stream. The PutParaBreak function guarantees
// that the pointer will be on a WORD boundary.
MarginValPtr = (LPSTR)(Chunker->CurChunkBuf + Chunker->Doc.Text.MarginOffset);
CHMemCopy( MarginValPtr, (LPSTR) (DWORD FAR *)&dwLeft, 4 );
MarginValPtr += 4;
CHMemCopy( MarginValPtr, (LPSTR) (DWORD FAR *)&dwRight, 4 );
}
VOID SO_ENTRYMOD SOUpdatePageMargins( dwLeft, dwRight, dwUser1, dwUser2 )
DWORD dwLeft;
DWORD dwRight;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
CHUpdatePageMargins(dwLeft,dwRight);
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutMargins( dwLeft, dwRight, dwUser1, dwUser2 )
DWORD dwLeft;
DWORD dwRight;
DWORD dwUser1;
DWORD dwUser2;
{
PFILTER pFilter;
SetupWorld();
Chunker->Doc.Text.MarginOffset = SOBeginParaAttrToken( SO_PAGEMARGINTOKENSIZE, SO_MARGINS, dwUser1, dwUser2 );
if( Chunker->Doc.Text.MarginOffset > 0 )
{
CHUpdatePageMargins(dwLeft,dwRight);
// Switch the function pointer to the UpdateParaIndents function.
pFilter = (PFILTER) UTGlobalLock( GETHFILTER(dwUser2) );
(*(pFilter->VwRtns.SetSoRtn))( SOPUTMARGINS, SOUpdatePageMargins, pFilter->hProc );
UTGlobalUnlock( GETHFILTER( dwUser2 ));
}
RestoreWorld();
}
#define SO_TABSTARTTOKENSIZE (2*sizeof(BYTE) + sizeof(WORD))
VOID SO_ENTRYMOD SOStartTabstops( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
PSOTAB TabArray;
WORD i;
SetupWorld();
Chunker->Doc.Text.NumTabstops = 0;
if( Chunker->Doc.Text.TabstopsOffset == -1 )
{
Chunker->Doc.Text.TabstopsOffset = SOBeginParaAttrToken( SO_TABSTARTTOKENSIZE, SO_TABSTOPS, dwUser1, dwUser2 );
if( Chunker->Doc.Text.TabstopsOffset != -1 )
*((WORD VWPTR *)(Chunker->CurChunkBuf+Chunker->Doc.Text.TabstopsOffset)) = 0;
}
else
{
// Clear out existing tabstops for the paragraph.
TabArray = (PSOTAB) (Chunker->CurChunkBuf + Chunker->Doc.Text.TabstopsOffset + sizeof(WORD));
for( i = 0; i < Chunker->Doc.Text.TabSetSize; i++ )
TabArray[i].wType = SO_TABEMPTY;
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutTabstop( pTab, dwUser1, dwUser2 )
PSOTAB pTab;
DWORD dwUser1;
DWORD dwUser2;
{
PSOTAB TabArray;
DWORD ParaSize;
LPSTR BufPtr;
int i;
BYTE FAR * src;
BYTE FAR * dest;
SetupWorld();
if( Chunker->Doc.Text.NumTabstops < Chunker->Doc.Text.TabSetSize )
{
TabArray = (PSOTAB) (Chunker->CurChunkBuf + Chunker->Doc.Text.TabstopsOffset + sizeof(WORD));
TabArray[ Chunker->Doc.Text.NumTabstops ] = *pTab;
}
else
{
if( Chunker->CurChunkSize + sizeof(SOTAB) > SO_CHUNK_LIMIT )
CHSetupNewChunk( GETHFILTER(dwUser2) );
if( !Chunker->ChunkFinished &&
!(CHUNKTABLE[Chunker->IDCurChunk].Flags & CH_CONTINUATION) )
{
// set i to the offset at the end of the current tab set.
i = Chunker->Doc.Text.TabstopsOffset + sizeof(WORD) + (sizeof(SOTAB)*Chunker->Doc.Text.TabSetSize);
ParaSize = Chunker->CurChunkSize - i;
// Point the BufPtr to the beginning of the paragraph.
BufPtr = Chunker->CurChunkBuf + i;
// Shift paragraph to make room for token at beginning of paragraph.
src = BufPtr;
dest = BufPtr+sizeof(SOTAB);
if (ParaSize != 0) UTmemmove(dest,src,ParaSize);
Chunker->Doc.Text.TabSetSize++;
TabArray = (PSOTAB) (Chunker->CurChunkBuf + Chunker->Doc.Text.TabstopsOffset + sizeof(WORD));
TabArray[ Chunker->Doc.Text.NumTabstops ] = *pTab;
Chunker->Doc.Text.AttrSize += sizeof( SOTAB );
if( Chunker->Doc.Text.MarginOffset != -1 &&
Chunker->Doc.Text.MarginOffset > Chunker->Doc.Text.TabstopsOffset )
{
Chunker->Doc.Text.MarginOffset += sizeof(SOTAB);
}
if( Chunker->Doc.Text.IndentOffset != -1 &&
Chunker->Doc.Text.IndentOffset > Chunker->Doc.Text.TabstopsOffset )
{
Chunker->Doc.Text.IndentOffset += sizeof(SOTAB);
}
if( Chunker->Doc.Text.SpacingOffset != -1 &&
Chunker->Doc.Text.SpacingOffset > Chunker->Doc.Text.TabstopsOffset )
{
Chunker->Doc.Text.SpacingOffset += sizeof(SOTAB);
}
if( Chunker->Doc.Text.AlignOffset != -1 &&
Chunker->Doc.Text.AlignOffset > Chunker->Doc.Text.TabstopsOffset )
{
Chunker->Doc.Text.AlignOffset += sizeof(SOTAB);
}
Chunker->CurChunkSize += sizeof( SOTAB );
CHUNKBUFPTR += sizeof( SOTAB );
*((WORD VWPTR *)(Chunker->CurChunkBuf+Chunker->Doc.Text.TabstopsOffset)) = Chunker->Doc.Text.TabSetSize;
}
else
{
RestoreWorld();
return;
}
}
// Update tabstop count.
Chunker->Doc.Text.NumTabstops++;
RestoreWorld();
}
VOID SO_ENTRYMOD SOEndTabstops( dwUser1, dwUser2 )
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
RestoreWorld();
}
VOID CHUpdateParagraphFunctions( wStatus, hFilter )
WORD wStatus;
HFILTER hFilter;
{
PFILTER pFilter;
#ifdef OS2
void (* VW_ENTRYMOD SetSoRtn)(SHORT, VOID (* SO_ENTRYMOD)(), HPROC);
#else
void (VW_ENTRYMOD * SetSoRtn)(SHORT, VOID (SO_ENTRYMOD *)(), HPROC);
#endif
HPROC hProc;
pFilter = (PFILTER) UTGlobalLock( hFilter );
SetSoRtn = pFilter->VwRtns.SetSoRtn;
hProc = pFilter->hProc;
if( wStatus == CH_ACTIVE )
{
(*(SetSoRtn))( SOPUTCHAR, SOPutChar, hProc );
(*(SetSoRtn))( SOPUTCHARX, SOPutCharX, hProc );
(*(SetSoRtn))( SOPUTSPECIALCHARX, SOPutSpecialCharX, hProc );
(*(SetSoRtn))( SOPUTSTRING, SOPutString, hProc );
(*(SetSoRtn))( SOPUTCHARATTR, SOPutCharAttr, hProc );
(*(SetSoRtn))( SOPUTCHARHEIGHT, SOPutCharHeight, hProc );
(*(SetSoRtn))( SOPUTMARGINS, SOPutMargins, hProc );
(*(SetSoRtn))( SOPUTPARAINDENTS, SOPutParaIndents, hProc );
(*(SetSoRtn))( SOPUTPARAALIGN, SOPutParaAlign, hProc );
(*(SetSoRtn))( SOPUTBREAK, (SOFUNCPTR)SOPutBreak, hProc );
(*(SetSoRtn))( SOSTARTTABSTOPS, SOStartTabstops, hProc );
(*(SetSoRtn))( SOPUTTABSTOP, SOPutTabstop, hProc );
(*(SetSoRtn))( SOENDTABSTOPS, SOEndTabstops, hProc );
(*(SetSoRtn))( SOPUTSUBDOCINFO, NULL, hProc );
(*(SetSoRtn))( SOTAGBEGIN, SOTagBegin, hProc );
(*(SetSoRtn))( SOTAGEND, SOTagEnd, hProc );
(*(SetSoRtn))( SOPUTCHARFONTBYID, SOPutCharFontById, hProc );
(*(SetSoRtn))( SOPUTCHARFONTBYNAME, SOPutCharFontByName, hProc );
(*(SetSoRtn))( SOPUTPARASPACING, SOPutParaSpacing, hProc );
(*(SetSoRtn))( SOGOTOPOSITION, SOGoToPosition, hProc );
(*(SetSoRtn))( SODRAWLINE, SODrawLine, hProc );
if( Chunker->wFlags & CH_TABLETEXT )
{
(*(SetSoRtn))( SOBEGINTABLE, NULL, hProc );
if( Chunker->wFlags & CH_LOOKAHEAD )
{
(*(SetSoRtn))( SOENDTABLE, SOEndTable, hProc );
(*(SetSoRtn))( SOPUTTABLEROWFORMAT, SOPutTableRowFormat, hProc );
(*(SetSoRtn))( SOPUTTABLECELLINFO, SOPutTableCellInfo, hProc );
}
else
{
(*(SetSoRtn))( SOENDTABLE, SOEndTableAgain, hProc );
(*(SetSoRtn))( SOPUTTABLEROWFORMAT, NULL, hProc );
(*(SetSoRtn))( SOPUTTABLECELLINFO, NULL, hProc );
}
}
else
{
if( Chunker->wFlags & CH_LOOKAHEAD )
(*(SetSoRtn))( SOBEGINTABLE, SOBeginTable, hProc );
else
(*(SetSoRtn))( SOBEGINTABLE, SOBeginTableAgain, hProc );
(*(SetSoRtn))( SOENDTABLE, NULL, hProc );
(*(SetSoRtn))( SOPUTTABLEROWFORMAT, NULL, hProc );
(*(SetSoRtn))( SOPUTTABLECELLINFO, NULL, hProc );
}
(*(SetSoRtn))( SOPUTGRAPHICOBJECT, SOPutGraphicObject, hProc );
}
else
{
(*(SetSoRtn))( SOPUTCHAR, NULL, hProc );
(*(SetSoRtn))( SOPUTCHARX, NULL, hProc );
(*(SetSoRtn))( SOPUTSPECIALCHARX, NULL, hProc );
(*(SetSoRtn))( SOPUTSTRING, NULL, hProc );
(*(SetSoRtn))( SOPUTCHARATTR, NULL, hProc );
(*(SetSoRtn))( SOPUTCHARHEIGHT, NULL, hProc );
(*(SetSoRtn))( SOPUTMARGINS, NULL, hProc );
(*(SetSoRtn))( SOPUTPARAINDENTS, NULL, hProc );
(*(SetSoRtn))( SOPUTPARAALIGN, NULL, hProc );
(*(SetSoRtn))( SOPUTBREAK, NULL, hProc );
(*(SetSoRtn))( SOSTARTTABSTOPS, NULL, hProc );
(*(SetSoRtn))( SOPUTTABSTOP, NULL, hProc );
(*(SetSoRtn))( SOENDTABSTOPS, NULL, hProc );
(*(SetSoRtn))( SOPUTSUBDOCINFO, NULL, hProc );
(*(SetSoRtn))( SOTAGBEGIN, NULL, hProc );
(*(SetSoRtn))( SOTAGEND, NULL, hProc );
(*(SetSoRtn))( SOPUTCHARFONTBYID, NULL, hProc );
(*(SetSoRtn))( SOPUTCHARFONTBYNAME, NULL, hProc );
(*(SetSoRtn))( SOPUTPARASPACING, NULL, hProc );
(*(SetSoRtn))( SOBEGINTABLE, NULL, hProc );
(*(SetSoRtn))( SOENDTABLE, NULL, hProc );
(*(SetSoRtn))( SOPUTTABLEROWFORMAT, NULL, hProc );
(*(SetSoRtn))( SOPUTTABLECELLINFO, NULL, hProc );
(*(SetSoRtn))( SOPUTGRAPHICOBJECT, NULL, hProc );
(*(SetSoRtn))( SOGOTOPOSITION, NULL, hProc );
(*(SetSoRtn))( SODRAWLINE, NULL, hProc );
}
UTGlobalUnlock( hFilter );
}
VOID EDDeleteUntil( dwDesiredCountable, hFilter )
DWORD dwDesiredCountable;
HFILTER hFilter;
{
Chunker->dwDesiredCountable = dwDesiredCountable;
Chunker->wDelCharHeight = 0;
Chunker->wDelCharAttrOn = 0;
Chunker->wDelCharAttrOff = 0;
Chunker->wFlags |= CH_SKIPTEXT;
CHSetDeletionFunctions( hFilter );
}
VOID CHSetDeletionFunctions( hFilter )
HFILTER hFilter;
{
PFILTER pFilter;
#ifdef OS2
void (* VW_ENTRYMOD SetSoRtn)(SHORT, VOID (* SO_ENTRYMOD)(), HPROC);
#else
void (VW_ENTRYMOD * SetSoRtn)(SHORT, VOID (SO_ENTRYMOD *)(), HPROC);
#endif
pFilter = (PFILTER) UTGlobalLock( hFilter );
SetSoRtn = pFilter->VwRtns.SetSoRtn;
SetSoRtn( SOPUTCHAR, SOPutDeletedChar, pFilter->hProc );
SetSoRtn( SOPUTCHARX, SOPutDeletedCharX, pFilter->hProc );
SetSoRtn( SOPUTSPECIALCHARX, SOPutDeletedCharX, pFilter->hProc );
// SetSoRtn( SOPUTSTRING, SOPutDeletedString, hProc );
SetSoRtn( SOPUTCHARHEIGHT, SOPutDeletedCharHeight, pFilter->hProc );
SetSoRtn( SOPUTCHARATTR, SOPutDeletedCharAttr, pFilter->hProc );
SetSoRtn( SOPUTBREAK, (SOFUNCPTR)SOPutDeletedBreak, pFilter->hProc );
// If we were still maintaining the editor code, then I would write
// PutDeletedCharFont functions, but right now I see no need...
SetSoRtn( SOPUTCHARFONTBYID, NULL, pFilter->hProc );
SetSoRtn( SOPUTCHARFONTBYNAME, NULL, pFilter->hProc );
SetSoRtn( SOGOTOPOSITION, NULL, pFilter->hProc );
SetSoRtn( SODRAWLINE, NULL, pFilter->hProc );
SetSoRtn( SOTAGBEGIN, NULL, pFilter->hProc );
SetSoRtn( SOTAGEND, NULL, pFilter->hProc );
UTGlobalUnlock( hFilter );
}
WORD EDLeaveDeletion( hFilter )
HFILTER hFilter;
{
PFILTER pFilter;
WORD UpdateAttr = TRUE;
WORD Ret=0;
#ifdef OS2
void (* VW_ENTRYMOD SetSoRtn)(SHORT, VOID (* SO_ENTRYMOD)(), HPROC);
#else
void (VW_ENTRYMOD * SetSoRtn)(SHORT, VOID (SO_ENTRYMOD *)(), HPROC);
#endif
pFilter = (PFILTER) UTGlobalLock( hFilter );
SetSoRtn = pFilter->VwRtns.SetSoRtn;
SetSoRtn( SOPUTCHAR, SOPutChar, pFilter->hProc );
SetSoRtn( SOPUTCHARX, SOPutCharX, pFilter->hProc );
SetSoRtn( SOPUTSPECIALCHARX, SOPutSpecialCharX, pFilter->hProc );
SetSoRtn( SOPUTSTRING, SOPutString, pFilter->hProc );
SetSoRtn( SOPUTCHARHEIGHT, SOPutCharHeight, pFilter->hProc );
SetSoRtn( SOPUTCHARATTR, SOPutCharAttr, pFilter->hProc );
SetSoRtn( SOPUTBREAK, (SOFUNCPTR)SOPutBreak, pFilter->hProc );
SetSoRtn( SOTAGBEGIN, SOTagBegin, pFilter->hProc );
SetSoRtn( SOTAGEND, SOTagEnd, pFilter->hProc );
SetSoRtn( SOPUTCHARFONTBYID, SOPutCharFontById, pFilter->hProc );
SetSoRtn( SOPUTCHARFONTBYNAME, SOPutCharFontByName, pFilter->hProc );
SetSoRtn( SOGOTOPOSITION, SOGoToPosition, pFilter->hProc );
SetSoRtn( SODRAWLINE, SODrawLine, pFilter->hProc );
UTGlobalUnlock( hFilter );
Chunker->wFlags &= ~(CH_SKIPTEXT & CH_NOPARAATTR);
return Ret;
}
VOID CHResetParaSeek( hFilter )
HFILTER hFilter;
{
// Save seek spot information as a possible chunk boundary.
SSMark(hFilter);
// Store the new paragraph's start position.
Chunker->Doc.Text.dwParaCountableOffset = Chunker->dwChunkCountables;
Chunker->Doc.Text.CurParaOffset = (SHORT)Chunker->CurChunkSize;
Chunker->Doc.Text.wParaBreakOffset = (WORD)Chunker->CurChunkSize;
}
void CHResetParaAttributeFunctions( pFilter )
PFILTER pFilter;
{
#ifdef OS2
void (* VW_ENTRYMOD SetSoRtn)(SHORT, VOID (* SO_ENTRYMOD)(), HPROC);
#else
void (VW_ENTRYMOD * SetSoRtn)(SHORT, VOID (SO_ENTRYMOD *)(), HPROC);
#endif
SetSoRtn = pFilter->VwRtns.SetSoRtn;
Chunker->Doc.Text.CurParaOffset = (SHORT)Chunker->CurChunkSize;
Chunker->Doc.Text.AttrSize = 0;
Chunker->Doc.Text.MarginOffset = -1;
Chunker->Doc.Text.IndentOffset = -1;
Chunker->Doc.Text.SpacingOffset = -1;
Chunker->Doc.Text.AlignOffset = -1;
Chunker->Doc.Text.TabstopsOffset = -1;
Chunker->Doc.Text.NumTabstops = 0;
Chunker->Doc.Text.TabSetSize = 0;
(*SetSoRtn)( SOPUTMARGINS, SOPutMargins, pFilter->hProc );
(*SetSoRtn)( SOPUTPARAINDENTS, SOPutParaIndents, pFilter->hProc );
(*SetSoRtn)( SOPUTPARASPACING, SOPutParaSpacing, pFilter->hProc );
(*SetSoRtn)( SOPUTPARAALIGN, SOPutParaAlign, pFilter->hProc );
(*SetSoRtn)( SOSTARTTABSTOPS, SOStartTabstops, pFilter->hProc );
(*SetSoRtn)( SOPUTTABSTOP, SOPutTabstop, pFilter->hProc );
}
VOID CHSetContinuationFunctions( hFilter )
HFILTER hFilter;
{
PFILTER pFilter;
#ifdef OS2
void (* VW_ENTRYMOD SetSoRtn)(SHORT, VOID (* SO_ENTRYMOD)(), HPROC);
#else
void (VW_ENTRYMOD * SetSoRtn)(SHORT, VOID (SO_ENTRYMOD *)(), HPROC);
#endif
Chunker->Doc.Text.CurParaOffset = 0;
pFilter = (PFILTER) UTGlobalLock( hFilter );
SetSoRtn = pFilter->VwRtns.SetSoRtn;
SetSoRtn( SOPUTMARGINS, NULL, pFilter->hProc );
SetSoRtn( SOPUTPARAINDENTS, NULL, pFilter->hProc );
SetSoRtn( SOPUTPARASPACING, NULL, pFilter->hProc );
SetSoRtn( SOPUTPARAALIGN, NULL, pFilter->hProc );
SetSoRtn( SOSTARTTABSTOPS, NULL, pFilter->hProc );
SetSoRtn( SOPUTTABSTOP, NULL, pFilter->hProc );
UTGlobalUnlock( hFilter );
}
BOOL CHHandleParaChunkBoundary( pCurChunk, pNextChunk, hFilter )
PCHUNK pCurChunk;
PCHUNK pNextChunk;
HFILTER hFilter;
{
BOOL ret = TRUE;
DWORD dwTotalCountables;
// The chunk has been read for the first time.
if( Chunker->Doc.Text.wParaBreakOffset == 0 )
{
// There are no paragraph breaks in the chunk. The next chunk
// will be a continuation chunk.
// Add the end-of-chunk token.
*CHUNKBUFPTR++ = (BYTE)SO_BEGINTOKEN;
*CHUNKBUFPTR++ = (BYTE)SO_ENDOFCHUNK;
// The end-of-chunk token is NOT included in the chunk size.
pCurChunk->Info.Text.Size = (SHORT)Chunker->CurChunkSize;
// Mark the next chunk as a continuation chunk.
pNextChunk->Flags |= (CH_CONTINUATION | CH_WRAPINVALID);
pNextChunk->SeekID = pCurChunk->SeekID;
pNextChunk->Info.Text.dwSeekCountableOffset = pCurChunk->Info.Text.dwSeekCountableOffset;
dwTotalCountables = Chunker->dwChunkCountables;
// 3-1-93:
// We're going to keep going, so that we don't have to
// break out of our call to VwStreamRead.
// Store the current chunk in the ChunksInMemory array.
UTGlobalUnlock( Chunker->LookAheadChunk.hMem );
CHStoreChunkInMemory( &(Chunker->LookAheadChunk) );
if( Chunker->LookAheadChunk.dwSize != SO_CHUNK_SIZE )
{
UTGlobalFree( Chunker->LookAheadChunk.hMem );
Chunker->LookAheadChunk.hMem = NULLHANDLE;
}
if( Chunker->LookAheadChunk.hMem == NULLHANDLE )
{
Chunker->LookAheadChunk.hMem = UTGlobalAlloc( SO_CHUNK_SIZE);
Chunker->LookAheadChunk.dwSize = SO_CHUNK_SIZE;
if( Chunker->LookAheadChunk.hMem == NULLHANDLE )
CHBailOut(SCCCHERR_OUTOFMEMORY);
}
Chunker->LookAheadChunk.IDSection = Chunker->IDCurSection;
ret = FALSE;
Chunker->CurChunkBuf = CHUNKBUFPTR = (LPSTR) UTGlobalLock( Chunker->LookAheadChunk.hMem );
Chunker->IDCurChunk = Chunker->LookAheadChunk.IDChunk = Chunker->IDCurChunk+1;
CHUNKTABLE[Chunker->IDCurChunk].dwSize = SO_CHUNK_SIZE;
Chunker->CurChunkSize = 0;
CHSetContinuationFunctions( hFilter );
}
else
{
// Add the end-of-chunk token.
CHUNKBUFPTR = Chunker->CurChunkBuf + Chunker->Doc.Text.wParaBreakOffset;
*CHUNKBUFPTR++ = (BYTE)SO_BEGINTOKEN;
*CHUNKBUFPTR++ = (BYTE)SO_ENDOFCHUNK;
// The end-of-chunk token is NOT included in the chunk size.
pCurChunk->Info.Text.Size = Chunker->Doc.Text.wParaBreakOffset;
// Save the seek data for the next chunk.
SSSave( &(pNextChunk->SeekID), hFilter );
pNextChunk->Flags &= ~CH_CONTINUATION;
Chunker->Doc.Text.wCurTableColumn = 0; // Matters if we're in the middle of a table
dwTotalCountables = Chunker->Doc.Text.dwParaCountableOffset;
pNextChunk->Info.Text.dwSeekCountableOffset = dwTotalCountables;
}
// Initialize chunk variables.
pNextChunk->Info.Text.Size = 0;
pNextChunk->Info.Text.NumLines = 0;
pNextChunk->Info.Text.dwFirstGraphic = Chunker->Doc.Text.dwCurGraphicId;
if( Chunker->wFlags & CH_TABLETEXT )
{
pNextChunk->Flags |= CH_STARTSINTABLE;
pNextChunk->Info.Text.dwTableId = Chunker->Doc.Text.dwCurTableId;
pNextChunk->Info.Text.wTableRow = Chunker->Doc.Text.wCurTableRow;
pNextChunk->Info.Text.wTableCol = Chunker->Doc.Text.wCurTableColumn;
if( Chunker->Doc.Text.wCurTableRow > 0 )
{
if( Chunker->Doc.Text.bRowFormatted )
pCurChunk->Flags |= CH_TOPROWFORMATTED;
}
else
{
if( Chunker->Doc.Text.bRowFormatted )
pNextChunk->Flags |= CH_TOPROWFORMATTED;
}
}
else
pNextChunk->Info.Text.dwTableId = Chunker->Doc.Text.wTablesPresent;
pNextChunk->Info.Text.dwCountableOffset = dwTotalCountables;
pCurChunk->Info.Text.dwEndOfCountables = dwTotalCountables;
return ret;
}
VOID SO_ENTRYMOD SOPutDeletedChar( wCh, dwUser1, dwUser2 )
WORD wCh;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
Chunker->dwChunkCountables++;
if( Chunker->dwChunkCountables == Chunker->dwDesiredCountable )
{
EDLeaveDeletion( GETHFILTER(dwUser2) );
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutDeletedCharX( wCh, wType, dwUser1, dwUser2 )
WORD wCh;
WORD wType;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
if( !Chunker->ChunkFinished && (wType & SO_COUNTBIT) )
{
Chunker->dwChunkCountables++;
if( Chunker->dwChunkCountables == Chunker->dwDesiredCountable )
{
EDLeaveDeletion( GETHFILTER(dwUser2) );
}
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutDeletedCharAttr( wAttr, wState, dwUser1, dwUser2 )
WORD wAttr;
WORD wState;
DWORD dwUser1;
DWORD dwUser2;
{
WORD AttrBit;
SetupWorld();
// This requires that the value of wAttr is <= 15.
AttrBit = (WORD) (1 << wAttr);
if( wState == SO_ON )
{
if( Chunker->wDelCharAttrOff & AttrBit )
Chunker->wDelCharAttrOff &= ~AttrBit;
else
Chunker->wDelCharAttrOn |= AttrBit;
}
else
{
if( Chunker->wDelCharAttrOn & AttrBit )
Chunker->wDelCharAttrOn &= ~AttrBit;
else
Chunker->wDelCharAttrOff |= AttrBit;
}
RestoreWorld();
}
VOID SO_ENTRYMOD SOPutDeletedCharHeight( wHeight, dwUser1, dwUser2 )
WORD wHeight;
DWORD dwUser1;
DWORD dwUser2;
{
SetupWorld();
Chunker->wDelCharHeight = wHeight;
RestoreWorld();
}