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.
 
 
 
 
 
 

280 lines
6.7 KiB

/*****************************************************************************
* *
* TABLE.C *
* *
* Copyright (C) Microsoft Corporation 1990. *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* *
* This module compiles tables into side by side paragraph structures. *
* Eventually, it will also handle side by side paragraphs, and full *
* table support. *
* *
*****************************************************************************/
#include "stdafx.h"
#pragma hdrstop
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/***************************************************************************
*
- Name: StartTable
-
* Purpose:
* Starts table processing
*
* Arguments:
* ptbl: Pointer to table information.
*
* Returns:
* nothing.
*
* Globals:
* This function uses the global wTextBufChCount to determine
* whether or not to output the previous FCP. This way, tables
* can occur at the very top of a topic (but only if they are
* at the beginning of the RTF file.)
*
* +++
*
* Notes:
*
***************************************************************************/
void STDCALL StartTable(void)
{
if (tbl.tbs == tbsOff) {
// Get rid of old FCP and start table processing
if (wTextBufChCount) { // REVIEW (see Globals: comment above)
VOutFCP(FALSE);
pfInt = pfCur;
VSaveTabTable();
}
tbl.tbs = tbsOn;
tbl.wParaCmdBegin = 0;
tbl.wParaTextBegin = 0;
tbl.wParaTextCompBegin = 0;
tbl.wObjrgTotal = 0;
tbl.iCell = 0;
}
}
/***************************************************************************
*
- Name: RcEndTable
-
* Purpose:
* Finishes table processing on the given row, and outputs the entire
* table FCP in side by side format.
*
* Arguments:
* ptbl: Pointer to table information.
*
* Returns:
* return code from RcCopyPbfQcb, or RC_Failure if tables were not
* turned on from the \intbl command.
*
* Globals:
* pbfCommand, all VOutFCP stuff.
*
* +++
*
* Notes:
*
***************************************************************************/
RC_TYPE STDCALL RcEndTable(void)
{
INT16 iT = iColumnNil;
ASSERT(tbl.tbs == tbsOn);
if (tbl.tbs != tbsOn)
return RC_Failure;
// Remove all text and commands since last valid FCP:
pbfCommand->SetSize(tbl.wParaCmdBegin);
pbfText->SetSize(tbl.wParaTextCompBegin);
if (!pbfCommand->Add(&iT, sizeof(INT16)))
OOM();
tbl.tbs = tbsFinish;
VOutFCP(FALSE);
tbl.tbs = tbsOff;
return RC_Success;
}
/***************************************************************************
*
- Name: RcAddFcpPtbl
-
* Purpose:
* Puts a paragraph object into the command table for a table FCP.
*
* Arguments:
* ptbl: Pointer to table information
*
* Returns:
* General purpose return code. RC_Failure if tables were not turned on.
*
* Globals:
*
* +++
*
* Notes:
*
***************************************************************************/
RC_TYPE STDCALL RcAddFcpPtbl(void)
{
MOBJ mobj;
MOPG mopg;
ASSERT(tbl.tbs == tbsOn);
if (tbl.tbs != tbsOn)
return RC_Failure;
// prepare object header
mobj.bType = (BYTE) FCTYPE_PARAGROUP;
#ifdef MAGIC
mobj.bMagic = bMagicMOBJ;
#endif
// Fill the paragroup object and get the compressed size
VSetParaGroupObject(&mopg);
mopg.libText = tbl.wParaTextBegin; // do correction
// compress the group object
void* qcopgT = szScratchBuf + sizeof(INT16) + sizeof(MOBJ);
int cbCOPG = CbPackMOPG(&mopg, qcopgT);
int cbNewCommands = pbfCommand->GetSize() - tbl.wParaCmdBegin;
mobj.lcbSize = cbCOPG + cbNewCommands;
/*
* Object regions in the current object equals total in this fcp minus
* total already output in this fcp.
*/
mobj.wObjInfo = adrs.wObjrg - tbl.wObjrgTotal;
tbl.wObjrgTotal = adrs.wObjrg;
// pack the object header
int cbCOBJ = CbPackMOBJ(&mobj, szScratchBuf + sizeof(INT16));
memmove(szScratchBuf + sizeof(INT16) + cbCOBJ, qcopgT, cbCOPG);
*(INT16 *) szScratchBuf = tbl.iCell;
int cbInsert = cbCOPG + cbCOBJ + sizeof(INT16);
/* REVIEW:
* We now need to insert the data in szScratchBuf before the new
* commands that we have just been adding to the command buffer. What we
* really need here is a side-by-side buffer to copy everything to.
*/
// Expand the buffer:
if (pbfCommand->Add(szScratchBuf, cbInsert)) {
PBYTE qbCmd = pbfCommand->pbMem;
memmove(qbCmd + tbl.wParaCmdBegin + cbInsert,
qbCmd + tbl.wParaCmdBegin, cbNewCommands);
memcpy(qbCmd + tbl.wParaCmdBegin, szScratchBuf, cbInsert);
tbl.wParaCmdBegin = pbfCommand->GetSize();
tbl.wParaTextCompBegin = pbfText->GetSize();
tbl.wParaTextBegin = wTextBufChCount;
return RC_Success;
}
else
return RC_OutOfMemory;
}
/***************************************************************************
*
- Name: CbSetTableHeader
-
* Purpose:
* Fills out a buffer with the header information for a table FCP.
*
* Arguments:
* qv: A pointer to the buffer.
* ptbl: Pointer to table information.
*
* Returns:
* Number of bytes copied to the buffer.
*
* Globals:
*
* +++
*
* Notes:
* This function needs a better mechanism to avoid buffer overflow.
* Currently, the buffer does not overflow because there is a limit
* to the number of columns a table can have, and hence to the size
* of the header information.
*
***************************************************************************/
int STDCALL CbSetTableHeader(void* pv)
{
MCOL* pmcol;
UINT iCell;
HP hpTotal;
WORD* pi;
MSBS* pmsbs = (MSBS*) pv;
pmsbs->bcCol = (BYTE) tbl.cCell;
pmsbs -> fAbsolute = (BYTE) tbl.fAbsolute;
ASSERT(tbl.cCell > 0);
if (!tbl.fAbsolute) {
pi = (WORD*) (pmsbs + 1);
hpTotal = tbl.rghpCellx[tbl.cCell-1];
*pi = hpTotal;
pmcol = (MCOL*) (pi + 1);
}
else
pmcol = (MCOL*) (pmsbs + 1);
pmcol->xWidthSpace = MAX(0, tbl.hpLeft + tbl.hpSpace);
pmcol->xWidthColumn = MAX(1,
tbl.rghpCellx[0] - pmcol->xWidthSpace - (tbl.hpSpace / 2));
++pmcol;
for (iCell = 1; iCell < tbl.cCell; ++iCell, ++pmcol) {
pmcol->xWidthSpace = tbl.hpSpace;
pmcol->xWidthColumn = MAX(1,
tbl.rghpCellx[iCell] - tbl.rghpCellx[iCell - 1] - tbl.hpSpace);
}
if (!tbl.fAbsolute) {
pi = (WORD*) (pmsbs + 1);
pmcol = (MCOL*) (pi + 1);
for (iCell = 0; iCell < tbl.cCell; ++iCell, ++pmcol) {
int savewidth = pmcol->xWidthSpace;
pmcol->xWidthSpace = (WORD)
(DWORD) pmcol->xWidthSpace * 0x7FFF / hpTotal;
pmcol->xWidthColumn = (WORD)
(DWORD) pmcol->xWidthColumn * 0x7FFF / hpTotal;
}
}
return ((PBYTE) pmcol - (PBYTE) pv);
}