Leaked source code of windows server 2003
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.
 
 
 
 
 
 

3021 lines
104 KiB

/************************************************************/
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
/************************************************************/
/*--- Module not really used, just the idea behind FORMAT.ASM ---*/
#define NOCLIPBOARD
#define NOGDICAPMASKS
#define NOCTLMGR
#define NOVIRTUALKEYCODES
#define NOWINMESSAGES
#define NOWINSTYLES
#define NOKEYSTATE
#define NOSYSCOMMANDS
#define NORASTEROPS
#define NOSHOWWINDOW
#define NOCLIPBOARD
#define NOWINSTYLES
#define NOSYSMETRICS
#define NOMENUS
#define NOATOM
#define NOCREATESTRUCT
#define NODRAWTEXT
#define NOMB
#define NOMEMMGR
#define NOMETAFILE
#define NOWH
#define NOWINOFFSETS
#define NOWNDCLASS
#include <windows.h>
/* #include "wwsmall.h" */
#include "mw.h"
#include "cmddefs.h"
#include "fmtdefs.h"
#include "propdefs.h"
#include "ch.h"
#include "docdefs.h"
#include "ffdefs.h"
#include "filedefs.h"
#include "fkpdefs.h"
#include "dispdefs.h"
#include "scrndefs.h"
#include "macro.h"
#include "debug.h"
#include "fontdefs.h"
#include "str.h"
#include "wwdefs.h"
#ifdef DBCS
#include "dbcs.h"
/* We move several hard code Kanji code table from this source file
to kanji.h as external variables. Define CODE_TABLE will define
those variables */
#define CODE_TABLE
#include "kanji.h"
#endif
#if defined(TAIWAN) || defined(PRC)
int WINAPI GetFontAssocStatus(HDC);
#endif
#ifdef DFLI
#define Dfli(x) x /* Enable debug-format-line info */
#else
#define Dfli(x)
#endif
#ifdef CASHMERE
#define cchSmcapMax 16
#endif /* CASHMERE */
static int ichpFormat;
#ifdef CASHMERE
static CHAR mptlcch[] = " .-_";
#endif /* CASHMERE */
#if defined(JAPAN) || defined(KOREA) // added 22 Jun. 1992 by Hiraisi
int iWidenChar; /* counter for widened characters except (KANJI) space */
/* Ex.) DBCS, Japanese KANA */
int iNonWideSpaces;
#elif defined(TAIWAN) || defined(PRC)// Daniel/MSTC, 1993/02/25, for jcBoth
int iWidenChar; /* counter for widened characters except (KANJI) space */
/* Ex.) DBCS, Japanese KANA */
int iNonWideSpaces;
extern int vfWordWrap;
#define FKana(_ch) FALSE
#endif
/* T-HIROYN sync format.asm */
/*extern int docHelp;*/
extern struct FLI vfli;
extern struct CHP (**vhgchpFormat)[];
extern int ichpMacFormat;
extern struct CHP vchpAbs;
extern struct PAP vpapAbs;
extern struct SEP vsepAbs;
extern struct SEP vsepPage;
extern struct CHP vchpNormal;
extern struct DOD (**hpdocdod)[];
extern typeCP vcpLimSectCache;
extern typeCP vcpFirstParaCache;
extern typeCP vcpLimParaCache;
extern typeCP vcpFetch;
extern int vichFetch;
extern int vccpFetch;
extern CHAR *vpchFetch;
extern int vcchFetch;
extern int vftc;
extern int ypSubSuper;
extern int ypSubSuperPr;
extern HDC vhMDC;
extern HDC vhDCPrinter;
extern int dxpLogInch;
extern int dypLogInch;
extern int dxaPrPage;
extern int dyaPrPage;
extern int dxpPrPage;
extern int dypPrPage;
extern int dypMax;
extern struct FMI vfmiScreen, vfmiPrint;
extern int vfOutOfMemory;
extern CHAR vchDecimal; /* "decimal point" character */
extern int vzaTabDflt; /* width of default tab */
#if defined(JAPAN) || defined(KOREA)
extern int vfWordWrap; /*t-Yoshio WordWrap flag*/
#endif
#ifdef CASHMERE
extern int vfVisiMode;
#endif /* CASHMERE */
/* F O R M A T L I N E */
FormatLine(doc, cp, ichCp, cpMac, flm)
int doc;
typeCP cp;
int ichCp;
typeCP cpMac;
int flm;
{
/* Fills up vfli with a line of text */
int near Justify(struct IFI *, unsigned, int);
int near FGrowFormatHeap(void);
int near FFirstIch(int);
#ifdef DBCS
BOOL near FAdmitCh1(CHAR);
BOOL near FAdmitCh2(CHAR, CHAR);
BOOL near FOptAdmitCh1(CHAR);
BOOL near FOptAdmitCh2(CHAR, CHAR);
int DBCSDxpFromCh(int,int,int);
#endif
struct IFI ifi;
struct TBD *ptbd;
struct CHP chpLocal;
int xpTab;
#ifdef CASHMERE
int dypBefore;
#endif /* CASHMERE */
int dypAscent;
int dypDescent;
int dypAscentMac;
int dypDescentMac;
unsigned xaLeft;
unsigned xaRight;
struct PAP *ppap;
struct SEP *psep;
int fFlmPrinting = flm & flmPrinting;
int dxaFormat;
int dyaFormat;
int dxpFormat;
int dypFormat;
int ypSubSuperFormat;
int fTruncated = false; /* if the run was truncated */
int ichpNRH;
#ifdef DBCS
int dichSpaceAdjust;
int dypLeading;
int dypIntLeading;
int dypPAscent; /* Pure Ascent */
int dypLeadingMac;
int dypIntLeadingMac;
int dypPAscentMac;
BOOL fKanjiBreakOppr = false;
BOOL fKanjiPrevious = false;
/* true iff we already have a hanging character on the line. */
BOOL fKanjiHanging = false;
/* true iff the first and second bytes of a kanji character
were in two different runs. */
BOOL fOddBoundary = false;
typeCP cpFetchSave;
typeCP cpSeqFetch;
int ichFetchSave;
int cchUsedSave;
extern int utCur;
extern int dxaAdjustPer5Ch;
extern unsigned cxaCh;
#endif /* ifdef DBCS */
#ifdef CASHMERE
struct FNTB **hfntb;
int fVisiMode;
#endif /* CASHMERE */
/* Check for fli current */
if (vfli.doc == doc && vfli.cpMin == cp && vfli.ichCpMin == ichCp &&
vfli.flm == flm)
{
/* Just did this one */
return;
}
#ifdef JAPAN // added by Hiraisi
// When printing, WRITE doesn't redraw the screen.
{
extern BOOL fPrinting;
if( fPrinting && !fFlmPrinting )
return;
}
#endif
Scribble(5, 'F');
bltc(&vfli, 0, cwFLIBase);
/* This means:
vfli.fSplat = false;
vfli.dcpDepend = 0;
vfli.ichCpMac = 0;
vfli.dypLine = 0;
vfli.dypAfter = 0;
vfli.dypFont = 0;
vfli.dypBase = 0;
*/
/* vfSplatNext = FALSE; No longer used. */
/* Rest of format loads up cache with current data */
vfli.doc = doc;
vfli.cpMin = cp;
vfli.ichCpMin = ichCp;
vfli.flm = flm;
if (cp > cpMac)
{
/* Space after the endmark. Reset the cache because the footnotes come
at the same cp in the footnote window */
vfli.doc = docNil;
vfli.cpMac = cp;
vfli.rgdxp[0] = 0;
/* Line after end mark is taller than screen */
#ifdef CASHMERE
vfli.dypBase = vfli.dypFont = vfli.dypAfter = ((vfli.dypLine = dypMax)
>> 1);
#else /* not CASHMERE */
vfli.dypBase = vfli.dypFont = ((vfli.dypLine = dypMax) >> 1);
#endif /* not CASHMERE */
Scribble(5, ' ');
return;
}
/* Initialize run tables */
ichpFormat = 0;
/* Cache section and paragraph properties */
#ifdef CASHMERE
hfntb = (**hpdocdod)[doc].hfntb;
if (hfntb == 0 || cp < (**hfntb).rgfnd[0].cpFtn)
{
/* Normal text */
CacheSect(doc, cp);
}
else
{
/* Footnote section properties come from the section of the footnote
reference. */
CacheSect(doc, CpRefFromFtn(doc, cp));
}
#else /* not CASHMERE */
CacheSect(doc, cp);
#endif /* not CASHMERE */
psep = &vsepAbs;
CachePara(doc, cp);
ppap = &vpapAbs;
/* Now we have:
ppap paragraph properties
psep division properties
*/
if (ppap->fGraphics)
{
/* Format a picture paragraph in a special way (see picture.c) */
FormatGraphics(doc, cp, ichCp, cpMac, flm);
Scribble(5, ' ');
return;
}
/* Assure we have a good memory DC for font stuff */
ValidateMemoryDC();
if (vhMDC == NULL || vhDCPrinter == NULL)
{
Scribble(5, ' ');
return;
}
#ifdef CASHMERE
/* When printing, don't show visible characters */
fVisiMode = vfVisiMode && !fFlmPrinting;
#endif /* CASHMERE */
bltc(&ifi, 0, cwIFI);
/* This means:
ifi.ich = 0;
ifi.ichPrev = 0;
ifi.ichFetch = 0;
ifi.cchSpace = 0;
ifi.ichLeft = 0;
*/
ifi.jc = jcTabLeft;
ifi.fPrevSpace = true;
/* Set up some variables that have different value depending on whether we
are printing or not. */
if (fFlmPrinting)
{
dxaFormat = dxaPrPage;
dyaFormat = dyaPrPage;
dxpFormat = dxpPrPage;
dypFormat = dypPrPage;
ypSubSuperFormat = ypSubSuperPr;
}
else
{
dxaFormat = dyaFormat = czaInch;
dxpFormat = dxpLogInch;
dypFormat = dypLogInch;
ypSubSuperFormat = ypSubSuper;
}
/* Calculate line height and width measures. Compute
xaLeft left indent 0 means at left margin
xaRight width of column measured from left margin (not from left
indent).
*/
xaLeft = ppap->dxaLeft;
/* If this is the first line of a paragraph, adjust xaLeft for the first
line indent. (Also, set dypBefore, since its handy.) */
if (cp == vcpFirstParaCache)
{
xaLeft += ppap->dxaLeft1;
#ifdef CASHMERE
dypBefore = MultDiv(ppap->dyaBefore, dypLogInch, czaInch);
#endif /* CASHMERE */
}
#ifdef CASHMERE
else
{
dypBefore = 0;
}
#endif /* CASHMERE */
/* Now, set xaRight (width measured in twips). */
#ifdef CASHMERE
xaRight = (ppap->rhc ? vsepPage.xaMac - vsepPage.dxaGutter :
psep->dxaText) - ppap->dxaRight;
#else /* not CASHMERE */
xaRight = psep->dxaText - ppap->dxaRight;
#endif /* not CASHMERE */
/* Do necessary checks on xaLeft and xaRight */
if (xaRight > xaRightMax)
{
xaRight = xaRightMax;
}
if (xaLeft > xaRightMax)
{
xaLeft = xaRightMax;
}
if (xaLeft < 0)
{
xaLeft = 0;
}
if (xaRight < xaLeft)
{
xaRight = xaLeft + 1;
}
vfli.xpLeft = ifi.xp = ifi.xpLeft = MultDiv(xaLeft, dxpFormat, dxaFormat);
vfli.xpMarg = ifi.xpRight = MultDiv(xaRight, dxpFormat, dxaFormat);
ifi.xpPr = MultDiv(xaLeft, dxpPrPage, dxaPrPage);
ifi.xpPrRight = MultDiv(xaRight, dxpPrPage, dxaPrPage);
#ifndef JAPAN // added by Hiraisi (BUG#3542)
#ifdef DBCS /* was in JAPAN */
/* at least one kanji is displayed */
/* DxpFromCh() --> DBCSDxpFromCh() 03 Oct 1991 YutakaN */
{
int dxpPr;
if ( ifi.xpPrRight - ifi.xpPr < (dxpPr = DBCSDxpFromCh(bKanjiSpace1,bKanjiSpace2, TRUE) ) )
{
ifi.xpPrRight = ifi.xpPr + dxpPr + 1;
}
}
#endif
#endif
/* Get a pointer to the tab-stop table. */
ptbd = ppap->rgtbd;
/* Turn off justification. */
SetTextJustification(fFlmPrinting ? vhDCPrinter : vhMDC, 0, 0);
/* Initialize the line height information. */
dypAscentMac = dypDescentMac = 0;
/*T-HIROYN add from 3.0*/
#if defined(JAPAN) || defined(KOREA)
dypLeadingMac = dypIntLeadingMac = dypPAscentMac = 0;
#endif /* JAPAN */
/* To tell if there were any tabs */
ifi.ichLeft = -1;
#if defined(JAPAN) || defined(KOREA) // added 22 Jun. 1992 by Hiraisi
iWidenChar=0;
#elif defined(TAIWAN) || defined(PRC) // Daniel/MSTC, 1993/02/25, for jcBoth
iWidenChar=0;
#endif
/* Get the first run, and away we go... */
FetchCp(doc, cp, ichCp, fcmBoth + fcmParseCaps);
goto FirstCps;
for ( ; ; )
{
int iichNew;
int xpPrev;
int dxp;
int dxpPr;
/* The number of characters to process (usually vcchFetch) */
int cch;
/* The number of characters in current run already used */
int cchUsed;
/* A pointer to the current list of characters (usually vpchFetch) */
CHAR *pch;
#ifdef CASHMERE
CHAR rgchSmcap[cchSmcapMax];
#endif /* CASHMERE */
if (ifi.ichFetch == cch)
{
/* End of a run */
int dich;
BOOL fSizeChanged;
if (ifi.ich >= ichMaxLine )
/* End of run because of line length limit has been reached. */
{
goto DoBreak;
}
if (fTruncated)
{
cchUsed += cch;
pch = vpchFetch + cchUsed;
cch = vcchFetch - cchUsed;
fTruncated = false;
goto OldRun; /* use the rest of the old run */
}
NullRun:
#ifdef DBCS
if (!fOddBoundary)
{
/* The last fetch did not mess up a sequential access. */
FetchCp(docNil, cpNil, 0, fcmBoth + fcmParseCaps);
}
else
{
/* Previous fetch was an odd one. Set it up again. */
FetchCp(doc, cpSeqFetch, 0, fcmBoth + fcmParseCaps);
}
fOddBoundary = false;
#else
FetchCp(docNil, cpNil, 0, fcmBoth + fcmParseCaps);
#endif
FirstCps:
cchUsed = 0;
/* Continue fetching runs until a run is found with a nonzero
length. */
if ((cch = vcchFetch) == 0)
{
goto NullRun;
}
pch = vpchFetch;
if (vcpFetch >= cpMac || (!fFlmPrinting && *pch == chSect))
{
#ifdef SYSENDMARK
/* Force end mark and section mark to be in standard system
font. */
blt(&vchpNormal, &vchpAbs, cwCHP);
vchpAbs.ftc = ftcSystem;
vchpAbs.ftcXtra = 0;
vchpAbs.hps = hpsDefault;
#else
#ifdef REVIEW
/* The following comment is absolutely misleading! Ftc==0
doesn't give you a system font. It gives you the first
entry in the font table. */
#endif /* REVIEW */
/* Force end mark and section mark to be in standard system
font. */
blt(&vchpNormal, &vchpAbs, cwCHP);
vchpAbs.ftc = 0;
vchpAbs.ftcXtra = 0;
vchpAbs.hps = hpsDefault;
#endif /* if-else-def KANJI */
}
#ifdef CASHMERE
/* Adjust the size of the font for "small capitals". */
if (vchpAbs.csm == csmSmallCaps)
{
vchpAbs.hps = HpsAlter(vchpAbs.hps, -1);
}
#endif /* CASHMERE */
/* Now we have:
ichpFormat index into gchp table
vcpFetch first cp of current run
vfli.cpMin first cp of line
ifi.ich ???
*/
/* since LoadFont could change vchpAbs, and we don't want
that to happen, we copy vchpAbs into vchpLocal and use
vchpLocal in place of vchpAbs hereafter. Note that vchpAbs
is intentionally used above for handling the endmark. */
blt(&vchpAbs, &chpLocal, cwCHP);
if (fFlmPrinting)
{
LoadFont(doc, &chpLocal, mdFontPrint);
dypAscent = vfmiPrint.dypAscent + vfmiPrint.dypLeading;
dypDescent = vfmiPrint.dypDescent;
#ifdef DBCS /* was in JAPAN */
dypPAscent = vfmiPrint.dypAscent;
dypLeading = vfmiPrint.dypLeading;
dypIntLeading = vfmiPrint.dypIntLeading;
#endif
}
else
{
LoadFont(doc, &chpLocal, mdFontJam);
dypAscent = vfmiScreen.dypAscent + vfmiScreen.dypLeading;
dypDescent = vfmiScreen.dypDescent;
#ifdef DBCS /* was in JAPAN */
dypPAscent = vfmiScreen.dypAscent;
dypLeading = vfmiScreen.dypLeading;
dypIntLeading = vfmiScreen.dypIntLeading;
#endif
}
#ifdef ENABLE /* BRYANL 8/27/87: New philosophy for handling
font selection failures is: font selection
ALWAYS succeeds. This prevents FormatLine
returns that do not advance. */
/* Bail out if there is a memory failure. */
if (vfOutOfMemory)
{
goto DoBreak;
}
#endif /* ENABLE */
/* Floating line size algorithm */
if (chpLocal.hpsPos != 0)
{
/* Modify font for subscript/superscript */
if (chpLocal.hpsPos < hpsNegMin)
{
dypAscent += ypSubSuperFormat;
#ifdef DBCS /* was in JAPAN */
dypPAscent += ypSubSuperFormat;
#endif
}
else
{
dypDescent += ypSubSuperFormat;
}
}
/* Update the maximum ascent and descent of the line. */
fSizeChanged = FALSE;
if (dypDescentMac < dypDescent)
{
dypDescentMac = dypDescent;
fSizeChanged = TRUE;
}
if (dypAscentMac < dypAscent)
{
dypAscentMac = dypAscent;
fSizeChanged = TRUE;
}
#ifdef DBCS /* was in JAPAN */
if (dypPAscentMac < dypPAscent)
{
dypPAscentMac = dypPAscent;
fSizeChanged = TRUE;
}
if (dypIntLeadingMac < dypIntLeading)
{
dypIntLeadingMac = dypIntLeading;
fSizeChanged = TRUE;
}
if (dypLeadingMac < dypLeading)
{
dypLeadingMac = dypLeading;
fSizeChanged = TRUE;
}
#endif
if (fSizeChanged)
{
#ifdef AUTO_SPACING
/* This is the original Mac Word code that assumed line spacing
of 0 in a PAP meant auto line spacing. PC Word defaults to 1
line invalidating this assumption. */
if (ppap->dyaLine == 0)
{
#ifdef CASHMERE
ifi.dypLineSize = dypDescentMac + dypAscentMac + dypBefore;
#else /* not CASHMERE */
ifi.dypLineSize = dypDescentMac + dypAscentMac;
#endif /* not CASHMERE */
}
else
{
#ifdef CASHMERE
ifi.dypLineSize = imax(MultDiv(ppap->dyaLine, dypFormat,
dyaFormat) + dypBefore, dypBefore + 1);
#else /* not CASHMERE */
ifi.dypLineSize = imax(MultDiv(ppap->dyaLine, dypFormat,
dyaFormat), 1);
#endif /* not CASHMERE */
}
#else /* not AUTO_SPACING */
/* This code forces auto line spacing except in the case where
the user specifies a line spacing greater than the auto line
spacing. */
{
#ifdef DBCS /* was in JAPAN */
#if defined(TAIWAN) || defined(PRC)
register int dypAuto = dypDescentMac + dypAscentMac;
if (ppap->dyaLine > czaLine)
{
register int dypUser = imax(MultDiv(ppap->dyaLine,
dypFormat, dyaFormat), 1);
ifi.dypLineSize = max(dypAuto, dypUser);
}
else
{
ifi.dypLineSize = dypAuto;
}
#else /* TAIWAN */
register int dypAuto = dypDescentMac + dypAscentMac;
int cHalfLine;
int dypSingle = dypPAscentMac + dypDescentMac;
cHalfLine = (ppap->dyaLine + (czaLine / 4)) / (czaLine / 2);
ifi.dypLineSize = (cHalfLine == 3) ? (dypSingle*3)/2 :
((cHalfLine <= 2) ?
dypSingle :
(dypSingle * 2));
#endif /* TAIWAN */
#else // DBCS
#ifdef CASHMERE
register int dypAuto = dypDescentMac + dypAscentMac +
dypBefore;
#else /* not CASHMERE */
register int dypAuto = dypDescentMac + dypAscentMac;
#endif /* not CASHMERE */
if (ppap->dyaLine > czaLine)
{
#ifdef CASHMERE
register int dypUser = imax(MultDiv(ppap->dyaLine,
dypFormat, dyaFormat) + dypBefore, dypBefore + 1);
#else /* not CASHMERE */
register int dypUser = imax(MultDiv(ppap->dyaLine,
dypFormat, dyaFormat), 1);
#endif /* not CASHMERE */
ifi.dypLineSize = max(dypAuto, dypUser);
}
else
{
ifi.dypLineSize = dypAuto;
}
#endif /* DBCS */
}
#endif /* not AUTO_SPACING */
}
OldRun:
/* Calculate length of the run but no greater than 256 */
iichNew = (int)(vcpFetch - vfli.cpMin);
if (iichNew >= ichMaxLine)
{
iichNew = ichMaxLine - 1;
}
dich = iichNew - ifi.ich;
/* Ensure that all tab and non-required hyphen characters start at
beginning of run */
if (ichpFormat <= 0 || dich > 0 || CchDiffer(&chpLocal,
&(**vhgchpFormat)[ichpFormat - 1], cchCHPUsed) != 0 || *pch ==
chTab || *pch == chNRHFile)
{
#ifdef DFLI
if (*pch == chNRHFile)
CommSz("CHNRHFILE at beginning of run");
#endif
if (ichpFormat != ichpMacFormat || FGrowFormatHeap())
{
register struct CHP *pchp = &(**vhgchpFormat)[ichpFormat -
1];
if (ichpFormat > 0)
{
pchp->cchRun = ifi.ich - ifi.ichPrev;
pchp->ichRun = ifi.ichPrev;
}
blt(&chpLocal, ++pchp, cwCHP);
#ifdef ENABLE /* font codes */
pchp->ftc = vftc;
pchp->ftcXtra = (vftc & 0x01c0) >> 6;
pchp->hps = vhps;
#endif /* ENABLE */
pchp->cchRun = ichMaxLine;
if (dich <= 0)
{
pchp->ichRun = ifi.ich;
}
else
{
/* Q&D insert */
bltc(&vfli.rgdxp[ifi.ich], 0, dich);
bltbc(&vfli.rgch[ifi.ich], 0, dich);
pchp->ichRun = ifi.ich = iichNew;
}
ifi.ichPrev = ifi.ich;
ichpFormat++;
}
}
if (vcpFetch >= cpMac)
{
/* End of doc reached */
if (!ifi.fPrevSpace || vcpFetch == cp)
{
vfli.ichReal = ifi.ich;
vfli.xpReal = ifi.xpReal = ifi.xp;
}
/* T-HIROYN sync fromat.asm */
/* if (!fFlmPrinting && (doc != docHelp))*/
if (!fFlmPrinting)
{
/*
* Write 3.1j endmark is 1-bytecharcter
* t-Yoshio May 26,92
*/
#if defined(JAPAN) || defined(KOREA)
vfli.rgch[ifi.ich] = chEMark;
vfli.xpReal += (vfli.rgdxp[ifi.ich++] = DxpFromCh(chEMark,
false));
#else
#ifdef DBCS /* was in JAPAN */
/* We use Double byte character to chEMark in Japan */
if (ifi.ich + cchKanji > ichMaxLine) {
/* vfli.rgch has no room for the two-byte
end mark. Too bad do the break and
wait for the next time around. */
goto DoBreak;
}
vfli.rgch[ifi.ich] = chMark1;
vfli.xpReal += (vfli.rgdxp[ifi.ich++] = DxpFromCh(chMark1,
false));
vfli.rgch[ifi.ich] = chEMark;
vfli.rgdxp[ifi.ich++] = 0;
#if !defined(TAIWAN) && !defined(PRC)
ifi.dypLineSize += 2;
#endif
#else /* DBCS */
vfli.rgch[ifi.ich] = chEMark;
vfli.xpReal += (vfli.rgdxp[ifi.ich++] = DxpFromCh(chEMark,
false));
#endif
#endif /*JAPAN*/
}
vfli.dypLine = ifi.dypLineSize;
vfli.dypBase = dypDescentMac;
vfli.dypFont = dypAscentMac + dypDescentMac;
vfli.ichMac = vfli.ichReal = ifi.ich;
vfli.cpMac = cpMac + 1;
goto JustEol; /* dcpDepend == 0 */
}
/* Here we have ifi.ich, cch */
if (ifi.ich + cch > ichMaxLine)
/* If this run would put the line over 255, truncate it and set a
flag. */
{
cch = ichMaxLine - ifi.ich;
fTruncated = true;
}
ifi.ichFetch = 0;
#ifdef CASHMERE
if (chpLocal.csm != csmNormal)
{
int ich;
CHAR *pchT = &rgchSmcap[0];
/* We can handle only a run of cchSmcapMax small capital
characters. If the run is larger then truncate. */
if (cch > cchSmcapMax)
{
cch = cchSmcapMax;
fTruncated = true;
}
/* Raise the case of the characters. */
for (ich = 0 ; ich < cch ; ich++)
{
*pchT++ = ChUpper(*pch++);
}
pch = &rgchSmcap[0];
}
#endif /* CASHMERE */
/* Do "special" characters here */
if (chpLocal.fSpecial)
{
if (!FFormatSpecials(&ifi, flm, vsepAbs.nfcPgn))
{
if (ifi.chBreak == 0 ) /* No breaks in this line */
{
goto Unbroken;
}
else
{
vfli.dcpDepend = vcpFetch + ifi.ichFetch - vfli.cpMac;
goto JustBreak;
}
}
}
continue;
}
/* End of new run treatment. We are back in the "for every character"
section. */
{
register int ch = pch[ifi.ichFetch++];
NormChar:
#ifdef DBCS
/* Unless it is a kanji space, we only need to adjust
by 1 byte. */
dichSpaceAdjust = 1;
#endif
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
if (ch == chSpace && vfWordWrap)
#else
if (ch == chSpace)
#endif
{
/* Speed kludge for spaces */
ifi.xp += (vfli.rgdxp[ifi.ich] = dxp =
fFlmPrinting ? vfmiPrint.dxpSpace : vfmiScreen.dxpSpace);
ifi.xpPr += (dxpPr = vfmiPrint.dxpSpace);
vfli.rgch[ifi.ich++] = chSpace;
#ifdef DFLI
{
char rgch[100];
wsprintf(rgch," chSpace , xp==%d/%d, xpPr==%d/%d",
ifi.xp, ifi.xpRight, ifi.xpPr, ifi.xpPrRight);
CommSz(rgch);
}
#endif
goto BreakOppr;
}
#ifndef TEMP_KOREA
/* If the printer width is not in the printer width table, then get
it. */
if (ch < chFmiMin || ch >= chFmiMax || (dxpPr =
vfmiPrint.mpchdxp[ch]) == dxpNil)
{
#ifdef DBCS
/* Don't pass to DxpFromCh() DBCS LeadByte except for '8140H'.
** Because the function can make elleagal ShiftJIS and pass it
** to GetTextExtent(). GetTextExtent might return SBC space
** when the code is undefined. this will cause win-hang-up at
** formatting line. yutakan
*/
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
dxpPr=DBCSDxpFromCh(ch, ( ((cp + ifi.ich) < cpMac) ?
pch[ifi.ichFetch] : 0 ), TRUE);
#else
dxpPr=DBCSDxpFromCh(ch,pch[ifi.ichFetch],TRUE);
#endif //TAIWAN
#else
dxpPr = DxpFromCh(ch, TRUE);
#endif
}
if (fFlmPrinting)
{
/* If we are printing, then there is no need to bother with the
screen width. */
dxp = dxpPr;
}
else if (ch < chFmiMin || ch >= chFmiMax ||
(dxp = vfmiScreen.mpchdxp[ch]) == dxpNil)
#ifdef DBCS
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
dxp = DBCSDxpFromCh(ch, ( ((cp + ifi.ich) < cpMac) ?
pch[ifi.ichFetch] : 0 ), FALSE);
#else
// yutakan:
dxp = DBCSDxpFromCh(ch,pch[ifi.ichFetch],FALSE);
#endif //TAIWAN
#else
dxp = DxpFromCh(ch, FALSE);
#endif /* ifdef DBCS */
#endif /* ifndef KOREA */
#ifdef DBCS /* was in JAPAN */
//solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
//#ifdef TAIWAN
// if (IsDBCSLeadByte(ch) && !pch[ifi.ichFetch]) {
// ifi.xp += (vfli.rgdxp[ifi.ich] = (dxp/2));
// ifi.xpPr += (dxpPr/2);
// vfli.rgch[ifi.ich++] = ch;
// vfli.rgch[ifi.ich] = NULL;
// goto OnlyDBCSPaste;
// }
//#endif
/*T-HIROYN add from 3.0*/
ifi.xp += (vfli.rgdxp[ifi.ich] = dxp);
ifi.xpPr += dxpPr;
vfli.rgch[ifi.ich++] = ch;
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
// BUG 5477: Echen: add NON FA font, LeadByte + 2nd byte checking
if (((cp + ifi.ich) < cpMac) && IsDBCSLeadByte(ch) &&
GetFontAssocStatus(vhMDC)) {
#else
if (IsDBCSLeadByte(ch)) {
#endif //TAIWAN
CHAR ch2;
if (ifi.ich + 1 >= ichMaxLine) {
/* It's full. Do the break without this kanji character. */
#ifndef TEMP_KOREA
ifi.ich--;
#endif
ifi.ichFetch--; /* We don't want to skip the first byte. */
#ifndef TEMP_KOREA
ifi.xp -= dxp;
ifi.xpPr -= dxpPr;
#endif
lblFull2: /* new label of line full case ( for kanji and kana ) */
goto DoBreak;
}
/* Now all is well. Get the second byte of the kanji
character of interest from the current run. */
/* Get the second byte of the kanji character from
the current run. If we run of the current run,
use FetchRgch() to staple us over. */
#ifdef TEMP_KOREA /* for variable width, 90.12.26 by sangl */
vfli.rgch[ifi.ich++] = ch;
#endif
if (ifi.ichFetch == cch)
{
if (fTruncated)
{
cchUsed += cch;
pch = vpchFetch + cchUsed;
cch = vcchFetch - cchUsed;
fTruncated = false;
ch2 = vfli.rgch[ifi.ich] = pch[ifi.ichFetch++];
}
else {
int cchFetch;
/* Save parameters needed for the re-fetch. */
cpFetchSave = vcpFetch;
ichFetchSave = vichFetch;
cchUsedSave = cchUsed;
cpSeqFetch = vcpFetch + cch + 1;
FetchRgch(&cchFetch, &ch2, docNil, cpNil,
vcpFetch + cch + 1, 1);
fOddBoundary = true;
Assert(cchFetch != 0); /* Better fetched something for us. */
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
if ( !cchFetch ) goto SingleDBCS;
#endif //TAIWAN
/* Now, let's settle related parameters. */
pch = &ch2;
cch = cchFetch;
ifi.ichFetch = 1; /* == cch */
cchUsed = 0;
vfli.rgch[ifi.ich] = ch2;
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
//adjust DBCS char width by the new fetched 2nd byte
{
int dxpPr2, dxp2;
dxpPr2 = DBCSDxpFromCh(ch, ch2, TRUE);
if (fFlmPrinting) dxp2 = dxpPr2;
else dxp2 = DBCSDxpFromCh(ch, ch2, FALSE);
vfli.rgdxp[ifi.ich - 1] += (dxp2 - dxp);
ifi.xp += (dxp2 - dxp);
ifi.xpPr += (dxpPr2 - dxpPr);
}
#endif //TAIWAN
}
}
else
{
ch2 = vfli.rgch[ifi.ich] = pch[ifi.ichFetch++];
}
#ifdef TEMP_KOREA /* For variable width, 90.12.26 by sangl */
{ unsigned int wd;
wd = (ch<<8) + ch2;
dxpPr = DxpFromCh(wd, TRUE);
if (fFlmPrinting) /* if we are printing, then there is */
/* no need to bother with the screen width */
dxp = dxpPr;
else
dxp = DxpFromCh(wd, FALSE);
ifi.xp += (vfli.rgdxp[ifi.ich-1] = dxp);
ifi.xpPr += dxpPr;
vfli.rgdxp[ifi.ich++] = 0;
}
#else
vfli.rgdxp[ifi.ich++] = 0; /* The second byte has 0 width. */
#endif /* KOREA */
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
if (FKanjiSpace(ch, ch2) && vfWordWrap)
#else
if (FKanjiSpace(ch, ch2))
#endif
{
fKanjiPrevious = true;
fKanjiBreakOppr = false; /* Treat it like a regular space. */
dichSpaceAdjust = cchKanji;
goto BreakOppr;
}
if (ifi.xpPr > ifi.xpPrRight ) {
fKanjiBreakOppr = false; /* Reset the flag */
if (FAdmitCh2(ch, ch2) ||
(fKanjiPrevious && FOptAdmitCh2(ch, ch2))) {
/* We do a line break including this odd character. */
/* Make sure non-printables won't start a new line. */
/* If we already have a hanging character on the */
/* line, we don't want to treat this character as */
/* a hanging one. */
if (!fKanjiHanging )
{
fKanjiHanging = TRUE;
ch = chHyphen;
goto BreakOppr;
}
}
#ifndef JAPAN // added by Hiraisi (BUG#3542)
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
if(vfWordWrap)
#endif
ifi.ich--;
#endif
/* If this run was the result of an odd boundary run,
re-fetch. */
if (fOddBoundary && ifi.ichFetch == 1 )
{
FetchCp(doc, cpFetchSave, ichFetchSave,
fcmBoth + fcmParseCaps);
/* This fetch is guaranteed to result to non-null run. */
fOddBoundary = false;
pch = vpchFetch;
ifi.ichFetch = cch = vcchFetch;
#ifdef JAPAN // added by Hiraisi (BUG#3542)
ifi.ichFetch++;
#endif
cchUsed = cchUsedSave;
}
#ifndef JAPAN // added by Hiraisi (BUG#3542)
else
{
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
if(vfWordWrap)
#endif
ifi.ichFetch--;
}
#endif
/* ifi.xp and ifi.xpPr hasn't changed yet. */
goto lblFull2;
#ifdef TEMP_KOREA /* 90.12.26 : For variable width, 90.12.26 by sangl */
ifi.xp -= dxp;
ifi.xpPr -= dxpPr;
#endif /* KOREA */
}
#if defined(JAPAN) || defined(KOREA) // added 26 Jun. 1992 by Hiraisi
iWidenChar++;
#elif defined(TAIWAN) || defined(PRC)//Daniel/MSTC, 1993/02/25 , for jcBoth
iWidenChar++;
#endif
/* Record the line break opportunity while processing
it as a regular character at the same time. */
fKanjiBreakOppr = true;
fKanjiPrevious = true;
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
if(!vfWordWrap)
goto DefaultCh;
#endif
goto BreakOppr;
}
else {
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio add WordWrap flag*/
if (FKana(ch) && vfWordWrap) {
/* If it is a 1-byte kana letter, we want to treat it
in the same way as a kanji letter. */
if (ifi.xpPr > ifi.xpPrRight) {
fKanjiBreakOppr = false; /* Reset the flag */
if (FAdmitCh1(ch)) {
/* Make sure non-printables won't start a new line. */
/* If we already have a hanging character on the */
/* line, we don't want to treat this character as */
/* a hanging one. */
if (!fKanjiHanging) {
fKanjiHanging = TRUE;
ch = chHyphen;
goto BreakOppr;
}
}
goto lblFull2;
}
#if defined(JAPAN) || defined(KOREA) // added 22 Jun. 1992 by Hiraisi
iWidenChar++;
#elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25 , for jcBoth
iWidenChar++;
#endif
fKanjiPrevious = true;
fKanjiBreakOppr = true;
/* Go through the break opprotunity processing, then the
default character processing. */
goto BreakOppr;
}
else {
#endif /* JAPAN */
#ifdef TEMP_KOREA /* For variable width by sangl 90.12.26 */
if (ch < chFmiMin || ch >= chFmiMax || (dxpPr =
vfmiPrint.mpchdxp[ch]) == dxpNil)
{
dxpPr = DxpFromCh(ch, TRUE);
}
if (fFlmPrinting)
{
/* If we are printing, then there is no need to bother
with the screen width */
dxp = dxpPr;
}
else if (ch < chFmiMin || ch >= chFmiMax ||
(dxp = vfmiScreen.mpchdxp[ch]) == dxpNil)
dxp = dxpFromCh(ch, FALSE);
ifi.xp += (vfli.rgdxp[ifi.ich] = dxp);
ifi.xpPr += dxpPr;
vfli.rgch[ifi.ich++] = ch;
#endif /* KOREA */
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
SingleDBCS:
#endif //TAIWAN
if (fKanjiPrevious && FOptAdmitCh1(ch)) {
fKanjiPrevious = false;
if (ifi.xpPr > ifi.xpPrRight) {
fKanjiBreakOppr = false;
/* If we already have a hanging character past the
margin, we don't want to treat this as a
hanging character. */
if (!fKanjiHanging) {
fKanjiHanging = true;
ch = chHyphen;
goto BreakOppr;
}
}
else {
/* We can treat this character as though a Kanji
punctuation, as far as line breaking is
is concerned. */
fKanjiBreakOppr = true;
goto BreakOppr;
}
}
else {
/* Just go on with a regular English formatting. */
fKanjiBreakOppr = false;
fKanjiPrevious = false;
}
}
#if defined(JAPAN) || defined(KOREA)
}
#endif
#else /* DBCS */
ifi.xp += (vfli.rgdxp[ifi.ich] = dxp);
ifi.xpPr += dxpPr;
vfli.rgch[ifi.ich++] = ch;
#endif
#if defined (TAIWAN)
OnlyDBCSPaste:
#endif
/* special case "normal characters" above hyphen */
if (ch > chHyphen)
goto DefaultCh;
#if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
/*Non Word wrap Not Hyphen break*/
if(!vfWordWrap) {
if (ch == chHyphen)
goto DefaultCh;
}
#endif
switch (ch)
{
#ifdef CRLF
case chReturn:
/* Undo damage */
ifi.ich--;
ifi.xp -= dxp;
ifi.xpPr -= dxpPr;
continue;
#endif /* CRLF */
case chNRHFile:
/* Undo damage */
ifi.ich--;
ifi.xp -= dxp;
ifi.xpPr -= dxpPr;
ichpNRH = ichpFormat - 1;
#ifdef DFLI
{
char rgch[100];
wsprintf(rgch," OptHyph: width==%d, xpPr==%d/%d\n\r",
DxpFromCh(chHyphen,true), ifi.xpPr,ifi.xpPrRight);
CommSz(rgch);
}
#endif
if (ifi.xpPr + DxpFromCh(chHyphen, true) > ifi.xpPrRight)
{
/* Won't fit, force a break */
goto DoBreak;
}
#ifdef CASHMERE
else if (fVisiMode)
{
/* Treat just like a normal hyphen */
ch = chHyphen;
goto NormChar;
}
#endif /* CASHMERE */
xpPrev = ifi.xp;
vfli.rgch[ifi.ich] = chTab;
goto Tab0;
case chSect:
/* Undo damage */
ifi.ich--;
ifi.xp -= dxp;
ifi.xpPr -= dxpPr;
vfli.dypFont = vfli.dypLine = (dypAscentMac + (vfli.dypBase
= dypDescentMac));
vfli.cpMac = vcpFetch + ifi.ichFetch;
if (FFirstIch(ifi.ich))
{
/* Beginning of line; return a splat */
vfli.fSplat = true;
if (!fFlmPrinting)
{
#ifdef CASHMERE
int chT = vfli.cpMac == vcpLimSectCache ?
chSectSplat : chSplat;
#else /* not CASHMERE */
int chT = chSplat;
#endif /* not CASHMERE */
int dxpCh = DxpFromCh(chT, false);
/* Set the width of the splat to be about 8.5" */
int cch = min((dxpLogInch * 17 / 2) / dxpCh,
ichMaxLine - 32);
bltbc(&vfli.rgch[ifi.ich], chT, cch);
bltc(&vfli.rgdxp[ifi.ich], dxpCh, cch);
vfli.ichMac = cch + ifi.ich;
vfli.xpReal = LOWORD(GetTextExtent(vhMDC,
(LPSTR)vfli.rgch, cch));
vfli.xpLeft = 0;
}
else
{
vfli.ichMac = 0;
}
goto EndFormat;
}
/* The section character is in the middle of a line, the
line will terminate in front of the character. */
/* vfSplatNext = TRUE; No longer used*/
vfli.cpMac += cchUsed - 1;
vfli.dcpDepend = 1;
if (!ifi.fPrevSpace)
{
ifi.cBreak = ifi.cchSpace;
vfli.ichReal = ifi.ich;
vfli.xpReal = ifi.xpReal = ifi.xp;
}
vfli.ichMac = ifi.ich;
vfli.dypLine = ifi.dypLineSize;
goto JustBreak;
case chTab:
/* Undo damage */
ifi.ich--;
ifi.xp -= dxp;
ifi.xpPr -= dxpPr;
if (ifi.xpPr < ifi.xpPrRight)
{
register struct CHP *pchp;
unsigned xaPr;
unsigned xaTab;
if (!ifi.fPrevSpace)
{
/* Remember number of spaces to left and number of
real chars in line for justification */
ifi.cBreak = ifi.cchSpace;
vfli.ichReal = ifi.ich;
ifi.xpReal = ifi.xp;
}
if (ifi.jc != jcTabLeft)
{
Justify(&ifi, xpTab, flm);
}
xpPrev = ifi.xp;
/* Now get info about this tab */
xaPr = MultDiv(ifi.xpPr, dxaPrPage, dxpPrPage);
while ((xaTab = ptbd->dxa) != 0)
{
#ifdef DBCS /* was in JAPAN */
if (xaTab >= xaRight)
#else
if (xaTab > xaRight)
#endif
{
/* Don't let tabs extend past right margin. */
#ifdef DBCS /* was in JAPAN */
break; // Stop to examin next tab-stop
#else
xaTab = xaRight;
#endif
}
if (xaTab >= xaPr)
{
/* Use tab stop information */
#ifdef CASHMERE
ifi.tlc = ptbd->tlc;
#endif /* CASHMERE */
ifi.jc = jcTabMin + (ptbd++)->jc;
#ifdef ENABLE /* we do the mapping in HgtbdCreate */
if (ifi.jc != jcTabDecimal)
{
ifi.jc = jcTabLeft;
}
#endif
goto TabFound;
}
ptbd++;
}
/* Out of set tabs; go to next nth column */
xaTab = (xaPr / (vzaTabDflt) + 1) * (vzaTabDflt);
#ifdef CASHMERE
ifi.tlc = tlcWhite;
#endif /* CASHMERE */
ifi.jc = jcTabLeft;
TabFound:
xpTab = imax(MultDiv(xaTab, dxpFormat, dxaFormat),
ifi.xp);
/* Do left-justified tabs immediately */
if (ifi.jc == jcTabLeft)
{
ifi.xp = xpTab;
ifi.xpPr = MultDiv(xaTab, dxpPrPage, dxaPrPage);
}
ifi.xpLeft = ifi.xp;
ifi.ichLeft = ifi.ich;
ifi.cchSpace = 0;
ifi.chBreak = 0;
#if defined(JAPAN) || defined(KOREA) // added 02 Jul. 1992 by Hiraisi
iWidenChar=0;
#elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
iWidenChar=0;
#endif
Tab0:
ifi.fPrevSpace = false;
vfli.ichMac = ifi.ich;
vfli.xpReal = ifi.xp;
vfli.dypLine = ifi.dypLineSize;
vfli.dypBase = dypDescentMac;
vfli.dypFont = dypAscentMac + dypDescentMac;
if (ifi.ichFetch != 1 && (ichpFormat != ichpMacFormat
|| FGrowFormatHeap()))
{
/* Probably in real trouble if FGrowFormatHeap fails
at this point */
pchp = &(**vhgchpFormat)[ichpFormat - 1];
if (ichpFormat > 0)
{
/* Finish off previous run */
pchp->ichRun = ifi.ichPrev;
pchp->cchRun = ifi.ich - ifi.ichPrev;
}
blt(&chpLocal, ++pchp, cwCHP);
ichpFormat++;
}
else
{
pchp = &(**vhgchpFormat)[ichpFormat - 1];
}
pchp->ichRun = ifi.ich;
pchp->cchRun = ichMaxLine;
#ifdef CASHMERE
pchp->chLeader = mptlcch[ifi.tlc];
#endif /* CASHMERE */
vfli.rgdxp[ifi.ichPrev = ifi.ich++] = ifi.xp - xpPrev;
if (ch != chTab)
{
/* This character is a non-required hyphen. */
Dfli(CommSz("ch is really OptHyph "));
goto BreakOppr;
}
continue;
}
else
{
ch = chNBSFile;
goto NormChar;
}
case chHyphen:
if (ifi.xpPr > ifi.xpPrRight)
{
goto DoBreak;
}
BreakOppr:
Dfli(CommSz(" BKOPPR\n\r"));
/* this case never used in switch - always goto here */
/* case chSpace: */
if (ifi.ich >= ichMaxLine)
{
Dfli(CommSzNum(" Unbroken, ich>ichMaxLine\n\r"));
goto Unbroken;
}
case chEol:
case chNewLine:
ifi.chBreak = ch;
vfli.cpMac = vcpFetch + cchUsed + ifi.ichFetch;
vfli.xpReal = ifi.xp;
vfli.ichMac = ifi.ich;
vfli.dypLine = ifi.dypLineSize;
vfli.dypFont = dypAscentMac + (vfli.dypBase =
dypDescentMac);
Dfli(CommSzNumNum(" vfli.xpReal, ichMac ",vfli.xpReal,vfli.ichMac));
#ifdef DBCS /* was in JAPAN */
/* We recorded the kanji break opportunity, go default
character processing. */
if (fKanjiBreakOppr)
{
ifi.cBreak = ifi.cchSpace;
vfli.ichReal = ifi.ich;
vfli.xpReal = ifi.xpReal = ifi.xp;
goto DefaultCh;
}
#endif
if (ch == chHyphen || ch == chNRHFile)
{
Dfli(CommSz(" chHyph/OptHyph catch \n\r"));
ifi.cBreak = ifi.cchSpace;
vfli.ichReal = ifi.ich;
vfli.xpReal = ifi.xpReal = ifi.xp;
}
else
{
if (!ifi.fPrevSpace)
{
Dfli(CommSz("!fPrevSpace \n\r"));
ifi.cBreak = ifi.cchSpace;
#ifdef DBCS /* was in JAPAN */
vfli.ichReal = ifi.ich - dichSpaceAdjust;
dichSpaceAdjust = 1;
#else
vfli.ichReal = ifi.ich - 1;
#endif
ifi.xpReal = (vfli.xpReal = ifi.xp) - dxp;
}
if (ch == chEol || ch == chNewLine)
{
#ifdef CASHMERE
if (hfntb != 0 && vfli.cpMac ==
(**hfntb).rgfnd[0].cpFtn)
{
/* End of footnote */
if (!fFlmPrinting)
{
vfli.rgch[ifi.ich - 1] = chEMark;
vfli.xpReal += (vfli.rgdxp[ifi.ich - 1] =
DxpFromCh(chEMark, false)) - dxp;
vfli.ichReal++; /* show this guy */
}
}
else
#endif /* CASHMERE */
{
#ifdef CASHMERE
int chT = fVisiMode ? ChVisible(ch) : chSpace;
#else /* not CASHMERE */
int chT = chSpace;
#endif /* not CASHMERE */
int dxpNew = DxpFromCh(chT, fFlmPrinting);
vfli.rgch[ifi.ich - 1] = chT;
vfli.rgdxp[ifi.ich - 1] = dxpNew;
vfli.xpReal += (vfli.rgdxp[ifi.ich - 1] =
dxpNew) - dxp;
if (!ifi.fPrevSpace)
{
vfli.xpReal += dxpNew - dxp;
#ifdef CASHMERE
vfli.ichReal =
fVisiMode ? ifi.ich : ifi.ich - 1;
#else /* not CASHMERE */
vfli.ichReal = ifi.ich - 1;
#endif /* not CASHMERE */
}
}
if (ch == chEol)
{
JustEol:
if (fFlmPrinting)
{
vfli.ichMac = vfli.ichReal;
}
if (ifi.jc != jcTabLeft)
{
/* Handle last tab's text */
Justify(&ifi, xpTab, flm);
}
else if ((ifi.jc = ppap->jc) != jcBoth &&
ifi.jc != jcLeft)
{
/* Do line justification */
Justify(&ifi, ifi.xpRight, flm);
}
vfli.xpRight = ifi.xpRight;
goto EndFormat;
}
else
{
/* Handle a line break */
goto JustBreak;
}
}
++ifi.cchSpace;
ifi.fPrevSpace = true;
}
break;
DefaultCh:
default:
#ifdef DFLI
{
char rgch[100];
wsprintf(rgch," DefaultCh: %c, xp==%d/%d, xpPr==%d/%d\n\r",
ch, ifi.xp, ifi.xpRight, ifi.xpPr, ifi.xpPrRight);
CommSz(rgch);
}
#endif /* ifdef DFLI */
#ifdef DBCS /* was in JAPAN */
/* Reset the flag for the next character. */
fKanjiBreakOppr = false;
#endif
if (ifi.xpPr > ifi.xpPrRight)
DoBreak:
{
Dfli(CommSz(" BREAK!\n\r"));
if (ifi.chBreak == 0)
Unbroken:
{
/* Admit first character to the line, even if margin
is crossed. First character at ifi.ich - 1 may be
preceded by 0 width characters. */
#ifdef DBCS
if (IsDBCSLeadByte(ch))
{
if (FFirstIch(ifi.ich-2) && ifi.ich<ichMaxLine)
goto PChar;
vfli.cpMac = vcpFetch+cchUsed+ifi.ichFetch-2;
vfli.ichReal = vfli.ichMac = ifi.ich - 2;
vfli.dypLine = ifi.dypLineSize;
vfli.dypFont = dypAscentMac + (vfli.dypBase =
dypDescentMac);
vfli.dcpDepend = 1;
#ifdef KKBUGFIX /*t-Yoshio*/
vfli.xpReal = ifi.xpReal = ifi.xp - dxp;
#else
vfli.xpReal = ifi.xpReal = ifi.xp - (dxp * 2);
#endif
}
else
{
if (FFirstIch(ifi.ich-1) && ifi.ich<ichMaxLine)
goto PChar;
vfli.cpMac = vcpFetch+cchUsed+ifi.ichFetch-1;
vfli.ichReal = vfli.ichMac = ifi.ich - 1;
vfli.dypLine = ifi.dypLineSize;
vfli.dypFont = dypAscentMac + (vfli.dypBase =
dypDescentMac);
vfli.dcpDepend = 1;
vfli.xpReal = ifi.xpReal = ifi.xp - dxp;
}
#else
if (FFirstIch(ifi.ich - 1) && ifi.ich < ichMaxLine)
{
goto PChar;
}
vfli.cpMac = vcpFetch + cchUsed + ifi.ichFetch - 1;
vfli.ichReal = vfli.ichMac = ifi.ich - 1;
vfli.dypLine = ifi.dypLineSize;
vfli.dypFont = dypAscentMac + (vfli.dypBase =
dypDescentMac);
vfli.dcpDepend = 1;
vfli.xpReal = ifi.xpReal = ifi.xp - dxp;
#endif
goto DoJustify;
}
vfli.dcpDepend = vcpFetch + ifi.ichFetch - vfli.cpMac;
JustBreak:
if (ifi.chBreak == chNRHFile)
{
/* Append a non-required hyphen to the end of the
line. (Replace zero length tab previously
inserted) */
Dfli(CommSz(" Breaking line at OptHyphen\n\r"));
ifi.xpReal += (vfli.rgdxp[vfli.ichReal - 1] =
DxpFromCh(chHyphen, fFlmPrinting));
vfli.xpRight = vfli.xpReal = ifi.xpReal;
vfli.rgch[vfli.ichReal - 1] = chHyphen;
vfli.ichMac = vfli.ichReal;
if (ichpNRH < ichpFormat - 1)
{
register struct CHP *pchp =
&(**vhgchpFormat)[ichpNRH];
pchp->cchRun++;
if (pchp->ichRun >= vfli.ichMac)
{
pchp->ichRun = vfli.ichMac - 1;
}
}
}
if (fFlmPrinting)
{
vfli.ichMac = vfli.ichReal;
}
if (ifi.jc != jcTabLeft)
{
Justify(&ifi, xpTab, flm);
}
else
{
DoJustify:
if ((ifi.jc = ppap->jc) != jcLeft)
{
Dfli(CommSzNum(" DoJustify: xpRight ",ifi.xpRight));
Justify(&ifi, ifi.xpRight, flm);
}
}
vfli.xpRight = ifi.xpRight;
EndFormat:
vfli.ichLastTab = ifi.ichLeft;
#ifdef CASHMERE
if (vfli.cpMac == vcpLimParaCache)
{
vfli.dypAfter = vpapAbs.dyaAfter / DyaPerPixFormat;
vfli.dypLine += vfli.dypAfter;
vfli.dypBase += vfli.dypAfter;
}
#endif /* CASHMERE */
Scribble(5, ' ');
return;
}
else
{
PChar:
/* A printing character */
ifi.fPrevSpace = false;
}
break;
} /* Switch */
#ifdef DBCS /* was in KKBUGFIX */
//
// [yutakan:04/02/91]
//
if(vfOutOfMemory == TRUE)
return;
#endif
}
} /* for ( ; ; ) */
Scribble(5, ' ');
}
/* J U S T I F Y */
near Justify(pifi, xpTab, flm)
struct IFI *pifi;
unsigned xpTab;
int flm;
{
int dxp;
int ichT;
int xpLeft;
// justified paragraph is restored in Windows 3.1J by Hiraisi
//#ifdef JAPAN
// /* In the Kanji Write, there is no justified paragraph. */
// if (pifi->jc == jcBoth)
// {
// /* Assert(FALSE); */
// pifi->jc = jcLeft;
// dxp = 0; /* by yutakan / 08/03/91 */
// }
//#endif /* ifdef JAPAN */
xpLeft = pifi->xpLeft;
switch (pifi->jc)
{
CHAR *pch;
unsigned *pdxp;
#ifdef CASHMERE
case jcTabLeft:
case jcLeft:
return;
case jcTabRight:
dxp = xpTab - pifi->xpReal;
break;
case jcTabCenter:
dxp = (xpTab - xpLeft) - ((pifi->xpReal - xpLeft + 1) >> 1);
break;
#endif /* CASHMERE */
case jcTabDecimal:
dxp = xpTab - xpLeft;
for (ichT = pifi->ichLeft + 1; ichT < vfli.ichReal &&
vfli.rgch[ichT] != vchDecimal; ichT++)
{
dxp -= vfli.rgdxp[ichT];
}
break;
case jcCenter:
if ((dxp = xpTab - pifi->xpReal) <= 0)
{
return;
}
dxp = dxp >> 1;
break;
case jcRight:
dxp = xpTab - pifi->xpReal;
break;
case jcBoth:
//#if !defined(JAPAN) // added 22 Jun. 1992 by Hiraisi
#if !defined(JAPAN) && !defined(TAIWAN) && !defined(PRC) // Daniel/MSTC, 1993/02/25, for jcBoth
if (pifi->cBreak == 0)
{
/* Ragged edge forced */
return;
}
#endif
if ((dxp = xpTab - pifi->xpReal) <= 0)
{
/* There is nothing to do. */
return;
}
//#if !defined(JAPAN) // added 22 Jun. 1992 by Hiraisi
#if !defined(JAPAN) && !defined(TAIWAN) && !defined(PRC)//Daniel/MSTC, 1992,02,25, for jcBoth
pifi->xp += dxp;
vfli.xpReal += dxp;
vfli.dxpExtra = dxp / pifi->cBreak;
#endif
/* Rounding becomes a non-existant issue due to brilliant
re-thinking.
"What a piece of work is man
How noble in reason
In form and movement,
how abject and admirable..."
Bill "Shake" Spear [describing Sand Word] */
{
#ifdef JAPAN // added 22 Jun. 1992 by Hiraisi
/*
* In Japan, we examine the buffer from the beginning of the line.
* We find some NULLs in the buffer when a char is deleted,
* but we can ignore all of them.
*/
register CHAR *pch;
register int *pdxp;
CHAR *endPt;
int dxpT = dxp;
int cxpQuotient;
int cNonWideSpaces;
int ichLeft;
if( pifi->ichLeft >= 0 ) /* including some tabs in line */
ichLeft = pifi->ichLeft;
else
ichLeft = 0;
pch = &vfli.rgch[ichLeft];
pdxp = &vfli.rgdxp[ichLeft];
endPt = &vfli.rgch[vfli.ichReal];
if( vfWordWrap ){ /* Word Wrap ON */
/*
* We examine whether there is no break between a non-Japanese
* char and a following Japanese char. The reason is that we
* need to widen the non-Japanese char (except tab and space)
* if we can find no break there.
*/
for( ; pch<endPt ; ){
if( IsDBCSLeadByte( *pch ) ){
pch+=2;
}
else{
if( *pch != chSpace && *pch != chTab &&
!FKana( *pch ) && *pch != NULL ){
CHAR *ptr;
for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
if( IsDBCSLeadByte(*ptr) ){
iWidenChar++;
pch+=2;
}
else{
if( FKana(*ptr) ){
iWidenChar++;
pch++;
}
}
}
pch++;
}
}
/*
* We decrease iWidenChar if last char of the current line
* is Japanese, because it needs not to be widened.
*/
if( *(endPt-1) == NULL ){
for( endPt-- ; *endPt==NULL ; endPt-- );
endPt++;
}
if( IsDBCSLeadByte(*(endPt-2)) ){
iWidenChar--;
}
else{
if( FKana(*(endPt-1)) )
iWidenChar--;
}
iWidenChar += pifi->cBreak;
}
else{ /* Word Wrap OFF */
/* We widen all chars except last char in the line. */
int iDBCS, ichReal;
for( iDBCS=0, ichReal=vfli.ichReal ; pch<endPt ; pch++ ){
if( IsDBCSLeadByte( *pch ) ){
pch++;
iDBCS++;
}
else{
if( *pch == NULL )
ichReal--;
}
}
iWidenChar = ichReal - ichLeft - iDBCS - 1;
}
if( iWidenChar == 0 )
return;
pifi->xp += dxp;
vfli.xpReal += dxp;
vfli.dxpExtra = dxp / iWidenChar;
cNonWideSpaces = iWidenChar - (dxp % iWidenChar);
cxpQuotient = vfli.dxpExtra;
iNonWideSpaces = cNonWideSpaces;
vfli.ichFirstWide = 0;
vfli.fAdjSpace = fTrue;
pch = &vfli.rgch[ichLeft]; /* Reset pch */
for( ; ; ){
if( IsDBCSLeadByte(*pch) ){
if( vfli.ichFirstWide == 0 ){
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 )
return;
if( --cNonWideSpaces == 0 )
cxpQuotient++;
pch++;
pdxp++;
}
else{
if( vfWordWrap ){ /* Word Wrap ON */
if( *pch == chSpace || FKana(*pch) ){
if( vfli.ichFirstWide == 0 ){
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 )
return;
if( --cNonWideSpaces == 0 )
cxpQuotient++;
}
else{
if( *pch != chTab && *pch != NULL ){
CHAR *ptr;
/*
* We examine whether the following char of
* non-Japanese char is Japanese.
*/
for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
if( IsDBCSLeadByte(*ptr) || FKana(*ptr) ){
if( vfli.ichFirstWide == 0 ){
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 )
return;
if( --cNonWideSpaces == 0 )
cxpQuotient++;
}
}
}
}
else{ /* Word Wrap OFF */
if( *pch != NULL ){
if( vfli.ichFirstWide == 0 ){
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 )
return;
if( --cNonWideSpaces == 0 )
cxpQuotient++;
}
}
}
pch++;
pdxp++;
}
#elif defined(TAIWAN) || defined(PRC)//Daniel/MSTC, 1992/02/25, for jcBoth
/*
* In Japan, we examine the buffer from the beginning of the line.
* We find some NULLs in the buffer when a char is deleted,
* but we can ignore all of them.
*/
register CHAR *pch;
register int *pdxp;
CHAR *endPt;
int dxpT = dxp;
int cxpQuotient;
int cNonWideSpaces;
int ichLeft;
if( pifi->ichLeft >= 0 ) /* including some tabs in line */
ichLeft = pifi->ichLeft;
else ichLeft = 0;
pch = &vfli.rgch[ichLeft];
pdxp = &vfli.rgdxp[ichLeft];
endPt = &vfli.rgch[vfli.ichReal];
// if( vfWordWrap ){ /* Word Wrap ON */
/*
* We examine whether there is no break between a non-Japanese
* char and a following Japanese char. The reason is that we
* need to widen the non-Japanese char (except tab and space)
* if we can find no break there.
*/
for( ; pch<endPt ; )
{
if( IsDBCSLeadByte( *pch ) ) pch+=2;
else
{
if( *pch != chSpace && *pch != chTab && !FKana( *pch ) && *pch != NULL )
{ CHAR *ptr;
for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
if( IsDBCSLeadByte(*ptr) )
{
iWidenChar++;
pch+=2;
}
else
{
if( FKana(*ptr) )
{
iWidenChar++;
pch++;
}
}
}
pch++;
}
}// for
/*
* We decrease iWidenChar if last char of the current line
* is Japanese, because it needs not to be widened.
*/
if( *(endPt-1) == NULL )
{
for( endPt-- ; *endPt==NULL ; endPt-- );
endPt++;
}
if( IsDBCSLeadByte(*(endPt-2)) ) iWidenChar--;
else
{
if( FKana(*(endPt-1)) ) iWidenChar--;
}
iWidenChar += pifi->cBreak;
// } // vfWordWrap
if( iWidenChar == 0 )
return;
pifi->xp += dxp;
vfli.xpReal += dxp;
vfli.dxpExtra = dxp / iWidenChar;
cNonWideSpaces = iWidenChar - (dxp % iWidenChar);
cxpQuotient = vfli.dxpExtra;
iNonWideSpaces = cNonWideSpaces;
vfli.ichFirstWide = 0;
vfli.fAdjSpace = fTrue;
pch = &vfli.rgch[ichLeft]; /* Reset pch */
for( ; ; )
{
if( IsDBCSLeadByte(*pch) )
{
if( vfli.ichFirstWide == 0 )
{
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 ) return;
if( --cNonWideSpaces == 0 ) cxpQuotient++;
pch++;
pdxp++;
}
else
{
// if( vfWordWrap )
if( 1 )
{ /* Word Wrap ON */
if( *pch == chSpace || FKana(*pch) )
{
if( vfli.ichFirstWide == 0 )
{
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 ) return;
if( --cNonWideSpaces == 0 ) cxpQuotient++;
}
else
{
if( *pch != chTab && *pch != NULL )
{
CHAR *ptr;
/*
* We examine whether the following char of
* non-Japanese char is Japanese.
*/
for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
if( IsDBCSLeadByte(*ptr) || FKana(*ptr) )
{
if( vfli.ichFirstWide == 0 )
{
int *pdxpT = pdxp;
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
*pdxp += cxpQuotient;
if( --iWidenChar == 0 ) return;
if( --cNonWideSpaces == 0 ) cxpQuotient++;
}
}
} //else : ==chSpace || FKana()
} //Word Wrap On
}
pch++;
pdxp++;
}//for
#else // not JAPAN
register CHAR *pch = &vfli.rgch[vfli.ichReal];
register int *pdxp = &vfli.rgdxp[vfli.ichReal];
int dxpT = dxp;
int cBreak = pifi->cBreak;
int cxpQuotient = (dxpT / cBreak) + 1;
int cWideSpaces = dxpT % cBreak;
vfli.fAdjSpace = fTrue;
for ( ; ; )
{
/* Widen blanks */
--pch;
--pdxp;
#if defined(KOREA)
if ((*pch == chSpace) || FKanjiSpace(*pch, *(pch-1)))
{
if (FKanjiSpace(*pch, *(pch-1)))
--pch;
#else
if (*pch == chSpace)
{
#endif
if (cWideSpaces-- == 0)
{
int *pdxpT = pdxp + 1;
while (*pdxpT == 0)
{
pdxpT++;
}
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
cxpQuotient--;
}
*pdxp += cxpQuotient;
if ((dxpT -= cxpQuotient) <= 0)
{
if (pifi->cBreak > 1)
{
int *pdxpT = pdxp + 1;
while (*pdxpT == 0)
{
pdxpT++;
}
vfli.ichFirstWide = pdxpT - vfli.rgdxp;
}
return;
}
pifi->cBreak--;
}
}
#endif // JAPAN
}
} /* Switch */
if (dxp <= 0)
{
/* Nothing to do */
return;
}
pifi->xp += dxp;
if (flm & flmPrinting)
{
pifi->xpPr += dxp;
}
else
{
/* This statememt might introduce rounding errors in pifi->xpPr, but
with luck, they will be small. */
pifi->xpPr += MultDiv(MultDiv(dxp, czaInch, dxpLogInch), dxpPrPage,
dxaPrPage);
}
if (pifi->ichLeft < 0)
{
/* Normal justification */
vfli.xpLeft += dxp;
}
else
{
/* Tab justification */
vfli.rgdxp[pifi->ichLeft] += dxp;
}
vfli.xpReal += dxp;
}
/* F G R O W F O R M A T H E A P */
int near FGrowFormatHeap()
{
/* Grow vhgchpFormat by 20% */
int cchpIncr = ichpMacFormat / 5 + 1;
#ifdef WINHEAP
if (!LocalReAlloc((HANDLE)vhgchpFormat, (ichpMacFormat + cchpIncr) * cchCHP,
NONZEROLHND))
#else /* not WINHEAP */
if (!FChngSizeH(vhgchpFormat, (ichpMacFormat + cchpIncr) * cwCHP, false))
#endif /* not WINHEAP */
{
/* Sorry, charlie */
return false;
}
ichpMacFormat += cchpIncr;
return true;
}
/* #define DBEMG */
/* D X P F R O M C H */
#ifdef DBCS
/* DxpFromCh() assumes that ch passed is the first byte of a DBCS character
if it is a part of such character. */
#endif
int DxpFromCh(ch, fPrinter)
int ch;
int fPrinter;
{
int *pdxp; // changed to int (7.23.91) v-dougk
int dxpDummy; // changed to int (7.23.91) v-dougk
extern int dxpLogCh;
extern struct FCE *vpfceScreen;
/* If the width is not in the width table, then get it. */
if (ch < chFmiMin)
{
switch (ch)
{
case chTab:
case chEol:
case chReturn:
case chSect:
case chNewLine:
case chNRHFile:
/* the width for these characters aren't really important */
pdxp = (CHAR *)(fPrinter ? &vfmiPrint.dxpSpace : &vfmiScreen.dxpSpace);
break;
default:
pdxp = &dxpDummy;
*pdxp = dxpNil;
break;
}
}
else if (ch >= chFmiMax)
{
/* outside the range we hold in our table - kludge it */
pdxp = &dxpDummy;
*pdxp = dxpNil;
}
else
{
/* inside our table */
pdxp = (fPrinter ? vfmiPrint.mpchdxp : vfmiScreen.mpchdxp) + ch;
}
#ifdef DBCS
#ifdef KOREA
if (*pdxp == dxpNil && IsDBCSLeadByte(HIBYTE(ch)) )
#else
if (*pdxp == dxpNil && IsDBCSLeadByte(ch) )
#endif
{
int dxp;
#else
if (*pdxp == dxpNil)
{
int dxp;
#endif
#ifdef DBCS
struct FMI *pfmi;
#if 0 /*T-HIROYN*/
int rgchT[cchDBCS]; // changed to int (7.23.91) v-dougk
#endif
CHAR rgchT[cchDBCS]; // changed to int (7.23.91) v-dougk
int dxpT;
int dxpDBCS;
pfmi = fPrinter ? (&vfmiPrint) : (&vfmiScreen);
Assert(pfmi->bDummy == dxpNil);
if (pfmi->dxpDBCS == dxpNil)
{
#ifdef KOREA /* 90.12.26 For variable width by sangl */
rgchT[0] = HIBYTE(ch);
rgchT[1] = LOBYTE(ch);
#else
/* Get the width from GDI. */
rgchT[0] = rgchT[1] = ch;
#endif
dxpDBCS = (fPrinter ?
LOWORD(GetTextExtent(vhDCPrinter,
(LPSTR) rgchT, cchDBCS)) :
LOWORD(GetTextExtent(vhMDC,
(LPSTR) rgchT, cchDBCS)));
#ifndef TEMP_KOREA /* For variable width by sangl 90.12.26 */
/* Store in fmi, if it fits. */
if (0 <= dxpDBCS && dxpDBCS < dxpNil)
#if defined(JAPAN) || defined(KOREA) || defined(TAIWAN) || defined(PRC) //Win3.1 BYTE-->WORD
pfmi->dxpDBCS = (WORD) dxpDBCS;
#else
pfmi->dxpDBCS = (BYTE) dxpDBCS;
#endif
#endif
return (dxpDBCS - pfmi->dxpOverhang);
}
else
return (pfmi->dxpDBCS - pfmi->dxpOverhang);
}
#if defined(KOREA)
else if (*pdxp == dxpNil) {
#else
else {
#endif
int dxp;
#endif /* DBCS */
/* get width from GDI */
dxp = fPrinter ? LOWORD(GetTextExtent(vhDCPrinter, (LPSTR)&ch, 1)) -
vfmiPrint.dxpOverhang : LOWORD(GetTextExtent(vhMDC, (LPSTR)&ch, 1)) -
vfmiScreen.dxpOverhang;
#ifdef DBEMG
CommSzNum("Get this.... ", dxp);
#endif
//(7.24.91) v-dougk if (dxp >= 0 && dxp < dxpNil)
{
/* only store dxp's that fit in a byte */
*pdxp = dxp;
}
#ifdef DBEMG
{
char szT[10];
CommSzSz("fPrinter: ", (fPrinter ? "Printer" : "Screen"));
if (ch == 0x0D) {
szT[0] = 'C'; szT[1] = 'R'; szT[2] = '\0';
}
else if (ch == 0x0A) {
szT[0] = 'L'; szT[1] = 'F'; szT[2] = '\0';
}
else if (32 <= ch && ch <= 126) {
szT[0] = ch; szT[1] ='\0';
}
else if (FKanji1(ch)) {
szT[0] = 'K'; szT[1] = 'A'; szT[2] = 'N'; szT[3] = 'J';
szT[4] = 'I'; szT[5] = '\0';
}
else {
szT[0] = szT[1] = szT[2] = '-'; szT[3] = '\0';
}
CommSzSz("Character: ", szT);
CommSzNum("Dxp: ", (int) dxp);
CommSzNum("OverHang: ", (int) (fPrinter ? vfmiPrint.dxpOverhang : vfmiScreen.dxpOverhang));
}
#endif
return(dxp);
}
#ifdef DBEMG
{
char szT[10];
CommSzSz("fPrinter: ", (fPrinter ? "Printer" : "Screen"));
if (ch == 0x0D) {
szT[0] = 'C'; szT[1] = 'R'; szT[2] = '\0';
}
else if (ch == 0x0A) {
szT[0] = 'L'; szT[1] = 'F'; szT[2] = '\0';
}
else if (32 <= ch && ch <= 126) {
szT[0] = ch; szT[1] ='\0';
}
else if (FKanji1(ch)) {
szT[0] = 'K'; szT[1] = 'A'; szT[2] = 'N'; szT[3] = 'J';
szT[4] = 'I'; szT[5] = '\0';
}
else {
szT[0] = szT[1] = szT[2] = '-'; szT[3] = '\0';
}
CommSzSz("Character: ", szT);
CommSzNum("Dxp: ", (int) *pdxp);
CommSzNum("OverHang: ", (int) (fPrinter ? vfmiPrint.dxpOverhang : vfmiScreen.dxpOverhang));
}
#endif
return(*pdxp);
}
#ifdef DBCS
//
// DxpFromCh for DBCS
// yutakan, 03 Oct 1991
int DBCSDxpFromCh(ch, ch2, fPrinter)
int ch;
int ch2;
int fPrinter;
{
/* T-HIROYN sync us 3.1*/
int *pdxp; // changed to int (7.23.91) v-dougk
int dxpDummy; // changed to int (7.23.91) v-dougk
extern int dxpLogCh;
extern struct FCE *vpfceScreen;
/* If the width is not in the width table, then get it. */
if (ch < chFmiMin)
{
switch (ch)
{
case chTab:
case chEol:
case chReturn:
case chSect:
case chNewLine:
case chNRHFile:
/* the width for these characters aren't really important */
pdxp = (CHAR *)(fPrinter ? &vfmiPrint.dxpSpace : &vfmiScreen.dxpSpace);
break;
default:
pdxp = &dxpDummy;
*pdxp = dxpNil;
break;
}
}
else if (ch >= chFmiMax)
{
/* outside the range we hold in our table - kludge it */
pdxp = &dxpDummy;
*pdxp = dxpNil;
}
else
{
/* inside our table */
pdxp = (fPrinter ? vfmiPrint.mpchdxp : vfmiScreen.mpchdxp) + ch;
}
if (*pdxp == dxpNil )
{
int dxp;
#if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
// BUG 5477: Echen: add NON FA font, LeadByte + 2nd byte checking
if( ch2 != 0 && IsDBCSLeadByte(ch) && GetFontAssocStatus(vhMDC))
#else
if( IsDBCSLeadByte(ch) )
#endif //TAIWAN
{
struct FMI *pfmi;
#if defined(TAIWAN) || defined(KOREA) || defined(PRC) //for Bug# 3362, MSTC - pisuih, 2/10/93
CHAR rgchT[cchDBCS << 1];
int dxpOverhang;
#else
CHAR rgchT[cchDBCS];
#endif //TAIWAN
int dxpT;
int dxpDBCS;
pfmi = fPrinter ? (&vfmiPrint) : (&vfmiScreen);
Assert(pfmi->bDummy == dxpNil);
#if defined(TAIWAN) || defined(KOREA) || defined(PRC) //fix Italic position error while SBCS's overhang != DBCS's overhang
//for Bug# 3362, MSTC - pisuih, 3/4/93
//fix Go To page too slow, pisuih, 3/4/93
if ( (!pfmi->dxpDBCS) || (pfmi->dxpDBCS == dxpNil) )
{
rgchT[0] = rgchT[2] = ch;
rgchT[1] = rgchT[3] = ch2;
dxpDBCS = LOWORD(GetTextExtent( (fPrinter ? vhDCPrinter : vhMDC),
(LPSTR) rgchT, cchDBCS ));
dxpOverhang = (dxpDBCS << 1) - LOWORD( GetTextExtent(
(fPrinter ? vhDCPrinter : vhMDC), (LPSTR) rgchT, cchDBCS << 1 ));
//for compatible with SBCS's overhang
dxpDBCS += (pfmi->dxpOverhang - dxpOverhang);
/* Store in fmi, if it fits. */
if (0 <= dxpDBCS && dxpDBCS < dxpNil)
pfmi->dxpDBCS = (WORD) dxpDBCS;
return (dxpDBCS - pfmi->dxpOverhang);
}
else
return (pfmi->dxpDBCS - pfmi->dxpOverhang);
#else
if(pfmi->dxpDBCS == dxpNil)
{
/* Get the width from GDI. */
rgchT[0] = ch;
rgchT[1] = ch2;
dxpDBCS = (fPrinter ?
LOWORD(GetTextExtent(vhDCPrinter,
(LPSTR) rgchT, cchDBCS)) :
LOWORD(GetTextExtent(vhMDC,
(LPSTR) rgchT, cchDBCS)));
/* Store in fmi, if it fits. */
if (0 <= dxpDBCS && dxpDBCS < dxpNil)
#if defined(JAPAN) || defined(KOREA) //Win3.1 BYTE-->WORD
pfmi->dxpDBCS = (WORD) dxpDBCS;
#else
pfmi->dxpDBCS = (BYTE) dxpDBCS;
#endif
return (dxpDBCS - pfmi->dxpOverhang);
}
else
return (pfmi->dxpDBCS - pfmi->dxpOverhang);
#endif //TAIWAN
}
else
{
/* get width from GDI */
dxp = fPrinter ? LOWORD(GetTextExtent(vhDCPrinter, (LPSTR)&ch, 1)) -
vfmiPrint.dxpOverhang : LOWORD(GetTextExtent(vhMDC, (LPSTR)&ch, 1)) -
vfmiScreen.dxpOverhang;
}
/*T-HIROYN sync us 3.1*/
//(7.24.91) v-dougk if (dxp >= 0 && dxp < dxpNil)
{
/* only store dxp's that fit in a byte */
*pdxp = dxp;
}
return(dxp);
}
return(*pdxp);
}
#endif
/* F F I R S T I C H */
int near FFirstIch(ich)
int ich;
{
/* Returns true iff ich is 0 or preceded only by 0 width characters */
register int ichT;
register int *pdxp = &vfli.rgdxp[0];
for (ichT = 0; ichT < ich; ichT++)
{
if (*pdxp++)
{
return false;
}
}
return true;
}
ValidateMemoryDC()
{
/* Attempt to assure that vhMDC and vhDCPrinter are valid. If we have not
already run out of memory, then vhDCPrinter is guaranteed, but vhMDC may
fail due to out of memory -- it is the callers responsibility to check for
vhMDC == NULL. */
extern int vfOutOfMemory;
extern HDC vhMDC;
extern BOOL vfMonochrome;
extern long rgbText;
extern struct WWD *pwwdCur;
/* If we are out of memory, then we shouldn't try to gobble it up by getting
DC's. */
if (!vfOutOfMemory)
{
if (vhMDC == NULL)
{
/* Create a memory DC compatible with the screen if necessary. */
vhMDC = CreateCompatibleDC(pwwdCur->hDC);
/* Callers are responsible for checking for vhMDC == NULL case */
if (vhMDC != NULL)
{
/* Put the memory DC in transparent mode. */
SetBkMode(vhMDC, TRANSPARENT);
/* If the display is a monochrome device, then set the text
color for the memory DC. Monochrome bitmaps will not be
converted to the foreground and background colors in this case,
we must do the conversion. */
if (vfMonochrome = (GetDeviceCaps(pwwdCur->hDC, NUMCOLORS) ==
2))
{
SetTextColor(vhMDC, rgbText);
}
}
}
/* If the printer DC is NULL then we need to reestablish it. */
if (vhDCPrinter == NULL)
{
GetPrinterDC(FALSE);
/* GetPrinterDC has already called SetMapperFlags() on vhDCPrinter. */
}
}
}
#ifdef DBCS
/* The following two functions are used to determine if a given kanji
(two byte) character (or 1 byte kana letters) should be admitted
to the current line without causing the line break though it is
passed the right margin.
The table below shows which letters are admitted as a hanging character
on a line. The table below should be updated in sync with the code
itself.
Kanji (2-byte) characters
letter first byte second byte half width
hiragana small a 82 9F
i 82 A1
u 82 A3
e 82 A5
o 82 A7
tsu 82 C1
ya 82 E1
yu 82 E3
yo 82 E5
katakana small a 83 40 85 A5
i 83 42 85 A6
u 83 44 85 A7
e 83 46 85 A8
o 83 48 85 A9
tsu 83 62 85 AD
ya 83 83 85 AA
yu 83 85 85 AB
yo 83 87 85 AC
wa 83 8E
ka 83 95
ke 83 96
blank 81 40
horizontal bar (long) 81 5B 85 AE
(med) 81 5C
(short) 81 5D
touten
(Japanese comma) 81 41 85 A2
kuten
(Japanese period) 81 42 85 9F
handakuten 81 4B 85 DD
dakuten 81 4A 85 DC
kagikakko
(closing Japanese parenthesis)
81 76 85 A1
" (2-byte) 81 68 85 41
' (2-byte) 81 66 85 46
} (2-byte) 81 70 85 9D
] (2-byte) 81 6E 85 7C
) (2-byte) 81 6A 85 48
. (at the center) 81 45 85 A3
... 81 63
.. 81 64
closing angle bracket 81 72
closing double angled bracket
81 74
closing double kagikakko
81 78
closing inversed ) 81 7A
closing half angled bracket
81 6C
thinner ' 81 8C
thinner " 81 8D
1-byte kana characters
letter byte
katakana small a A7
i A8
u A9
e AA
o AB
tsu AF
ya AC
yu AD
yo AE
touten
(Japanese comma) A4
kuten
(Japanese period) A1
handakuten DF
dakuten DE
kagikakko
(closing Japanese parenthesis)
A3
. (at the center) A5
The following 1 or 2 byte characters are treated as a hanging character
if the previous character is a 2-byte kanji character.
letter byte
" 22
' 27
} 7D
] 5D
) 29
. 2E
, 2C
; 3B
: 3A
? 3F
! 21
byte 1 byte 2
. 81 44
, 81 43
; 81 47
: 81 46
? 81 48
! 81 49
. 85 4D
, 85 4B
; 85 4A
: 85 49
? 85 5E
! 85 40
*/
BOOL near FSearchChRgch(ch, rgch, ichLim)
CHAR ch;
CHAR *rgch;
int ichLim;
{
int ichMin;
BOOL fFound;
fFound = FALSE;
ichMin = 0;
while (!fFound && ichMin <= ichLim) {
int ichMid;
CHAR chMid;
/* Save on the dereferencing. */
chMid = rgch[ichMid = (ichMin + ichLim) >> 1];
if (ch == chMid) {
fFound = TRUE;
}
else if (ch < chMid) {
ichLim = ichMid - 1;
}
else {
ichMin = ichMid + 1;
}
}
return (fFound);
}
/* FAdmitCh1() returns true if and only if the given ch is a one-byte
kana code for those letters that can appear beyond the right margin. */
BOOL near FAdmitCh1(ch)
CHAR ch;
{
#ifdef JAPAN
if(!vfWordWrap) /*WordWrap off t-Yoshio*/
return FALSE;
return (
(ch == 0xA1) ||
((0xA3 <= ch) && (ch <= 0xA5)) ||
((0xA7 <= ch) && (ch <= 0xAF)) ||
((0xDE <= ch) && (ch <= 0xDF))
);
#else
return(FALSE);
#endif
}
/* FOptAdmitCh1() returns true if and only if the given ch is a
one-byte character that can be admitted to the end of a line
beyond the right margin, if it appears after a kanji character. */
BOOL near FOptAdmitCh1(ch)
CHAR ch;
{
static CHAR rgchOptAdmit1[]
= {0x21, 0x22, 0x27, 0x29, 0x2C, 0x2E, 0x3A, 0x3B,
0x3F, 0x5D, 0x7D};
#if defined(JAPAN) || defined(KOREA)
if(!vfWordWrap) /*WordWrap off t-Yoshio*/
return FALSE;
#endif
return (FSearchChRgch(ch, rgchOptAdmit1,
(sizeof(rgchOptAdmit1) / sizeof(CHAR)) - 1));
}
/* FAdmitCh2() returns true if and only if the given (ch1, ch2) combination
represents a kanji (2-byte) letter that can appear beyond the right
margin. */
BOOL near FAdmitCh2(ch1, ch2)
CHAR ch1, ch2;
{
int dch=0;
#if defined(JAPAN) || defined(KOREA)
if(!vfWordWrap) /*WordWrap off t-Yoshio*/
return FALSE;
#endif
while((dch < MPDCHRGCHIDX_MAC) && (ch1 != mpdchrgchIdx[dch]))
dch++;
if (dch < MPDCHRGCHIDX_MAC) {
return (FSearchChRgch(ch2, mpdchrgch[dch], mpdchichMax[dch] - 1));
}
else {
return (FALSE);
}
}
/* FOptAdmitCh2() returns true if and only if the given (ch1, ch2) is a
two-byte character combination that can be admitted to the end of a line
beyond the right margin, provided it appears after a kanji character. */
BOOL near FOptAdmitCh2(ch1, ch2)
CHAR ch1, ch2;
{
int i=0;
#if defined(JAPAN) || defined(KOREA)
if(!vfWordWrap) /*WordWrap off t-Yoshio*/
return FALSE;
#endif
while ((i < OPTADMIT2IDX_MAC) && (ch1 != OptAdmit2Idx[i]))
i++;
if (i < OPTADMIT2IDX_MAC){
return (FSearchChRgch(ch2, mpdchrgchOptAdmit2[i], OptAdmit2ichMax[i]));
}
else {
return (FALSE);
}
}
/* FOptAdmitCh() returns TRUE if and only if the given (ch1, ch2) can
be a hanging letter at the end of a line. Otherwise, FALSE. If ch1
is equal to '\0', ch2 is treated as a 1-byte character code. */
BOOL FOptAdmitCh(ch1, ch2)
CHAR ch1, ch2;
{
#if defined(JAPAN) || defined(KOREA)
if(!vfWordWrap) /*WordWrap off t-Yoshio*/
return FALSE;
#endif
if (ch1 == '\0') {
return ((ch2 == chSpace) || FAdmitCh1(ch2) || FOptAdmitCh1(ch2));
}
else {
return (FKanjiSpace(ch1, ch2) || FAdmitCh2(ch1, ch2) ||
FOptAdmitCh2(ch1, ch2));
}
}
#endif /* ifdef DBCS */