|
|
#include "lsmem.h"
#include "lstxtini.h"
#include "zqfromza.h"
#include "lscbk.h"
#include "lsdocinf.h"
#include "tlpr.h"
#include "txtils.h"
#include "txtln.h"
#include "txtobj.h"
#include "txtconst.h"
#define min(a,b) ((a) > (b) ? (b) : (a))
#define TxtVisiMask (fTxtVisiCondHyphens | fTxtVisiParaMarks | fTxtVisiSpaces | fTxtVisiTabs | fTxtVisiBreaks)
/* Internal Functions Prototypes */ static void DestroyLNObjTextCore(PLNOBJ plnobj); static LSERR ErrorLNObjText(PLNOBJ* plnobj, LSERR lserr); static LSERR TxtAddSpec(PILSOBJ pilsobj, WCHAR wchSymbol, CLABEL clab, WCHAR wchUndef); static LSERR TxtSortSpec(WCHAR* rgwchSpec, CLABEL* rgbKind, DWORD cwchSpec); static void CkeckModWidthClasses(PILSOBJ pilsobj, DWORD cModWidthClasses);
/* Export Functions Implementation*/
/* D E S T R O Y I L S O B J T E X T */ /*----------------------------------------------------------------------------
%%Function: DestroyILSObjText %%Contact: sergeyge
Deallocates list of arrays of txtobj's Deallocates arrays anchored to ILSOBJ
Deallocates text ilsobj ----------------------------------------------------------------------------*/ LSERR WINAPI DestroyILSObjText(PILSOBJ pilsobj) { if (pilsobj != NULL) {
if ( pilsobj->pwchOrig != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pwchOrig); pilsobj->pwchOrig = NULL; } if ( pilsobj->pdur != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pdur); pilsobj->pdur = NULL; } if ( pilsobj->pdurLeft != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pdurLeft); pilsobj->pdurLeft = NULL; } if ( pilsobj->pdurRight != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pdurRight); pilsobj->pdurRight = NULL; } if ( pilsobj->pduAdjust != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pduAdjust); pilsobj->pduAdjust = NULL; } if ( pilsobj->ptxtinf != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->ptxtinf); pilsobj->ptxtinf = NULL; } if ( pilsobj->pdurGind != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pdurGind); pilsobj->pdurGind = NULL; } if ( pilsobj->pginf != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pginf); pilsobj->pginf = NULL; } if ( pilsobj->pduGright != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pduGright); pilsobj->pduGright = NULL; } if ( pilsobj->plsexpinf != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plsexpinf); pilsobj->plsexpinf = NULL; } if ( pilsobj->pwSpaces != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pwSpaces); pilsobj->pwSpaces = NULL; }
if ( pilsobj->plspairact != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plspairact); pilsobj->plspairact = NULL; } if ( pilsobj->pilspairact != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilspairact); pilsobj->pilspairact = NULL; }
if ( pilsobj->plspract != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plspract); pilsobj->plspract = NULL; } if ( pilsobj->pilspract != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilspract); pilsobj->pilspract = NULL; }
if ( pilsobj->plsexpan != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plsexpan); pilsobj->plsexpan = NULL; } if ( pilsobj->pilsexpan != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilsexpan); pilsobj->pilsexpan = NULL; }
if ( pilsobj->plsbrk != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plsbrk); pilsobj->plsbrk = NULL; } if ( pilsobj->pilsbrk != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilsbrk); pilsobj->pilsbrk = NULL; }
if ( pilsobj->plnobj != NULL ) { DestroyLNObjTextCore(pilsobj->plnobj); pilsobj->plnobj = NULL; }
if (pilsobj->pbreakinf != NULL); { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pbreakinf); pilsobj->pbreakinf = NULL; }
(*pilsobj->plscbk->pfnDisposePtr) (pilsobj->pols, pilsobj);
}
return lserrNone; }
/* C R E A T E I L S O B J T E X T */ /*----------------------------------------------------------------------------
%%Function: CreateILSObjText %%Contact: sergeyge
Allocates text ilsobj and sets pols, plsc and call-backs in it Allocates first array of the list of arrays of txtobj's Allocates wchOrig/dur arrays. Other arrays will be allocated when needed. ----------------------------------------------------------------------------*/ LSERR WINAPI CreateILSObjText(POLS pols, PCLSC plsc, PCLSCBK plscbk, DWORD idobj, PILSOBJ* ppilsobj) { PILSOBJ ptxtils;
Unreferenced(idobj);
*ppilsobj = NULL; ptxtils = (*plscbk->pfnNewPtr)(pols, sizeof(struct ilsobj));
if (ptxtils == NULL) return lserrOutOfMemory;
*ppilsobj = ptxtils;
memset(ptxtils, 0, sizeof(struct ilsobj) );
ptxtils->pols = pols; ptxtils->plsc = (PLSC)plsc;
ptxtils->plscbk = plscbk;
return lserrNone; }
/* D E S T R O Y L N O B J T E X T */ /*----------------------------------------------------------------------------
%%Function: DestroyLNObjText %%Contact: sergeyge
Deallocates arrays anchored to LNOBJ
Deallocates text lnobj ----------------------------------------------------------------------------*/ LSERR WINAPI DestroyLNObjText(PLNOBJ plnobj) { if (plnobj->pilsobj->plnobj == NULL) { plnobj->pilsobj->plnobj = plnobj; }
else if (plnobj != NULL) { DestroyLNObjTextCore(plnobj); }
return lserrNone; }
/* C R E A T E L N O B J T E X T */ /*----------------------------------------------------------------------------
%%Function: CreateLNObjText %%Contact: sergeyge
Allocates text lnobj Allocates wch/dup arrays. dupPenAllocArray will be allocated when needed. ----------------------------------------------------------------------------*/ LSERR WINAPI CreateLNObjText(PCILSOBJ pilsobj, PLNOBJ* pplnobj) { PLNOBJ ptxtln;
if (pilsobj->plnobj != NULL) { *pplnobj = pilsobj->plnobj; if (pilsobj->plnobj->wchMax != pilsobj->wchMax) { Assert(pilsobj->plnobj->pwch != NULL); Assert(pilsobj->plnobj->pdup != NULL); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pwch); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pdup); if (pilsobj->plnobj->pgmap != NULL) { /* it will be allocated in CheckReallocGlyphs in lstxtnti.c */ (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pgmap); pilsobj->plnobj->pgmap = NULL; }
if (pilsobj->plnobj->pdupPenAlloc != NULL) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pdupPenAlloc); }
pilsobj->plnobj->pdupPenAlloc = NULL;
pilsobj->plnobj->wchMax = pilsobj->wchMax; pilsobj->plnobj->pwch = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(WCHAR) * pilsobj->wchMax); pilsobj->plnobj->pdup = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->wchMax); if (pilsobj->plnobj->pwch == NULL || pilsobj->plnobj->pdup == NULL) { pilsobj->plnobj = NULL; return ErrorLNObjText(pplnobj, lserrOutOfMemory); } }
if (pilsobj->plnobj->gindMax != pilsobj->gindMax) { if (pilsobj->plnobj->pgind != NULL ) (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pgind); if (pilsobj->plnobj->pdupGind != NULL ) (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pdupGind); if (pilsobj->plnobj->pgoffs != NULL ) (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pgoffs); if (pilsobj->plnobj->pexpt != NULL ) (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pexpt); if (pilsobj->plnobj->pdupBeforeJust != NULL ) (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pdupBeforeJust); if (pilsobj->plnobj->pgprop != NULL ) (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plnobj->pgprop);
pilsobj->plnobj->gindMax = pilsobj->gindMax; pilsobj->plnobj->pgind = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(GINDEX) * pilsobj->gindMax); pilsobj->plnobj->pdupGind = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->gindMax); pilsobj->plnobj->pgoffs = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(GOFFSET) * pilsobj->gindMax); pilsobj->plnobj->pexpt = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(EXPTYPE) * pilsobj->gindMax); pilsobj->plnobj->pdupBeforeJust = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->gindMax); pilsobj->plnobj->pgprop = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(GPROP) * pilsobj->gindMax);
if (pilsobj->plnobj->pgind == NULL || pilsobj->plnobj->pdupGind == NULL || pilsobj->plnobj->pgoffs == NULL || pilsobj->plnobj->pexpt == NULL || pilsobj->plnobj->pdupBeforeJust == NULL || pilsobj->plnobj->pgprop == NULL) { pilsobj->plnobj = NULL; return ErrorLNObjText(pplnobj, lserrOutOfMemory); }
memset(pilsobj->plnobj->pexpt, 0, sizeof(EXPTYPE) * pilsobj->gindMax);
}
pilsobj->plnobj = NULL;
} else { *pplnobj = NULL; ptxtln = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(struct lnobj));
if (ptxtln == NULL) { return lserrOutOfMemory; }
*pplnobj = ptxtln;
memset(ptxtln, 0, sizeof(struct lnobj) );
ptxtln->pilsobj = pilsobj;
ptxtln->ptxtobj = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(TXTOBJ) * txtobjMaxM + sizeof(TXTOBJ**)); if ( ptxtln->ptxtobj == NULL) { return ErrorLNObjText(pplnobj, lserrOutOfMemory); }
ptxtln->ptxtobjFirst = ptxtln->ptxtobj; *(TXTOBJ**)( ptxtln->ptxtobj + txtobjMaxM) = NULL;
ptxtln->wchMax = pilsobj->wchMax; ptxtln->pwch = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(WCHAR) * pilsobj->wchMax); ptxtln->pdup = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->wchMax);
if (ptxtln->pwch == NULL || ptxtln->pdup == NULL) { return ErrorLNObjText(pplnobj, lserrOutOfMemory); }
if (pilsobj->gindMax > 0) { ptxtln->pgind = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(GINDEX) * pilsobj->gindMax); ptxtln->pdupGind = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->gindMax); ptxtln->pgoffs = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(GOFFSET) * pilsobj->gindMax); ptxtln->pexpt = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(EXPTYPE) * pilsobj->gindMax); ptxtln->pdupBeforeJust = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->gindMax); ptxtln->pgprop = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(GPROP) * pilsobj->gindMax);
if (ptxtln->pgind == NULL || ptxtln->pdupGind == NULL || ptxtln->pgoffs == NULL || ptxtln->pexpt == NULL || ptxtln->pdupBeforeJust == NULL || ptxtln->pgprop == NULL) { return ErrorLNObjText(pplnobj, lserrOutOfMemory); }
ptxtln->gindMax = pilsobj->gindMax; } }
if (pilsobj->fNotSimpleText) { if (pilsobj->pdurRight != NULL) { memset(pilsobj->pdurRight, 0, sizeof(long) * pilsobj->wchMac ); Assert (pilsobj->pdurLeft != NULL); memset(pilsobj->pdurLeft, 0, sizeof(long) * pilsobj->wchMac ); Assert (pilsobj->ptxtinf != NULL); memset(pilsobj->ptxtinf, 0, sizeof(TXTINF) * pilsobj->wchMac ); } if ((*pplnobj)->pdupPen == (*pplnobj)->pdupPenAlloc && (*pplnobj)->pdupPen != NULL) memset((*pplnobj)->pdupPenAlloc, 0, sizeof(long) * pilsobj->wchMax);
if (pilsobj->gindMac != 0) { Assert (pilsobj->pduGright != NULL); memset(pilsobj->pduGright, 0, sizeof(long) * pilsobj->gindMac ); Assert (pilsobj->plsexpinf != NULL); memset(pilsobj->plsexpinf, 0, sizeof(LSEXPINFO) * pilsobj->gindMac ); Assert ((*pplnobj)->pexpt != NULL); memset((*pplnobj)->pexpt, 0, sizeof(EXPTYPE) * pilsobj->gindMac ); } }
pilsobj->txtobjMac = 0; pilsobj->wchMac = 0; pilsobj->gindMac = 0; pilsobj->wSpacesMac = 0;
pilsobj->fNotSimpleText = fFalse; pilsobj->fDifficultForAdjust = fFalse;
pilsobj->fTruncatedBefore = fFalse;
pilsobj->iwchCompressFetchedFirst = 0; pilsobj->itxtobjCompressFetchedLim = 0; pilsobj->iwchCompressFetchedLim = 0;
pilsobj->dcpFetchedWidth = 0;
pilsobj->breakinfMac = 3; pilsobj->pbreakinf[0].pdobj = NULL; pilsobj->pbreakinf[1].pdobj = NULL; pilsobj->pbreakinf[2].pdobj = NULL;
(*pplnobj)->ptxtobj = (*pplnobj)->ptxtobjFirst;
(*pplnobj)->pdupPen = (*pplnobj)->pdup;
(*pplnobj)->pdobjHyphen = NULL; (*pplnobj)->dwchYsr = 0;
return lserrNone;
}
/* S E T D O C T E X T */ /*----------------------------------------------------------------------------
%%Function: SetDocText %%Contact: sergeyge
Initialization at the doc level Called when resolutions are changed ----------------------------------------------------------------------------*/ LSERR WINAPI SetDocText(PILSOBJ pilsobj, PCLSDOCINF plsdocinf) { pilsobj->fDisplay = plsdocinf->fDisplay; pilsobj->fPresEqualRef = plsdocinf->fPresEqualRef; pilsobj->lsdevres = plsdocinf->lsdevres;
/* Be careful---In Visi case fPresEqualRef can be True, but sizes of characters---different
*/ if (pilsobj->fDisplay && !pilsobj->fPresEqualRef) { pilsobj->MagicConstantX = LsLwMultDivR(pilsobj->lsdevres.dxpInch, 1 << 21, pilsobj->lsdevres.dxrInch); pilsobj->durRightMaxX = min(1 << 21, (0x7FFFFFFF - (1 << 20)) / pilsobj->MagicConstantX);
pilsobj->MagicConstantY = pilsobj->MagicConstantX; pilsobj->durRightMaxY = pilsobj->durRightMaxY;
if (pilsobj->lsdevres.dxrInch != pilsobj->lsdevres.dyrInch || pilsobj->lsdevres.dxpInch != pilsobj->lsdevres.dypInch) pilsobj->MagicConstantY = LsLwMultDivR(pilsobj->lsdevres.dypInch, 1 << 21, pilsobj->lsdevres.dyrInch); pilsobj->durRightMaxY = min(1 << 21, (0x7FFFFFFF - (1 << 20)) / pilsobj->MagicConstantY); }
return lserrNone; }
/* S E T T E X T B R E A K I N G */ /*----------------------------------------------------------------------------
%%Function: SetTextBreaking %%Contact: sergeyge
Initialization on the doc level Called when the breaking table should be installed or changed ----------------------------------------------------------------------------*/ LSERR SetTextBreaking(PILSOBJ pilsobj, DWORD clsbrk, const LSBRK* rglsbrk, DWORD cBreakingClasses, const BYTE* rgibrk) { DWORD i;
if (pilsobj->cBreakingClasses < cBreakingClasses) { if (pilsobj->cBreakingClasses > 0) { Assert(pilsobj->pilsbrk != NULL); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilsbrk); pilsobj->pilsbrk = NULL; pilsobj->cBreakingClasses = 0; }
pilsobj->pilsbrk = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(BYTE) * cBreakingClasses * cBreakingClasses); if ( pilsobj->pilsbrk == NULL) { return lserrOutOfMemory; }
pilsobj->cBreakingClasses = cBreakingClasses; }
if (pilsobj->clsbrk < clsbrk) { if (pilsobj->clsbrk > 0) { Assert(pilsobj->plsbrk != NULL); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plsbrk); pilsobj->plsbrk = NULL; pilsobj->clsbrk = 0; }
pilsobj->plsbrk = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(LSBRK) * clsbrk); if ( pilsobj->plsbrk == NULL) { return lserrOutOfMemory; }
pilsobj->clsbrk = clsbrk;
}
memcpy(pilsobj->plsbrk, rglsbrk, sizeof(LSBRK) * clsbrk); memcpy(pilsobj->pilsbrk, rgibrk, sizeof(BYTE) * cBreakingClasses * cBreakingClasses);
for (i = 0; i < cBreakingClasses * cBreakingClasses; i++) { if (rgibrk[i] >= clsbrk) { Assert(fFalse); return lserrInvalidParameter; /* REVIEW sergeyge: another error code? */ } }
return lserrNone; }
/* S E T T E X T M O D W I D T H P A I R S */ /*----------------------------------------------------------------------------
%%Function: SetTextModWidthPairs %%Contact: sergeyge
Initialization on the doc level Called when the ModWidthPairs table should be installed or changed ----------------------------------------------------------------------------*/ LSERR SetTextModWidthPairs(PILSOBJ pilsobj, DWORD clspairact, const LSPAIRACT* rglspairact, DWORD cModWidthClasses, const BYTE* rgipairact) { DWORD i; CkeckModWidthClasses(pilsobj, cModWidthClasses);
if (pilsobj->pilspairact == NULL) { pilsobj->pilspairact = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(BYTE) * cModWidthClasses * cModWidthClasses); if ( pilsobj->pilspairact == NULL) { return lserrOutOfMemory; } }
if (pilsobj->clspairact < clspairact) { if (pilsobj->clspairact > 0) { Assert(pilsobj->plspairact != NULL); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plspairact); pilsobj->plspairact = NULL; pilsobj->clspairact = 0; }
pilsobj->plspairact = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(LSPAIRACT) * clspairact); if ( pilsobj->plspairact == NULL) { return lserrOutOfMemory; }
pilsobj->clspairact = clspairact; }
memcpy(pilsobj->plspairact, rglspairact, sizeof(LSPAIRACT) * clspairact); memcpy(pilsobj->pilspairact, rgipairact, sizeof(BYTE) * cModWidthClasses * cModWidthClasses);
for (i = 0; i < cModWidthClasses * cModWidthClasses; i++) { if (rgipairact[i] >= clspairact) { Assert(fFalse); return lserrInvalidParameter; /* REVIEW sergeyge: another error code? */ } }
return lserrNone;
}
/* S E T T E X T C O M P R E S S I O N */ /*----------------------------------------------------------------------------
%%Function: SetTextCompression %%Contact: sergeyge
Initialization on the doc level Called when the Compression table should be installed or changed ----------------------------------------------------------------------------*/ LSERR SetTextCompression(PILSOBJ pilsobj, DWORD cCompPrior, DWORD clspract, const LSPRACT* rglspract, DWORD cModWidthClasses, const BYTE* rgipract) { DWORD i; CkeckModWidthClasses(pilsobj, cModWidthClasses);
if (pilsobj->pilspract == NULL) { pilsobj->pilspract = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(BYTE) * cModWidthClasses); if ( pilsobj->pilspract == NULL) { return lserrOutOfMemory; } }
if (pilsobj->clspract < clspract) { if (pilsobj->clspract > 0) { Assert(pilsobj->plspract != NULL); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plspract); pilsobj->plspract = NULL; pilsobj->clspract = 0; }
pilsobj->plspract = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(LSPRACT) * clspract); if ( pilsobj->plspract == NULL) { return lserrOutOfMemory; }
pilsobj->clspract = clspract; }
pilsobj->cCompPrior = cCompPrior;
memcpy(pilsobj->plspract, rglspract, sizeof(LSPRACT) * clspract); memcpy(pilsobj->pilspract, rgipract, sizeof(BYTE) * cModWidthClasses);
for (i = 0; i < cModWidthClasses; i++) { if (rgipract[i] >= clspract) { Assert(fFalse); return lserrInvalidParameter; /* REVIEW sergeyge: another error code? */ } }
return lserrNone;
}
/* S E T T E X T E X P A N S I O N */ /*----------------------------------------------------------------------------
%%Function: SetTextExpansion %%Contact: sergeyge
Initialization on the doc level Called when the Expansion table should be installed or changed ----------------------------------------------------------------------------*/ LSERR SetTextExpansion(PILSOBJ pilsobj, DWORD clsexpan, const LSEXPAN* rglsexpan, DWORD cModWidthClasses, const BYTE* rgiexpan) { DWORD i; CkeckModWidthClasses(pilsobj, cModWidthClasses);
if (pilsobj->pilsexpan == NULL) { pilsobj->pilsexpan = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(BYTE) * cModWidthClasses * cModWidthClasses); if ( pilsobj->pilsexpan == NULL) { return lserrOutOfMemory; } }
if (pilsobj->clsexpan < clsexpan) { if (pilsobj->clsexpan > 0) { Assert(pilsobj->plsexpan != NULL); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->plsexpan); pilsobj->plsexpan = NULL; pilsobj->clsexpan = 0; }
pilsobj->plsexpan = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(LSEXPAN) * clsexpan); if ( pilsobj->plsexpan == NULL) { return lserrOutOfMemory; }
pilsobj->clsexpan = clsexpan; }
memcpy(pilsobj->plsexpan, rglsexpan, sizeof(LSEXPAN) * clsexpan); memcpy(pilsobj->pilsexpan, rgiexpan, sizeof(BYTE) * cModWidthClasses * cModWidthClasses);
for (i = 0; i < cModWidthClasses * cModWidthClasses; i++) { if (rgiexpan[i] >= clsexpan) { Assert(fFalse); return lserrInvalidParameter; /* REVIEW sergeyge: another error code? */ } }
return lserrNone;
}
/* S E T T E X T L I N E P A R A M S */ /*----------------------------------------------------------------------------
%%Function: SetTextLineParams %%Contact: sergeyge
Initialization at the beginning of the line with the text specific parameters. ----------------------------------------------------------------------------*/ LSERR SetTextLineParams(PLNOBJ plnobj, const TLPR* ptlpr) { PILSOBJ pilsobj;
pilsobj = plnobj->pilsobj;
pilsobj->grpf = ptlpr->grpfText; pilsobj->fSnapGrid = ptlpr->fSnapGrid; pilsobj->duaHyphenationZone = ptlpr->duaHyphenationZone;
pilsobj->lskeop = ptlpr->lskeop;
plnobj->fDrawInCharCodes = pilsobj->grpf & fTxtDrawInCharCodes;
if ( (pilsobj->grpf & fTxtApplyBreakingRules) && pilsobj->pilsbrk == NULL) return lserrBreakingTableNotSet;
return lserrNone; }
/* M O D I F Y T E X T L I N E E N D I N G */ /*----------------------------------------------------------------------------
%%Function: ModifyTextLineEnding %%Contact: sergeyge
Modifies line ending information when text vanishes across paragraph boundary ----------------------------------------------------------------------------*/ LSERR ModifyTextLineEnding(PLNOBJ plnobj, LSKEOP lskeop) {
plnobj->pilsobj->lskeop = lskeop;
return lserrNone; }
/* S E T T E X T C O N F I G */ /*----------------------------------------------------------------------------
%%Function: SetTextConfig %%Contact: sergeyge
Sets special characters in the ilsobj ----------------------------------------------------------------------------*/ LSERR SetTextConfig(PILSOBJ pilsobj, const LSTXTCFG* plstxtcfg) { LSERR lserr; WCHAR wchUndef;
wchUndef = plstxtcfg->wchUndef;
pilsobj->wchVisiNull = plstxtcfg->wchVisiNull; pilsobj->wchVisiEndPara = plstxtcfg->wchVisiEndPara; pilsobj->wchVisiAltEndPara = plstxtcfg->wchVisiAltEndPara; pilsobj->wchVisiEndLineInPara = plstxtcfg->wchVisiEndLineInPara; pilsobj->wchVisiSpace = plstxtcfg->wchVisiSpace; pilsobj->wchVisiNonBreakSpace = plstxtcfg->wchVisiNonBreakSpace; pilsobj->wchVisiNonBreakHyphen = plstxtcfg->wchVisiNonBreakHyphen; pilsobj->wchVisiNonReqHyphen = plstxtcfg->wchVisiNonReqHyphen; pilsobj->wchVisiTab = plstxtcfg->wchVisiTab; pilsobj->wchVisiEmSpace = plstxtcfg->wchVisiEmSpace; pilsobj->wchVisiEnSpace = plstxtcfg->wchVisiEnSpace; pilsobj->wchVisiNarrowSpace = plstxtcfg->wchVisiNarrowSpace; pilsobj->wchVisiOptBreak = plstxtcfg->wchVisiOptBreak; pilsobj->wchVisiNoBreak = plstxtcfg->wchVisiNoBreak; pilsobj->wchVisiFESpace = plstxtcfg->wchVisiFESpace;
Assert(0 == clabRegular); Assert(pilsobj->wchVisiEndPara != wchUndef); Assert(pilsobj->wchVisiAltEndPara != wchUndef); Assert(pilsobj->wchVisiEndLineInPara != wchUndef);
pilsobj->wchSpace = plstxtcfg->wchSpace; pilsobj->wchHyphen = plstxtcfg->wchHyphen; pilsobj->wchReplace = plstxtcfg->wchReplace; pilsobj->wchNonBreakSpace = plstxtcfg->wchNonBreakSpace;
lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNull, clabNull, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchSpace, clabSpace, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchHyphen, clabHardHyphen, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchTab, clabTab, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEndPara1, clabEOP1, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEndPara2, clabEOP2, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchAltEndPara, clabAltEOP, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEndLineInPara, clabEndLineInPara, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchColumnBreak, clabColumnBreak, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchSectionBreak, clabSectionBreak, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchPageBreak, clabPageBreak, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNonBreakSpace, clabNonBreakSpace, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNonBreakHyphen, clabNonBreakHyphen, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNonReqHyphen, clabNonReqHyphen, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEmDash, clabHardHyphen, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEnDash, clabHardHyphen, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEnSpace, clabEnSpace, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchEmSpace, clabEmSpace, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNarrowSpace, clabNarrowSpace, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchOptBreak, clabOptBreak, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNoBreak, clabNonBreak, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchFESpace, clabFESpace, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchJoiner, clabJoiner, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchNonJoiner, clabNonJoiner, wchUndef); if (lserr != lserrNone) return lserr; lserr = TxtAddSpec(pilsobj, plstxtcfg->wchToReplace, clabToReplace, wchUndef); if (lserr != lserrNone) return lserr;
lserr = TxtSortSpec( pilsobj->rgwchSpec, pilsobj->rgbKind, pilsobj->cwchSpec); if (lserr != lserrNone) return lserr;
Assert(pilsobj->pwchOrig == NULL && pilsobj->pdur == NULL && pilsobj->pwSpaces == NULL);
pilsobj->wchMax = plstxtcfg->cEstimatedCharsPerLine; pilsobj->pwchOrig = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(WCHAR) * pilsobj->wchMax ); pilsobj->pdur = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * pilsobj->wchMax ); pilsobj->pwSpaces = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(long) * wSpacesMaxM); pilsobj->pbreakinf = (*pilsobj->plscbk->pfnNewPtr)(pilsobj->pols, sizeof(BREAKINFO) * 3); /* One for Prev/Next/Force Break for main subline */
if (pilsobj->pwchOrig == NULL || pilsobj->pdur == NULL || pilsobj->pwSpaces == NULL || pilsobj->pbreakinf == NULL) { return lserrOutOfMemory; }
pilsobj->wSpacesMax = wSpacesMaxM; pilsobj->breakinfMax = 3; pilsobj->breakinfMac = 3;
/* be careful---CreateLNObjText makes pilsobj->plnobj = NULL,
if pilsobj->plnobj is not NULL */ Assert(pilsobj->plnobj == NULL);
lserr = CreateLNObjText(pilsobj, &pilsobj->plnobj);
return lserr; }
/* Internal Functions Implementation */
/*----------------------------------------------------------------------------
%%Function: ErrorLNObjText %%Contact: sergeyge
----------------------------------------------------------------------------*/ static LSERR ErrorLNObjText(PLNOBJ* pplnobj, LSERR lserr) { DestroyLNObjTextCore(*pplnobj); *pplnobj = NULL; return lserr; }
/*----------------------------------------------------------------------------
%%Function: DestroyLNObjTextCore %%Contact: sergeyge
----------------------------------------------------------------------------*/ static void DestroyLNObjTextCore(PLNOBJ plnobj) { PILSOBJ pilsobj; PTXTOBJ ptxtobj; PTXTOBJ ptxtobjNext;
pilsobj = plnobj->pilsobj;
ptxtobj = plnobj->ptxtobjFirst; while ( ptxtobj != NULL ) { ptxtobjNext = *(TXTOBJ**)(ptxtobj + txtobjMaxM); (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, ptxtobj); ptxtobj = ptxtobjNext; }
plnobj->ptxtobjFirst = NULL;
if ( plnobj->pwch != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pwch); plnobj->pwch = NULL; } if ( plnobj->pdup != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pdup); plnobj->pdup = NULL; } if ( plnobj->pdupPenAlloc != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pdupPenAlloc); plnobj->pdupPenAlloc = NULL; }
if ( plnobj->pgind != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pgind); plnobj->pgind = NULL; } if ( plnobj->pdupGind != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pdupGind); plnobj->pdupGind = NULL; } if ( plnobj->pgoffs != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pgoffs); plnobj->pgoffs = NULL; } if ( plnobj->pexpt != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pexpt); plnobj->pexpt = NULL; } if ( plnobj->pdupBeforeJust != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pdupBeforeJust); plnobj->pdupBeforeJust = NULL; } if ( plnobj->pgprop != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pgprop); plnobj->pgprop = NULL; } if ( plnobj->pgmap != NULL ) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, plnobj->pgmap); plnobj->pgmap = NULL; }
(*pilsobj->plscbk->pfnDisposePtr) (pilsobj->pols, plnobj);
return; }
/* C H E C K C M O D W I D T H C L A S S E S */ /*----------------------------------------------------------------------------
%%Function: CheckCModWidthClasses %%Contact: sergeyge
Checks that new cModWidthClasses does not contradict old one. If it does, disposes all relevant arrays ----------------------------------------------------------------------------*/ static void CkeckModWidthClasses(PILSOBJ pilsobj, DWORD cModWidthClasses) { if (pilsobj->cModWidthClasses != cModWidthClasses) { if (pilsobj->pilspairact != NULL) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilspairact); pilsobj->pilspairact = NULL; }
if (pilsobj->pilspract != NULL) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilspract); pilsobj->pilspract = NULL; }
if (pilsobj->pilsexpan != NULL) { (*pilsobj->plscbk->pfnDisposePtr)(pilsobj->pols, pilsobj->pilsexpan); pilsobj->pilsexpan = NULL; }
pilsobj->cModWidthClasses = cModWidthClasses; }
}
/* T X T A D D S P E C */ /*----------------------------------------------------------------------------
%%Function: TxtAddSpec %%Contact: sergeyge
Sets special character in the ilsobj structure
Strategy:
if special character (wchSymbol) less than 256, set its type in the rgbSwitch[wchSymbol] (there cannot be more then 15 different types)
if special character is greater than 256, set first bit of rgbSwitch[wchSymbol & 0x00FF] (it is independent of types of characters < 256 , since these types <= 15); also remember character and it's type in rgwchSpec, rgbKind respectively. ----------------------------------------------------------------------------*/ static LSERR TxtAddSpec(PILSOBJ pilsobj, WCHAR wchSymbol, CLABEL clab, WCHAR wchUndef) { CLABEL* rgbSwitch;
rgbSwitch = pilsobj->rgbSwitch;
if (wchSymbol == wchUndef) { return lserrNone; } if (wchSymbol < 256) { if ( (rgbSwitch[wchSymbol] & fSpecMask) == 0) { rgbSwitch[wchSymbol] |= clab; } else { Assert(fFalse); return lserrDuplicateSpecialCharacter; } } else { rgbSwitch[wchSymbol & 0x00FF] |= clabSuspicious; pilsobj->rgwchSpec[pilsobj->cwchSpec] = wchSymbol; pilsobj->rgbKind[pilsobj->cwchSpec] = clab; pilsobj->cwchSpec++; }
return lserrNone; }
/* T X T S O R T S P E C */ /*----------------------------------------------------------------------------
%%Function: TxtSortSpec %%Contact: sergeyge
Sorts rgwchSpec array (and moves elements of rgbKind appropriately) to make search for special chars >= 256 faster. ----------------------------------------------------------------------------*/ static LSERR TxtSortSpec(WCHAR* rgwchSpec, CLABEL* rgbKind, DWORD cwchSpec) { int i, j, iMin; WCHAR wchChange; CLABEL clabChange; BOOL fChanged;
for (i=0; i < (int)cwchSpec-1; i++) { iMin = i; fChanged = fFalse; for (j = i+1; j < (int)cwchSpec; j++) { if (rgwchSpec[j] < rgwchSpec[iMin]) { fChanged = fTrue; iMin = j; } } if (fChanged) { clabChange = rgbKind[i]; wchChange = rgwchSpec[i]; rgbKind[i] = rgbKind[iMin]; rgwchSpec[i] = rgwchSpec[iMin]; rgbKind[iMin] = clabChange; rgwchSpec[iMin] = wchChange;
} }
for (i=0; i < (int)cwchSpec-1; i++) { if (rgwchSpec[i] == rgwchSpec[i+1]) { Assert(fFalse); return lserrDuplicateSpecialCharacter; } }
return lserrNone; }
|