#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(); }