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

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /*--- Module not really used, just the idea behind FORMAT.ASM ---*/
  5. #define NOCLIPBOARD
  6. #define NOGDICAPMASKS
  7. #define NOCTLMGR
  8. #define NOVIRTUALKEYCODES
  9. #define NOWINMESSAGES
  10. #define NOWINSTYLES
  11. #define NOKEYSTATE
  12. #define NOSYSCOMMANDS
  13. #define NORASTEROPS
  14. #define NOSHOWWINDOW
  15. #define NOCLIPBOARD
  16. #define NOWINSTYLES
  17. #define NOSYSMETRICS
  18. #define NOMENUS
  19. #define NOATOM
  20. #define NOCREATESTRUCT
  21. #define NODRAWTEXT
  22. #define NOMB
  23. #define NOMEMMGR
  24. #define NOMETAFILE
  25. #define NOWH
  26. #define NOWINOFFSETS
  27. #define NOWNDCLASS
  28. #include <windows.h>
  29. /* #include "wwsmall.h" */
  30. #include "mw.h"
  31. #include "cmddefs.h"
  32. #include "fmtdefs.h"
  33. #include "propdefs.h"
  34. #include "ch.h"
  35. #include "docdefs.h"
  36. #include "ffdefs.h"
  37. #include "filedefs.h"
  38. #include "fkpdefs.h"
  39. #include "dispdefs.h"
  40. #include "scrndefs.h"
  41. #include "macro.h"
  42. #include "debug.h"
  43. #include "fontdefs.h"
  44. #include "str.h"
  45. #include "wwdefs.h"
  46. #ifdef DBCS
  47. #include "dbcs.h"
  48. /* We move several hard code Kanji code table from this source file
  49. to kanji.h as external variables. Define CODE_TABLE will define
  50. those variables */
  51. #define CODE_TABLE
  52. #include "kanji.h"
  53. #endif
  54. #if defined(TAIWAN) || defined(PRC)
  55. int WINAPI GetFontAssocStatus(HDC);
  56. #endif
  57. #ifdef DFLI
  58. #define Dfli(x) x /* Enable debug-format-line info */
  59. #else
  60. #define Dfli(x)
  61. #endif
  62. #ifdef CASHMERE
  63. #define cchSmcapMax 16
  64. #endif /* CASHMERE */
  65. static int ichpFormat;
  66. #ifdef CASHMERE
  67. static CHAR mptlcch[] = " .-_";
  68. #endif /* CASHMERE */
  69. #if defined(JAPAN) || defined(KOREA) // added 22 Jun. 1992 by Hiraisi
  70. int iWidenChar; /* counter for widened characters except (KANJI) space */
  71. /* Ex.) DBCS, Japanese KANA */
  72. int iNonWideSpaces;
  73. #elif defined(TAIWAN) || defined(PRC)// Daniel/MSTC, 1993/02/25, for jcBoth
  74. int iWidenChar; /* counter for widened characters except (KANJI) space */
  75. /* Ex.) DBCS, Japanese KANA */
  76. int iNonWideSpaces;
  77. extern int vfWordWrap;
  78. #define FKana(_ch) FALSE
  79. #endif
  80. /* T-HIROYN sync format.asm */
  81. /*extern int docHelp;*/
  82. extern struct FLI vfli;
  83. extern struct CHP (**vhgchpFormat)[];
  84. extern int ichpMacFormat;
  85. extern struct CHP vchpAbs;
  86. extern struct PAP vpapAbs;
  87. extern struct SEP vsepAbs;
  88. extern struct SEP vsepPage;
  89. extern struct CHP vchpNormal;
  90. extern struct DOD (**hpdocdod)[];
  91. extern typeCP vcpLimSectCache;
  92. extern typeCP vcpFirstParaCache;
  93. extern typeCP vcpLimParaCache;
  94. extern typeCP vcpFetch;
  95. extern int vichFetch;
  96. extern int vccpFetch;
  97. extern CHAR *vpchFetch;
  98. extern int vcchFetch;
  99. extern int vftc;
  100. extern int ypSubSuper;
  101. extern int ypSubSuperPr;
  102. extern HDC vhMDC;
  103. extern HDC vhDCPrinter;
  104. extern int dxpLogInch;
  105. extern int dypLogInch;
  106. extern int dxaPrPage;
  107. extern int dyaPrPage;
  108. extern int dxpPrPage;
  109. extern int dypPrPage;
  110. extern int dypMax;
  111. extern struct FMI vfmiScreen, vfmiPrint;
  112. extern int vfOutOfMemory;
  113. extern CHAR vchDecimal; /* "decimal point" character */
  114. extern int vzaTabDflt; /* width of default tab */
  115. #if defined(JAPAN) || defined(KOREA)
  116. extern int vfWordWrap; /*t-Yoshio WordWrap flag*/
  117. #endif
  118. #ifdef CASHMERE
  119. extern int vfVisiMode;
  120. #endif /* CASHMERE */
  121. /* F O R M A T L I N E */
  122. FormatLine(doc, cp, ichCp, cpMac, flm)
  123. int doc;
  124. typeCP cp;
  125. int ichCp;
  126. typeCP cpMac;
  127. int flm;
  128. {
  129. /* Fills up vfli with a line of text */
  130. int near Justify(struct IFI *, unsigned, int);
  131. int near FGrowFormatHeap(void);
  132. int near FFirstIch(int);
  133. #ifdef DBCS
  134. BOOL near FAdmitCh1(CHAR);
  135. BOOL near FAdmitCh2(CHAR, CHAR);
  136. BOOL near FOptAdmitCh1(CHAR);
  137. BOOL near FOptAdmitCh2(CHAR, CHAR);
  138. int DBCSDxpFromCh(int,int,int);
  139. #endif
  140. struct IFI ifi;
  141. struct TBD *ptbd;
  142. struct CHP chpLocal;
  143. int xpTab;
  144. #ifdef CASHMERE
  145. int dypBefore;
  146. #endif /* CASHMERE */
  147. int dypAscent;
  148. int dypDescent;
  149. int dypAscentMac;
  150. int dypDescentMac;
  151. unsigned xaLeft;
  152. unsigned xaRight;
  153. struct PAP *ppap;
  154. struct SEP *psep;
  155. int fFlmPrinting = flm & flmPrinting;
  156. int dxaFormat;
  157. int dyaFormat;
  158. int dxpFormat;
  159. int dypFormat;
  160. int ypSubSuperFormat;
  161. int fTruncated = false; /* if the run was truncated */
  162. int ichpNRH;
  163. #ifdef DBCS
  164. int dichSpaceAdjust;
  165. int dypLeading;
  166. int dypIntLeading;
  167. int dypPAscent; /* Pure Ascent */
  168. int dypLeadingMac;
  169. int dypIntLeadingMac;
  170. int dypPAscentMac;
  171. BOOL fKanjiBreakOppr = false;
  172. BOOL fKanjiPrevious = false;
  173. /* true iff we already have a hanging character on the line. */
  174. BOOL fKanjiHanging = false;
  175. /* true iff the first and second bytes of a kanji character
  176. were in two different runs. */
  177. BOOL fOddBoundary = false;
  178. typeCP cpFetchSave;
  179. typeCP cpSeqFetch;
  180. int ichFetchSave;
  181. int cchUsedSave;
  182. extern int utCur;
  183. extern int dxaAdjustPer5Ch;
  184. extern unsigned cxaCh;
  185. #endif /* ifdef DBCS */
  186. #ifdef CASHMERE
  187. struct FNTB **hfntb;
  188. int fVisiMode;
  189. #endif /* CASHMERE */
  190. /* Check for fli current */
  191. if (vfli.doc == doc && vfli.cpMin == cp && vfli.ichCpMin == ichCp &&
  192. vfli.flm == flm)
  193. {
  194. /* Just did this one */
  195. return;
  196. }
  197. #ifdef JAPAN // added by Hiraisi
  198. // When printing, WRITE doesn't redraw the screen.
  199. {
  200. extern BOOL fPrinting;
  201. if( fPrinting && !fFlmPrinting )
  202. return;
  203. }
  204. #endif
  205. Scribble(5, 'F');
  206. bltc(&vfli, 0, cwFLIBase);
  207. /* This means:
  208. vfli.fSplat = false;
  209. vfli.dcpDepend = 0;
  210. vfli.ichCpMac = 0;
  211. vfli.dypLine = 0;
  212. vfli.dypAfter = 0;
  213. vfli.dypFont = 0;
  214. vfli.dypBase = 0;
  215. */
  216. /* vfSplatNext = FALSE; No longer used. */
  217. /* Rest of format loads up cache with current data */
  218. vfli.doc = doc;
  219. vfli.cpMin = cp;
  220. vfli.ichCpMin = ichCp;
  221. vfli.flm = flm;
  222. if (cp > cpMac)
  223. {
  224. /* Space after the endmark. Reset the cache because the footnotes come
  225. at the same cp in the footnote window */
  226. vfli.doc = docNil;
  227. vfli.cpMac = cp;
  228. vfli.rgdxp[0] = 0;
  229. /* Line after end mark is taller than screen */
  230. #ifdef CASHMERE
  231. vfli.dypBase = vfli.dypFont = vfli.dypAfter = ((vfli.dypLine = dypMax)
  232. >> 1);
  233. #else /* not CASHMERE */
  234. vfli.dypBase = vfli.dypFont = ((vfli.dypLine = dypMax) >> 1);
  235. #endif /* not CASHMERE */
  236. Scribble(5, ' ');
  237. return;
  238. }
  239. /* Initialize run tables */
  240. ichpFormat = 0;
  241. /* Cache section and paragraph properties */
  242. #ifdef CASHMERE
  243. hfntb = (**hpdocdod)[doc].hfntb;
  244. if (hfntb == 0 || cp < (**hfntb).rgfnd[0].cpFtn)
  245. {
  246. /* Normal text */
  247. CacheSect(doc, cp);
  248. }
  249. else
  250. {
  251. /* Footnote section properties come from the section of the footnote
  252. reference. */
  253. CacheSect(doc, CpRefFromFtn(doc, cp));
  254. }
  255. #else /* not CASHMERE */
  256. CacheSect(doc, cp);
  257. #endif /* not CASHMERE */
  258. psep = &vsepAbs;
  259. CachePara(doc, cp);
  260. ppap = &vpapAbs;
  261. /* Now we have:
  262. ppap paragraph properties
  263. psep division properties
  264. */
  265. if (ppap->fGraphics)
  266. {
  267. /* Format a picture paragraph in a special way (see picture.c) */
  268. FormatGraphics(doc, cp, ichCp, cpMac, flm);
  269. Scribble(5, ' ');
  270. return;
  271. }
  272. /* Assure we have a good memory DC for font stuff */
  273. ValidateMemoryDC();
  274. if (vhMDC == NULL || vhDCPrinter == NULL)
  275. {
  276. Scribble(5, ' ');
  277. return;
  278. }
  279. #ifdef CASHMERE
  280. /* When printing, don't show visible characters */
  281. fVisiMode = vfVisiMode && !fFlmPrinting;
  282. #endif /* CASHMERE */
  283. bltc(&ifi, 0, cwIFI);
  284. /* This means:
  285. ifi.ich = 0;
  286. ifi.ichPrev = 0;
  287. ifi.ichFetch = 0;
  288. ifi.cchSpace = 0;
  289. ifi.ichLeft = 0;
  290. */
  291. ifi.jc = jcTabLeft;
  292. ifi.fPrevSpace = true;
  293. /* Set up some variables that have different value depending on whether we
  294. are printing or not. */
  295. if (fFlmPrinting)
  296. {
  297. dxaFormat = dxaPrPage;
  298. dyaFormat = dyaPrPage;
  299. dxpFormat = dxpPrPage;
  300. dypFormat = dypPrPage;
  301. ypSubSuperFormat = ypSubSuperPr;
  302. }
  303. else
  304. {
  305. dxaFormat = dyaFormat = czaInch;
  306. dxpFormat = dxpLogInch;
  307. dypFormat = dypLogInch;
  308. ypSubSuperFormat = ypSubSuper;
  309. }
  310. /* Calculate line height and width measures. Compute
  311. xaLeft left indent 0 means at left margin
  312. xaRight width of column measured from left margin (not from left
  313. indent).
  314. */
  315. xaLeft = ppap->dxaLeft;
  316. /* If this is the first line of a paragraph, adjust xaLeft for the first
  317. line indent. (Also, set dypBefore, since its handy.) */
  318. if (cp == vcpFirstParaCache)
  319. {
  320. xaLeft += ppap->dxaLeft1;
  321. #ifdef CASHMERE
  322. dypBefore = MultDiv(ppap->dyaBefore, dypLogInch, czaInch);
  323. #endif /* CASHMERE */
  324. }
  325. #ifdef CASHMERE
  326. else
  327. {
  328. dypBefore = 0;
  329. }
  330. #endif /* CASHMERE */
  331. /* Now, set xaRight (width measured in twips). */
  332. #ifdef CASHMERE
  333. xaRight = (ppap->rhc ? vsepPage.xaMac - vsepPage.dxaGutter :
  334. psep->dxaText) - ppap->dxaRight;
  335. #else /* not CASHMERE */
  336. xaRight = psep->dxaText - ppap->dxaRight;
  337. #endif /* not CASHMERE */
  338. /* Do necessary checks on xaLeft and xaRight */
  339. if (xaRight > xaRightMax)
  340. {
  341. xaRight = xaRightMax;
  342. }
  343. if (xaLeft > xaRightMax)
  344. {
  345. xaLeft = xaRightMax;
  346. }
  347. if (xaLeft < 0)
  348. {
  349. xaLeft = 0;
  350. }
  351. if (xaRight < xaLeft)
  352. {
  353. xaRight = xaLeft + 1;
  354. }
  355. vfli.xpLeft = ifi.xp = ifi.xpLeft = MultDiv(xaLeft, dxpFormat, dxaFormat);
  356. vfli.xpMarg = ifi.xpRight = MultDiv(xaRight, dxpFormat, dxaFormat);
  357. ifi.xpPr = MultDiv(xaLeft, dxpPrPage, dxaPrPage);
  358. ifi.xpPrRight = MultDiv(xaRight, dxpPrPage, dxaPrPage);
  359. #ifndef JAPAN // added by Hiraisi (BUG#3542)
  360. #ifdef DBCS /* was in JAPAN */
  361. /* at least one kanji is displayed */
  362. /* DxpFromCh() --> DBCSDxpFromCh() 03 Oct 1991 YutakaN */
  363. {
  364. int dxpPr;
  365. if ( ifi.xpPrRight - ifi.xpPr < (dxpPr = DBCSDxpFromCh(bKanjiSpace1,bKanjiSpace2, TRUE) ) )
  366. {
  367. ifi.xpPrRight = ifi.xpPr + dxpPr + 1;
  368. }
  369. }
  370. #endif
  371. #endif
  372. /* Get a pointer to the tab-stop table. */
  373. ptbd = ppap->rgtbd;
  374. /* Turn off justification. */
  375. SetTextJustification(fFlmPrinting ? vhDCPrinter : vhMDC, 0, 0);
  376. /* Initialize the line height information. */
  377. dypAscentMac = dypDescentMac = 0;
  378. /*T-HIROYN add from 3.0*/
  379. #if defined(JAPAN) || defined(KOREA)
  380. dypLeadingMac = dypIntLeadingMac = dypPAscentMac = 0;
  381. #endif /* JAPAN */
  382. /* To tell if there were any tabs */
  383. ifi.ichLeft = -1;
  384. #if defined(JAPAN) || defined(KOREA) // added 22 Jun. 1992 by Hiraisi
  385. iWidenChar=0;
  386. #elif defined(TAIWAN) || defined(PRC) // Daniel/MSTC, 1993/02/25, for jcBoth
  387. iWidenChar=0;
  388. #endif
  389. /* Get the first run, and away we go... */
  390. FetchCp(doc, cp, ichCp, fcmBoth + fcmParseCaps);
  391. goto FirstCps;
  392. for ( ; ; )
  393. {
  394. int iichNew;
  395. int xpPrev;
  396. int dxp;
  397. int dxpPr;
  398. /* The number of characters to process (usually vcchFetch) */
  399. int cch;
  400. /* The number of characters in current run already used */
  401. int cchUsed;
  402. /* A pointer to the current list of characters (usually vpchFetch) */
  403. CHAR *pch;
  404. #ifdef CASHMERE
  405. CHAR rgchSmcap[cchSmcapMax];
  406. #endif /* CASHMERE */
  407. if (ifi.ichFetch == cch)
  408. {
  409. /* End of a run */
  410. int dich;
  411. BOOL fSizeChanged;
  412. if (ifi.ich >= ichMaxLine )
  413. /* End of run because of line length limit has been reached. */
  414. {
  415. goto DoBreak;
  416. }
  417. if (fTruncated)
  418. {
  419. cchUsed += cch;
  420. pch = vpchFetch + cchUsed;
  421. cch = vcchFetch - cchUsed;
  422. fTruncated = false;
  423. goto OldRun; /* use the rest of the old run */
  424. }
  425. NullRun:
  426. #ifdef DBCS
  427. if (!fOddBoundary)
  428. {
  429. /* The last fetch did not mess up a sequential access. */
  430. FetchCp(docNil, cpNil, 0, fcmBoth + fcmParseCaps);
  431. }
  432. else
  433. {
  434. /* Previous fetch was an odd one. Set it up again. */
  435. FetchCp(doc, cpSeqFetch, 0, fcmBoth + fcmParseCaps);
  436. }
  437. fOddBoundary = false;
  438. #else
  439. FetchCp(docNil, cpNil, 0, fcmBoth + fcmParseCaps);
  440. #endif
  441. FirstCps:
  442. cchUsed = 0;
  443. /* Continue fetching runs until a run is found with a nonzero
  444. length. */
  445. if ((cch = vcchFetch) == 0)
  446. {
  447. goto NullRun;
  448. }
  449. pch = vpchFetch;
  450. if (vcpFetch >= cpMac || (!fFlmPrinting && *pch == chSect))
  451. {
  452. #ifdef SYSENDMARK
  453. /* Force end mark and section mark to be in standard system
  454. font. */
  455. blt(&vchpNormal, &vchpAbs, cwCHP);
  456. vchpAbs.ftc = ftcSystem;
  457. vchpAbs.ftcXtra = 0;
  458. vchpAbs.hps = hpsDefault;
  459. #else
  460. #ifdef REVIEW
  461. /* The following comment is absolutely misleading! Ftc==0
  462. doesn't give you a system font. It gives you the first
  463. entry in the font table. */
  464. #endif /* REVIEW */
  465. /* Force end mark and section mark to be in standard system
  466. font. */
  467. blt(&vchpNormal, &vchpAbs, cwCHP);
  468. vchpAbs.ftc = 0;
  469. vchpAbs.ftcXtra = 0;
  470. vchpAbs.hps = hpsDefault;
  471. #endif /* if-else-def KANJI */
  472. }
  473. #ifdef CASHMERE
  474. /* Adjust the size of the font for "small capitals". */
  475. if (vchpAbs.csm == csmSmallCaps)
  476. {
  477. vchpAbs.hps = HpsAlter(vchpAbs.hps, -1);
  478. }
  479. #endif /* CASHMERE */
  480. /* Now we have:
  481. ichpFormat index into gchp table
  482. vcpFetch first cp of current run
  483. vfli.cpMin first cp of line
  484. ifi.ich ???
  485. */
  486. /* since LoadFont could change vchpAbs, and we don't want
  487. that to happen, we copy vchpAbs into vchpLocal and use
  488. vchpLocal in place of vchpAbs hereafter. Note that vchpAbs
  489. is intentionally used above for handling the endmark. */
  490. blt(&vchpAbs, &chpLocal, cwCHP);
  491. if (fFlmPrinting)
  492. {
  493. LoadFont(doc, &chpLocal, mdFontPrint);
  494. dypAscent = vfmiPrint.dypAscent + vfmiPrint.dypLeading;
  495. dypDescent = vfmiPrint.dypDescent;
  496. #ifdef DBCS /* was in JAPAN */
  497. dypPAscent = vfmiPrint.dypAscent;
  498. dypLeading = vfmiPrint.dypLeading;
  499. dypIntLeading = vfmiPrint.dypIntLeading;
  500. #endif
  501. }
  502. else
  503. {
  504. LoadFont(doc, &chpLocal, mdFontJam);
  505. dypAscent = vfmiScreen.dypAscent + vfmiScreen.dypLeading;
  506. dypDescent = vfmiScreen.dypDescent;
  507. #ifdef DBCS /* was in JAPAN */
  508. dypPAscent = vfmiScreen.dypAscent;
  509. dypLeading = vfmiScreen.dypLeading;
  510. dypIntLeading = vfmiScreen.dypIntLeading;
  511. #endif
  512. }
  513. #ifdef ENABLE /* BRYANL 8/27/87: New philosophy for handling
  514. font selection failures is: font selection
  515. ALWAYS succeeds. This prevents FormatLine
  516. returns that do not advance. */
  517. /* Bail out if there is a memory failure. */
  518. if (vfOutOfMemory)
  519. {
  520. goto DoBreak;
  521. }
  522. #endif /* ENABLE */
  523. /* Floating line size algorithm */
  524. if (chpLocal.hpsPos != 0)
  525. {
  526. /* Modify font for subscript/superscript */
  527. if (chpLocal.hpsPos < hpsNegMin)
  528. {
  529. dypAscent += ypSubSuperFormat;
  530. #ifdef DBCS /* was in JAPAN */
  531. dypPAscent += ypSubSuperFormat;
  532. #endif
  533. }
  534. else
  535. {
  536. dypDescent += ypSubSuperFormat;
  537. }
  538. }
  539. /* Update the maximum ascent and descent of the line. */
  540. fSizeChanged = FALSE;
  541. if (dypDescentMac < dypDescent)
  542. {
  543. dypDescentMac = dypDescent;
  544. fSizeChanged = TRUE;
  545. }
  546. if (dypAscentMac < dypAscent)
  547. {
  548. dypAscentMac = dypAscent;
  549. fSizeChanged = TRUE;
  550. }
  551. #ifdef DBCS /* was in JAPAN */
  552. if (dypPAscentMac < dypPAscent)
  553. {
  554. dypPAscentMac = dypPAscent;
  555. fSizeChanged = TRUE;
  556. }
  557. if (dypIntLeadingMac < dypIntLeading)
  558. {
  559. dypIntLeadingMac = dypIntLeading;
  560. fSizeChanged = TRUE;
  561. }
  562. if (dypLeadingMac < dypLeading)
  563. {
  564. dypLeadingMac = dypLeading;
  565. fSizeChanged = TRUE;
  566. }
  567. #endif
  568. if (fSizeChanged)
  569. {
  570. #ifdef AUTO_SPACING
  571. /* This is the original Mac Word code that assumed line spacing
  572. of 0 in a PAP meant auto line spacing. PC Word defaults to 1
  573. line invalidating this assumption. */
  574. if (ppap->dyaLine == 0)
  575. {
  576. #ifdef CASHMERE
  577. ifi.dypLineSize = dypDescentMac + dypAscentMac + dypBefore;
  578. #else /* not CASHMERE */
  579. ifi.dypLineSize = dypDescentMac + dypAscentMac;
  580. #endif /* not CASHMERE */
  581. }
  582. else
  583. {
  584. #ifdef CASHMERE
  585. ifi.dypLineSize = imax(MultDiv(ppap->dyaLine, dypFormat,
  586. dyaFormat) + dypBefore, dypBefore + 1);
  587. #else /* not CASHMERE */
  588. ifi.dypLineSize = imax(MultDiv(ppap->dyaLine, dypFormat,
  589. dyaFormat), 1);
  590. #endif /* not CASHMERE */
  591. }
  592. #else /* not AUTO_SPACING */
  593. /* This code forces auto line spacing except in the case where
  594. the user specifies a line spacing greater than the auto line
  595. spacing. */
  596. {
  597. #ifdef DBCS /* was in JAPAN */
  598. #if defined(TAIWAN) || defined(PRC)
  599. register int dypAuto = dypDescentMac + dypAscentMac;
  600. if (ppap->dyaLine > czaLine)
  601. {
  602. register int dypUser = imax(MultDiv(ppap->dyaLine,
  603. dypFormat, dyaFormat), 1);
  604. ifi.dypLineSize = max(dypAuto, dypUser);
  605. }
  606. else
  607. {
  608. ifi.dypLineSize = dypAuto;
  609. }
  610. #else /* TAIWAN */
  611. register int dypAuto = dypDescentMac + dypAscentMac;
  612. int cHalfLine;
  613. int dypSingle = dypPAscentMac + dypDescentMac;
  614. cHalfLine = (ppap->dyaLine + (czaLine / 4)) / (czaLine / 2);
  615. ifi.dypLineSize = (cHalfLine == 3) ? (dypSingle*3)/2 :
  616. ((cHalfLine <= 2) ?
  617. dypSingle :
  618. (dypSingle * 2));
  619. #endif /* TAIWAN */
  620. #else // DBCS
  621. #ifdef CASHMERE
  622. register int dypAuto = dypDescentMac + dypAscentMac +
  623. dypBefore;
  624. #else /* not CASHMERE */
  625. register int dypAuto = dypDescentMac + dypAscentMac;
  626. #endif /* not CASHMERE */
  627. if (ppap->dyaLine > czaLine)
  628. {
  629. #ifdef CASHMERE
  630. register int dypUser = imax(MultDiv(ppap->dyaLine,
  631. dypFormat, dyaFormat) + dypBefore, dypBefore + 1);
  632. #else /* not CASHMERE */
  633. register int dypUser = imax(MultDiv(ppap->dyaLine,
  634. dypFormat, dyaFormat), 1);
  635. #endif /* not CASHMERE */
  636. ifi.dypLineSize = max(dypAuto, dypUser);
  637. }
  638. else
  639. {
  640. ifi.dypLineSize = dypAuto;
  641. }
  642. #endif /* DBCS */
  643. }
  644. #endif /* not AUTO_SPACING */
  645. }
  646. OldRun:
  647. /* Calculate length of the run but no greater than 256 */
  648. iichNew = (int)(vcpFetch - vfli.cpMin);
  649. if (iichNew >= ichMaxLine)
  650. {
  651. iichNew = ichMaxLine - 1;
  652. }
  653. dich = iichNew - ifi.ich;
  654. /* Ensure that all tab and non-required hyphen characters start at
  655. beginning of run */
  656. if (ichpFormat <= 0 || dich > 0 || CchDiffer(&chpLocal,
  657. &(**vhgchpFormat)[ichpFormat - 1], cchCHPUsed) != 0 || *pch ==
  658. chTab || *pch == chNRHFile)
  659. {
  660. #ifdef DFLI
  661. if (*pch == chNRHFile)
  662. CommSz("CHNRHFILE at beginning of run");
  663. #endif
  664. if (ichpFormat != ichpMacFormat || FGrowFormatHeap())
  665. {
  666. register struct CHP *pchp = &(**vhgchpFormat)[ichpFormat -
  667. 1];
  668. if (ichpFormat > 0)
  669. {
  670. pchp->cchRun = ifi.ich - ifi.ichPrev;
  671. pchp->ichRun = ifi.ichPrev;
  672. }
  673. blt(&chpLocal, ++pchp, cwCHP);
  674. #ifdef ENABLE /* font codes */
  675. pchp->ftc = vftc;
  676. pchp->ftcXtra = (vftc & 0x01c0) >> 6;
  677. pchp->hps = vhps;
  678. #endif /* ENABLE */
  679. pchp->cchRun = ichMaxLine;
  680. if (dich <= 0)
  681. {
  682. pchp->ichRun = ifi.ich;
  683. }
  684. else
  685. {
  686. /* Q&D insert */
  687. bltc(&vfli.rgdxp[ifi.ich], 0, dich);
  688. bltbc(&vfli.rgch[ifi.ich], 0, dich);
  689. pchp->ichRun = ifi.ich = iichNew;
  690. }
  691. ifi.ichPrev = ifi.ich;
  692. ichpFormat++;
  693. }
  694. }
  695. if (vcpFetch >= cpMac)
  696. {
  697. /* End of doc reached */
  698. if (!ifi.fPrevSpace || vcpFetch == cp)
  699. {
  700. vfli.ichReal = ifi.ich;
  701. vfli.xpReal = ifi.xpReal = ifi.xp;
  702. }
  703. /* T-HIROYN sync fromat.asm */
  704. /* if (!fFlmPrinting && (doc != docHelp))*/
  705. if (!fFlmPrinting)
  706. {
  707. /*
  708. * Write 3.1j endmark is 1-bytecharcter
  709. * t-Yoshio May 26,92
  710. */
  711. #if defined(JAPAN) || defined(KOREA)
  712. vfli.rgch[ifi.ich] = chEMark;
  713. vfli.xpReal += (vfli.rgdxp[ifi.ich++] = DxpFromCh(chEMark,
  714. false));
  715. #else
  716. #ifdef DBCS /* was in JAPAN */
  717. /* We use Double byte character to chEMark in Japan */
  718. if (ifi.ich + cchKanji > ichMaxLine) {
  719. /* vfli.rgch has no room for the two-byte
  720. end mark. Too bad do the break and
  721. wait for the next time around. */
  722. goto DoBreak;
  723. }
  724. vfli.rgch[ifi.ich] = chMark1;
  725. vfli.xpReal += (vfli.rgdxp[ifi.ich++] = DxpFromCh(chMark1,
  726. false));
  727. vfli.rgch[ifi.ich] = chEMark;
  728. vfli.rgdxp[ifi.ich++] = 0;
  729. #if !defined(TAIWAN) && !defined(PRC)
  730. ifi.dypLineSize += 2;
  731. #endif
  732. #else /* DBCS */
  733. vfli.rgch[ifi.ich] = chEMark;
  734. vfli.xpReal += (vfli.rgdxp[ifi.ich++] = DxpFromCh(chEMark,
  735. false));
  736. #endif
  737. #endif /*JAPAN*/
  738. }
  739. vfli.dypLine = ifi.dypLineSize;
  740. vfli.dypBase = dypDescentMac;
  741. vfli.dypFont = dypAscentMac + dypDescentMac;
  742. vfli.ichMac = vfli.ichReal = ifi.ich;
  743. vfli.cpMac = cpMac + 1;
  744. goto JustEol; /* dcpDepend == 0 */
  745. }
  746. /* Here we have ifi.ich, cch */
  747. if (ifi.ich + cch > ichMaxLine)
  748. /* If this run would put the line over 255, truncate it and set a
  749. flag. */
  750. {
  751. cch = ichMaxLine - ifi.ich;
  752. fTruncated = true;
  753. }
  754. ifi.ichFetch = 0;
  755. #ifdef CASHMERE
  756. if (chpLocal.csm != csmNormal)
  757. {
  758. int ich;
  759. CHAR *pchT = &rgchSmcap[0];
  760. /* We can handle only a run of cchSmcapMax small capital
  761. characters. If the run is larger then truncate. */
  762. if (cch > cchSmcapMax)
  763. {
  764. cch = cchSmcapMax;
  765. fTruncated = true;
  766. }
  767. /* Raise the case of the characters. */
  768. for (ich = 0 ; ich < cch ; ich++)
  769. {
  770. *pchT++ = ChUpper(*pch++);
  771. }
  772. pch = &rgchSmcap[0];
  773. }
  774. #endif /* CASHMERE */
  775. /* Do "special" characters here */
  776. if (chpLocal.fSpecial)
  777. {
  778. if (!FFormatSpecials(&ifi, flm, vsepAbs.nfcPgn))
  779. {
  780. if (ifi.chBreak == 0 ) /* No breaks in this line */
  781. {
  782. goto Unbroken;
  783. }
  784. else
  785. {
  786. vfli.dcpDepend = vcpFetch + ifi.ichFetch - vfli.cpMac;
  787. goto JustBreak;
  788. }
  789. }
  790. }
  791. continue;
  792. }
  793. /* End of new run treatment. We are back in the "for every character"
  794. section. */
  795. {
  796. register int ch = pch[ifi.ichFetch++];
  797. NormChar:
  798. #ifdef DBCS
  799. /* Unless it is a kanji space, we only need to adjust
  800. by 1 byte. */
  801. dichSpaceAdjust = 1;
  802. #endif
  803. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
  804. if (ch == chSpace && vfWordWrap)
  805. #else
  806. if (ch == chSpace)
  807. #endif
  808. {
  809. /* Speed kludge for spaces */
  810. ifi.xp += (vfli.rgdxp[ifi.ich] = dxp =
  811. fFlmPrinting ? vfmiPrint.dxpSpace : vfmiScreen.dxpSpace);
  812. ifi.xpPr += (dxpPr = vfmiPrint.dxpSpace);
  813. vfli.rgch[ifi.ich++] = chSpace;
  814. #ifdef DFLI
  815. {
  816. char rgch[100];
  817. wsprintf(rgch," chSpace , xp==%d/%d, xpPr==%d/%d",
  818. ifi.xp, ifi.xpRight, ifi.xpPr, ifi.xpPrRight);
  819. CommSz(rgch);
  820. }
  821. #endif
  822. goto BreakOppr;
  823. }
  824. #ifndef TEMP_KOREA
  825. /* If the printer width is not in the printer width table, then get
  826. it. */
  827. if (ch < chFmiMin || ch >= chFmiMax || (dxpPr =
  828. vfmiPrint.mpchdxp[ch]) == dxpNil)
  829. {
  830. #ifdef DBCS
  831. /* Don't pass to DxpFromCh() DBCS LeadByte except for '8140H'.
  832. ** Because the function can make elleagal ShiftJIS and pass it
  833. ** to GetTextExtent(). GetTextExtent might return SBC space
  834. ** when the code is undefined. this will cause win-hang-up at
  835. ** formatting line. yutakan
  836. */
  837. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  838. dxpPr=DBCSDxpFromCh(ch, ( ((cp + ifi.ich) < cpMac) ?
  839. pch[ifi.ichFetch] : 0 ), TRUE);
  840. #else
  841. dxpPr=DBCSDxpFromCh(ch,pch[ifi.ichFetch],TRUE);
  842. #endif //TAIWAN
  843. #else
  844. dxpPr = DxpFromCh(ch, TRUE);
  845. #endif
  846. }
  847. if (fFlmPrinting)
  848. {
  849. /* If we are printing, then there is no need to bother with the
  850. screen width. */
  851. dxp = dxpPr;
  852. }
  853. else if (ch < chFmiMin || ch >= chFmiMax ||
  854. (dxp = vfmiScreen.mpchdxp[ch]) == dxpNil)
  855. #ifdef DBCS
  856. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  857. dxp = DBCSDxpFromCh(ch, ( ((cp + ifi.ich) < cpMac) ?
  858. pch[ifi.ichFetch] : 0 ), FALSE);
  859. #else
  860. // yutakan:
  861. dxp = DBCSDxpFromCh(ch,pch[ifi.ichFetch],FALSE);
  862. #endif //TAIWAN
  863. #else
  864. dxp = DxpFromCh(ch, FALSE);
  865. #endif /* ifdef DBCS */
  866. #endif /* ifndef KOREA */
  867. #ifdef DBCS /* was in JAPAN */
  868. //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  869. //#ifdef TAIWAN
  870. // if (IsDBCSLeadByte(ch) && !pch[ifi.ichFetch]) {
  871. // ifi.xp += (vfli.rgdxp[ifi.ich] = (dxp/2));
  872. // ifi.xpPr += (dxpPr/2);
  873. // vfli.rgch[ifi.ich++] = ch;
  874. // vfli.rgch[ifi.ich] = NULL;
  875. // goto OnlyDBCSPaste;
  876. // }
  877. //#endif
  878. /*T-HIROYN add from 3.0*/
  879. ifi.xp += (vfli.rgdxp[ifi.ich] = dxp);
  880. ifi.xpPr += dxpPr;
  881. vfli.rgch[ifi.ich++] = ch;
  882. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  883. // BUG 5477: Echen: add NON FA font, LeadByte + 2nd byte checking
  884. if (((cp + ifi.ich) < cpMac) && IsDBCSLeadByte(ch) &&
  885. GetFontAssocStatus(vhMDC)) {
  886. #else
  887. if (IsDBCSLeadByte(ch)) {
  888. #endif //TAIWAN
  889. CHAR ch2;
  890. if (ifi.ich + 1 >= ichMaxLine) {
  891. /* It's full. Do the break without this kanji character. */
  892. #ifndef TEMP_KOREA
  893. ifi.ich--;
  894. #endif
  895. ifi.ichFetch--; /* We don't want to skip the first byte. */
  896. #ifndef TEMP_KOREA
  897. ifi.xp -= dxp;
  898. ifi.xpPr -= dxpPr;
  899. #endif
  900. lblFull2: /* new label of line full case ( for kanji and kana ) */
  901. goto DoBreak;
  902. }
  903. /* Now all is well. Get the second byte of the kanji
  904. character of interest from the current run. */
  905. /* Get the second byte of the kanji character from
  906. the current run. If we run of the current run,
  907. use FetchRgch() to staple us over. */
  908. #ifdef TEMP_KOREA /* for variable width, 90.12.26 by sangl */
  909. vfli.rgch[ifi.ich++] = ch;
  910. #endif
  911. if (ifi.ichFetch == cch)
  912. {
  913. if (fTruncated)
  914. {
  915. cchUsed += cch;
  916. pch = vpchFetch + cchUsed;
  917. cch = vcchFetch - cchUsed;
  918. fTruncated = false;
  919. ch2 = vfli.rgch[ifi.ich] = pch[ifi.ichFetch++];
  920. }
  921. else {
  922. int cchFetch;
  923. /* Save parameters needed for the re-fetch. */
  924. cpFetchSave = vcpFetch;
  925. ichFetchSave = vichFetch;
  926. cchUsedSave = cchUsed;
  927. cpSeqFetch = vcpFetch + cch + 1;
  928. FetchRgch(&cchFetch, &ch2, docNil, cpNil,
  929. vcpFetch + cch + 1, 1);
  930. fOddBoundary = true;
  931. Assert(cchFetch != 0); /* Better fetched something for us. */
  932. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  933. if ( !cchFetch ) goto SingleDBCS;
  934. #endif //TAIWAN
  935. /* Now, let's settle related parameters. */
  936. pch = &ch2;
  937. cch = cchFetch;
  938. ifi.ichFetch = 1; /* == cch */
  939. cchUsed = 0;
  940. vfli.rgch[ifi.ich] = ch2;
  941. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  942. //adjust DBCS char width by the new fetched 2nd byte
  943. {
  944. int dxpPr2, dxp2;
  945. dxpPr2 = DBCSDxpFromCh(ch, ch2, TRUE);
  946. if (fFlmPrinting) dxp2 = dxpPr2;
  947. else dxp2 = DBCSDxpFromCh(ch, ch2, FALSE);
  948. vfli.rgdxp[ifi.ich - 1] += (dxp2 - dxp);
  949. ifi.xp += (dxp2 - dxp);
  950. ifi.xpPr += (dxpPr2 - dxpPr);
  951. }
  952. #endif //TAIWAN
  953. }
  954. }
  955. else
  956. {
  957. ch2 = vfli.rgch[ifi.ich] = pch[ifi.ichFetch++];
  958. }
  959. #ifdef TEMP_KOREA /* For variable width, 90.12.26 by sangl */
  960. { unsigned int wd;
  961. wd = (ch<<8) + ch2;
  962. dxpPr = DxpFromCh(wd, TRUE);
  963. if (fFlmPrinting) /* if we are printing, then there is */
  964. /* no need to bother with the screen width */
  965. dxp = dxpPr;
  966. else
  967. dxp = DxpFromCh(wd, FALSE);
  968. ifi.xp += (vfli.rgdxp[ifi.ich-1] = dxp);
  969. ifi.xpPr += dxpPr;
  970. vfli.rgdxp[ifi.ich++] = 0;
  971. }
  972. #else
  973. vfli.rgdxp[ifi.ich++] = 0; /* The second byte has 0 width. */
  974. #endif /* KOREA */
  975. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
  976. if (FKanjiSpace(ch, ch2) && vfWordWrap)
  977. #else
  978. if (FKanjiSpace(ch, ch2))
  979. #endif
  980. {
  981. fKanjiPrevious = true;
  982. fKanjiBreakOppr = false; /* Treat it like a regular space. */
  983. dichSpaceAdjust = cchKanji;
  984. goto BreakOppr;
  985. }
  986. if (ifi.xpPr > ifi.xpPrRight ) {
  987. fKanjiBreakOppr = false; /* Reset the flag */
  988. if (FAdmitCh2(ch, ch2) ||
  989. (fKanjiPrevious && FOptAdmitCh2(ch, ch2))) {
  990. /* We do a line break including this odd character. */
  991. /* Make sure non-printables won't start a new line. */
  992. /* If we already have a hanging character on the */
  993. /* line, we don't want to treat this character as */
  994. /* a hanging one. */
  995. if (!fKanjiHanging )
  996. {
  997. fKanjiHanging = TRUE;
  998. ch = chHyphen;
  999. goto BreakOppr;
  1000. }
  1001. }
  1002. #ifndef JAPAN // added by Hiraisi (BUG#3542)
  1003. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
  1004. if(vfWordWrap)
  1005. #endif
  1006. ifi.ich--;
  1007. #endif
  1008. /* If this run was the result of an odd boundary run,
  1009. re-fetch. */
  1010. if (fOddBoundary && ifi.ichFetch == 1 )
  1011. {
  1012. FetchCp(doc, cpFetchSave, ichFetchSave,
  1013. fcmBoth + fcmParseCaps);
  1014. /* This fetch is guaranteed to result to non-null run. */
  1015. fOddBoundary = false;
  1016. pch = vpchFetch;
  1017. ifi.ichFetch = cch = vcchFetch;
  1018. #ifdef JAPAN // added by Hiraisi (BUG#3542)
  1019. ifi.ichFetch++;
  1020. #endif
  1021. cchUsed = cchUsedSave;
  1022. }
  1023. #ifndef JAPAN // added by Hiraisi (BUG#3542)
  1024. else
  1025. {
  1026. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
  1027. if(vfWordWrap)
  1028. #endif
  1029. ifi.ichFetch--;
  1030. }
  1031. #endif
  1032. /* ifi.xp and ifi.xpPr hasn't changed yet. */
  1033. goto lblFull2;
  1034. #ifdef TEMP_KOREA /* 90.12.26 : For variable width, 90.12.26 by sangl */
  1035. ifi.xp -= dxp;
  1036. ifi.xpPr -= dxpPr;
  1037. #endif /* KOREA */
  1038. }
  1039. #if defined(JAPAN) || defined(KOREA) // added 26 Jun. 1992 by Hiraisi
  1040. iWidenChar++;
  1041. #elif defined(TAIWAN) || defined(PRC)//Daniel/MSTC, 1993/02/25 , for jcBoth
  1042. iWidenChar++;
  1043. #endif
  1044. /* Record the line break opportunity while processing
  1045. it as a regular character at the same time. */
  1046. fKanjiBreakOppr = true;
  1047. fKanjiPrevious = true;
  1048. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
  1049. if(!vfWordWrap)
  1050. goto DefaultCh;
  1051. #endif
  1052. goto BreakOppr;
  1053. }
  1054. else {
  1055. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio add WordWrap flag*/
  1056. if (FKana(ch) && vfWordWrap) {
  1057. /* If it is a 1-byte kana letter, we want to treat it
  1058. in the same way as a kanji letter. */
  1059. if (ifi.xpPr > ifi.xpPrRight) {
  1060. fKanjiBreakOppr = false; /* Reset the flag */
  1061. if (FAdmitCh1(ch)) {
  1062. /* Make sure non-printables won't start a new line. */
  1063. /* If we already have a hanging character on the */
  1064. /* line, we don't want to treat this character as */
  1065. /* a hanging one. */
  1066. if (!fKanjiHanging) {
  1067. fKanjiHanging = TRUE;
  1068. ch = chHyphen;
  1069. goto BreakOppr;
  1070. }
  1071. }
  1072. goto lblFull2;
  1073. }
  1074. #if defined(JAPAN) || defined(KOREA) // added 22 Jun. 1992 by Hiraisi
  1075. iWidenChar++;
  1076. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25 , for jcBoth
  1077. iWidenChar++;
  1078. #endif
  1079. fKanjiPrevious = true;
  1080. fKanjiBreakOppr = true;
  1081. /* Go through the break opprotunity processing, then the
  1082. default character processing. */
  1083. goto BreakOppr;
  1084. }
  1085. else {
  1086. #endif /* JAPAN */
  1087. #ifdef TEMP_KOREA /* For variable width by sangl 90.12.26 */
  1088. if (ch < chFmiMin || ch >= chFmiMax || (dxpPr =
  1089. vfmiPrint.mpchdxp[ch]) == dxpNil)
  1090. {
  1091. dxpPr = DxpFromCh(ch, TRUE);
  1092. }
  1093. if (fFlmPrinting)
  1094. {
  1095. /* If we are printing, then there is no need to bother
  1096. with the screen width */
  1097. dxp = dxpPr;
  1098. }
  1099. else if (ch < chFmiMin || ch >= chFmiMax ||
  1100. (dxp = vfmiScreen.mpchdxp[ch]) == dxpNil)
  1101. dxp = dxpFromCh(ch, FALSE);
  1102. ifi.xp += (vfli.rgdxp[ifi.ich] = dxp);
  1103. ifi.xpPr += dxpPr;
  1104. vfli.rgch[ifi.ich++] = ch;
  1105. #endif /* KOREA */
  1106. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  1107. SingleDBCS:
  1108. #endif //TAIWAN
  1109. if (fKanjiPrevious && FOptAdmitCh1(ch)) {
  1110. fKanjiPrevious = false;
  1111. if (ifi.xpPr > ifi.xpPrRight) {
  1112. fKanjiBreakOppr = false;
  1113. /* If we already have a hanging character past the
  1114. margin, we don't want to treat this as a
  1115. hanging character. */
  1116. if (!fKanjiHanging) {
  1117. fKanjiHanging = true;
  1118. ch = chHyphen;
  1119. goto BreakOppr;
  1120. }
  1121. }
  1122. else {
  1123. /* We can treat this character as though a Kanji
  1124. punctuation, as far as line breaking is
  1125. is concerned. */
  1126. fKanjiBreakOppr = true;
  1127. goto BreakOppr;
  1128. }
  1129. }
  1130. else {
  1131. /* Just go on with a regular English formatting. */
  1132. fKanjiBreakOppr = false;
  1133. fKanjiPrevious = false;
  1134. }
  1135. }
  1136. #if defined(JAPAN) || defined(KOREA)
  1137. }
  1138. #endif
  1139. #else /* DBCS */
  1140. ifi.xp += (vfli.rgdxp[ifi.ich] = dxp);
  1141. ifi.xpPr += dxpPr;
  1142. vfli.rgch[ifi.ich++] = ch;
  1143. #endif
  1144. #if defined (TAIWAN)
  1145. OnlyDBCSPaste:
  1146. #endif
  1147. /* special case "normal characters" above hyphen */
  1148. if (ch > chHyphen)
  1149. goto DefaultCh;
  1150. #if defined(JAPAN) || defined(KOREA) /*t-Yoshio*/
  1151. /*Non Word wrap Not Hyphen break*/
  1152. if(!vfWordWrap) {
  1153. if (ch == chHyphen)
  1154. goto DefaultCh;
  1155. }
  1156. #endif
  1157. switch (ch)
  1158. {
  1159. #ifdef CRLF
  1160. case chReturn:
  1161. /* Undo damage */
  1162. ifi.ich--;
  1163. ifi.xp -= dxp;
  1164. ifi.xpPr -= dxpPr;
  1165. continue;
  1166. #endif /* CRLF */
  1167. case chNRHFile:
  1168. /* Undo damage */
  1169. ifi.ich--;
  1170. ifi.xp -= dxp;
  1171. ifi.xpPr -= dxpPr;
  1172. ichpNRH = ichpFormat - 1;
  1173. #ifdef DFLI
  1174. {
  1175. char rgch[100];
  1176. wsprintf(rgch," OptHyph: width==%d, xpPr==%d/%d\n\r",
  1177. DxpFromCh(chHyphen,true), ifi.xpPr,ifi.xpPrRight);
  1178. CommSz(rgch);
  1179. }
  1180. #endif
  1181. if (ifi.xpPr + DxpFromCh(chHyphen, true) > ifi.xpPrRight)
  1182. {
  1183. /* Won't fit, force a break */
  1184. goto DoBreak;
  1185. }
  1186. #ifdef CASHMERE
  1187. else if (fVisiMode)
  1188. {
  1189. /* Treat just like a normal hyphen */
  1190. ch = chHyphen;
  1191. goto NormChar;
  1192. }
  1193. #endif /* CASHMERE */
  1194. xpPrev = ifi.xp;
  1195. vfli.rgch[ifi.ich] = chTab;
  1196. goto Tab0;
  1197. case chSect:
  1198. /* Undo damage */
  1199. ifi.ich--;
  1200. ifi.xp -= dxp;
  1201. ifi.xpPr -= dxpPr;
  1202. vfli.dypFont = vfli.dypLine = (dypAscentMac + (vfli.dypBase
  1203. = dypDescentMac));
  1204. vfli.cpMac = vcpFetch + ifi.ichFetch;
  1205. if (FFirstIch(ifi.ich))
  1206. {
  1207. /* Beginning of line; return a splat */
  1208. vfli.fSplat = true;
  1209. if (!fFlmPrinting)
  1210. {
  1211. #ifdef CASHMERE
  1212. int chT = vfli.cpMac == vcpLimSectCache ?
  1213. chSectSplat : chSplat;
  1214. #else /* not CASHMERE */
  1215. int chT = chSplat;
  1216. #endif /* not CASHMERE */
  1217. int dxpCh = DxpFromCh(chT, false);
  1218. /* Set the width of the splat to be about 8.5" */
  1219. int cch = min((dxpLogInch * 17 / 2) / dxpCh,
  1220. ichMaxLine - 32);
  1221. bltbc(&vfli.rgch[ifi.ich], chT, cch);
  1222. bltc(&vfli.rgdxp[ifi.ich], dxpCh, cch);
  1223. vfli.ichMac = cch + ifi.ich;
  1224. vfli.xpReal = LOWORD(GetTextExtent(vhMDC,
  1225. (LPSTR)vfli.rgch, cch));
  1226. vfli.xpLeft = 0;
  1227. }
  1228. else
  1229. {
  1230. vfli.ichMac = 0;
  1231. }
  1232. goto EndFormat;
  1233. }
  1234. /* The section character is in the middle of a line, the
  1235. line will terminate in front of the character. */
  1236. /* vfSplatNext = TRUE; No longer used*/
  1237. vfli.cpMac += cchUsed - 1;
  1238. vfli.dcpDepend = 1;
  1239. if (!ifi.fPrevSpace)
  1240. {
  1241. ifi.cBreak = ifi.cchSpace;
  1242. vfli.ichReal = ifi.ich;
  1243. vfli.xpReal = ifi.xpReal = ifi.xp;
  1244. }
  1245. vfli.ichMac = ifi.ich;
  1246. vfli.dypLine = ifi.dypLineSize;
  1247. goto JustBreak;
  1248. case chTab:
  1249. /* Undo damage */
  1250. ifi.ich--;
  1251. ifi.xp -= dxp;
  1252. ifi.xpPr -= dxpPr;
  1253. if (ifi.xpPr < ifi.xpPrRight)
  1254. {
  1255. register struct CHP *pchp;
  1256. unsigned xaPr;
  1257. unsigned xaTab;
  1258. if (!ifi.fPrevSpace)
  1259. {
  1260. /* Remember number of spaces to left and number of
  1261. real chars in line for justification */
  1262. ifi.cBreak = ifi.cchSpace;
  1263. vfli.ichReal = ifi.ich;
  1264. ifi.xpReal = ifi.xp;
  1265. }
  1266. if (ifi.jc != jcTabLeft)
  1267. {
  1268. Justify(&ifi, xpTab, flm);
  1269. }
  1270. xpPrev = ifi.xp;
  1271. /* Now get info about this tab */
  1272. xaPr = MultDiv(ifi.xpPr, dxaPrPage, dxpPrPage);
  1273. while ((xaTab = ptbd->dxa) != 0)
  1274. {
  1275. #ifdef DBCS /* was in JAPAN */
  1276. if (xaTab >= xaRight)
  1277. #else
  1278. if (xaTab > xaRight)
  1279. #endif
  1280. {
  1281. /* Don't let tabs extend past right margin. */
  1282. #ifdef DBCS /* was in JAPAN */
  1283. break; // Stop to examin next tab-stop
  1284. #else
  1285. xaTab = xaRight;
  1286. #endif
  1287. }
  1288. if (xaTab >= xaPr)
  1289. {
  1290. /* Use tab stop information */
  1291. #ifdef CASHMERE
  1292. ifi.tlc = ptbd->tlc;
  1293. #endif /* CASHMERE */
  1294. ifi.jc = jcTabMin + (ptbd++)->jc;
  1295. #ifdef ENABLE /* we do the mapping in HgtbdCreate */
  1296. if (ifi.jc != jcTabDecimal)
  1297. {
  1298. ifi.jc = jcTabLeft;
  1299. }
  1300. #endif
  1301. goto TabFound;
  1302. }
  1303. ptbd++;
  1304. }
  1305. /* Out of set tabs; go to next nth column */
  1306. xaTab = (xaPr / (vzaTabDflt) + 1) * (vzaTabDflt);
  1307. #ifdef CASHMERE
  1308. ifi.tlc = tlcWhite;
  1309. #endif /* CASHMERE */
  1310. ifi.jc = jcTabLeft;
  1311. TabFound:
  1312. xpTab = imax(MultDiv(xaTab, dxpFormat, dxaFormat),
  1313. ifi.xp);
  1314. /* Do left-justified tabs immediately */
  1315. if (ifi.jc == jcTabLeft)
  1316. {
  1317. ifi.xp = xpTab;
  1318. ifi.xpPr = MultDiv(xaTab, dxpPrPage, dxaPrPage);
  1319. }
  1320. ifi.xpLeft = ifi.xp;
  1321. ifi.ichLeft = ifi.ich;
  1322. ifi.cchSpace = 0;
  1323. ifi.chBreak = 0;
  1324. #if defined(JAPAN) || defined(KOREA) // added 02 Jul. 1992 by Hiraisi
  1325. iWidenChar=0;
  1326. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  1327. iWidenChar=0;
  1328. #endif
  1329. Tab0:
  1330. ifi.fPrevSpace = false;
  1331. vfli.ichMac = ifi.ich;
  1332. vfli.xpReal = ifi.xp;
  1333. vfli.dypLine = ifi.dypLineSize;
  1334. vfli.dypBase = dypDescentMac;
  1335. vfli.dypFont = dypAscentMac + dypDescentMac;
  1336. if (ifi.ichFetch != 1 && (ichpFormat != ichpMacFormat
  1337. || FGrowFormatHeap()))
  1338. {
  1339. /* Probably in real trouble if FGrowFormatHeap fails
  1340. at this point */
  1341. pchp = &(**vhgchpFormat)[ichpFormat - 1];
  1342. if (ichpFormat > 0)
  1343. {
  1344. /* Finish off previous run */
  1345. pchp->ichRun = ifi.ichPrev;
  1346. pchp->cchRun = ifi.ich - ifi.ichPrev;
  1347. }
  1348. blt(&chpLocal, ++pchp, cwCHP);
  1349. ichpFormat++;
  1350. }
  1351. else
  1352. {
  1353. pchp = &(**vhgchpFormat)[ichpFormat - 1];
  1354. }
  1355. pchp->ichRun = ifi.ich;
  1356. pchp->cchRun = ichMaxLine;
  1357. #ifdef CASHMERE
  1358. pchp->chLeader = mptlcch[ifi.tlc];
  1359. #endif /* CASHMERE */
  1360. vfli.rgdxp[ifi.ichPrev = ifi.ich++] = ifi.xp - xpPrev;
  1361. if (ch != chTab)
  1362. {
  1363. /* This character is a non-required hyphen. */
  1364. Dfli(CommSz("ch is really OptHyph "));
  1365. goto BreakOppr;
  1366. }
  1367. continue;
  1368. }
  1369. else
  1370. {
  1371. ch = chNBSFile;
  1372. goto NormChar;
  1373. }
  1374. case chHyphen:
  1375. if (ifi.xpPr > ifi.xpPrRight)
  1376. {
  1377. goto DoBreak;
  1378. }
  1379. BreakOppr:
  1380. Dfli(CommSz(" BKOPPR\n\r"));
  1381. /* this case never used in switch - always goto here */
  1382. /* case chSpace: */
  1383. if (ifi.ich >= ichMaxLine)
  1384. {
  1385. Dfli(CommSzNum(" Unbroken, ich>ichMaxLine\n\r"));
  1386. goto Unbroken;
  1387. }
  1388. case chEol:
  1389. case chNewLine:
  1390. ifi.chBreak = ch;
  1391. vfli.cpMac = vcpFetch + cchUsed + ifi.ichFetch;
  1392. vfli.xpReal = ifi.xp;
  1393. vfli.ichMac = ifi.ich;
  1394. vfli.dypLine = ifi.dypLineSize;
  1395. vfli.dypFont = dypAscentMac + (vfli.dypBase =
  1396. dypDescentMac);
  1397. Dfli(CommSzNumNum(" vfli.xpReal, ichMac ",vfli.xpReal,vfli.ichMac));
  1398. #ifdef DBCS /* was in JAPAN */
  1399. /* We recorded the kanji break opportunity, go default
  1400. character processing. */
  1401. if (fKanjiBreakOppr)
  1402. {
  1403. ifi.cBreak = ifi.cchSpace;
  1404. vfli.ichReal = ifi.ich;
  1405. vfli.xpReal = ifi.xpReal = ifi.xp;
  1406. goto DefaultCh;
  1407. }
  1408. #endif
  1409. if (ch == chHyphen || ch == chNRHFile)
  1410. {
  1411. Dfli(CommSz(" chHyph/OptHyph catch \n\r"));
  1412. ifi.cBreak = ifi.cchSpace;
  1413. vfli.ichReal = ifi.ich;
  1414. vfli.xpReal = ifi.xpReal = ifi.xp;
  1415. }
  1416. else
  1417. {
  1418. if (!ifi.fPrevSpace)
  1419. {
  1420. Dfli(CommSz("!fPrevSpace \n\r"));
  1421. ifi.cBreak = ifi.cchSpace;
  1422. #ifdef DBCS /* was in JAPAN */
  1423. vfli.ichReal = ifi.ich - dichSpaceAdjust;
  1424. dichSpaceAdjust = 1;
  1425. #else
  1426. vfli.ichReal = ifi.ich - 1;
  1427. #endif
  1428. ifi.xpReal = (vfli.xpReal = ifi.xp) - dxp;
  1429. }
  1430. if (ch == chEol || ch == chNewLine)
  1431. {
  1432. #ifdef CASHMERE
  1433. if (hfntb != 0 && vfli.cpMac ==
  1434. (**hfntb).rgfnd[0].cpFtn)
  1435. {
  1436. /* End of footnote */
  1437. if (!fFlmPrinting)
  1438. {
  1439. vfli.rgch[ifi.ich - 1] = chEMark;
  1440. vfli.xpReal += (vfli.rgdxp[ifi.ich - 1] =
  1441. DxpFromCh(chEMark, false)) - dxp;
  1442. vfli.ichReal++; /* show this guy */
  1443. }
  1444. }
  1445. else
  1446. #endif /* CASHMERE */
  1447. {
  1448. #ifdef CASHMERE
  1449. int chT = fVisiMode ? ChVisible(ch) : chSpace;
  1450. #else /* not CASHMERE */
  1451. int chT = chSpace;
  1452. #endif /* not CASHMERE */
  1453. int dxpNew = DxpFromCh(chT, fFlmPrinting);
  1454. vfli.rgch[ifi.ich - 1] = chT;
  1455. vfli.rgdxp[ifi.ich - 1] = dxpNew;
  1456. vfli.xpReal += (vfli.rgdxp[ifi.ich - 1] =
  1457. dxpNew) - dxp;
  1458. if (!ifi.fPrevSpace)
  1459. {
  1460. vfli.xpReal += dxpNew - dxp;
  1461. #ifdef CASHMERE
  1462. vfli.ichReal =
  1463. fVisiMode ? ifi.ich : ifi.ich - 1;
  1464. #else /* not CASHMERE */
  1465. vfli.ichReal = ifi.ich - 1;
  1466. #endif /* not CASHMERE */
  1467. }
  1468. }
  1469. if (ch == chEol)
  1470. {
  1471. JustEol:
  1472. if (fFlmPrinting)
  1473. {
  1474. vfli.ichMac = vfli.ichReal;
  1475. }
  1476. if (ifi.jc != jcTabLeft)
  1477. {
  1478. /* Handle last tab's text */
  1479. Justify(&ifi, xpTab, flm);
  1480. }
  1481. else if ((ifi.jc = ppap->jc) != jcBoth &&
  1482. ifi.jc != jcLeft)
  1483. {
  1484. /* Do line justification */
  1485. Justify(&ifi, ifi.xpRight, flm);
  1486. }
  1487. vfli.xpRight = ifi.xpRight;
  1488. goto EndFormat;
  1489. }
  1490. else
  1491. {
  1492. /* Handle a line break */
  1493. goto JustBreak;
  1494. }
  1495. }
  1496. ++ifi.cchSpace;
  1497. ifi.fPrevSpace = true;
  1498. }
  1499. break;
  1500. DefaultCh:
  1501. default:
  1502. #ifdef DFLI
  1503. {
  1504. char rgch[100];
  1505. wsprintf(rgch," DefaultCh: %c, xp==%d/%d, xpPr==%d/%d\n\r",
  1506. ch, ifi.xp, ifi.xpRight, ifi.xpPr, ifi.xpPrRight);
  1507. CommSz(rgch);
  1508. }
  1509. #endif /* ifdef DFLI */
  1510. #ifdef DBCS /* was in JAPAN */
  1511. /* Reset the flag for the next character. */
  1512. fKanjiBreakOppr = false;
  1513. #endif
  1514. if (ifi.xpPr > ifi.xpPrRight)
  1515. DoBreak:
  1516. {
  1517. Dfli(CommSz(" BREAK!\n\r"));
  1518. if (ifi.chBreak == 0)
  1519. Unbroken:
  1520. {
  1521. /* Admit first character to the line, even if margin
  1522. is crossed. First character at ifi.ich - 1 may be
  1523. preceded by 0 width characters. */
  1524. #ifdef DBCS
  1525. if (IsDBCSLeadByte(ch))
  1526. {
  1527. if (FFirstIch(ifi.ich-2) && ifi.ich<ichMaxLine)
  1528. goto PChar;
  1529. vfli.cpMac = vcpFetch+cchUsed+ifi.ichFetch-2;
  1530. vfli.ichReal = vfli.ichMac = ifi.ich - 2;
  1531. vfli.dypLine = ifi.dypLineSize;
  1532. vfli.dypFont = dypAscentMac + (vfli.dypBase =
  1533. dypDescentMac);
  1534. vfli.dcpDepend = 1;
  1535. #ifdef KKBUGFIX /*t-Yoshio*/
  1536. vfli.xpReal = ifi.xpReal = ifi.xp - dxp;
  1537. #else
  1538. vfli.xpReal = ifi.xpReal = ifi.xp - (dxp * 2);
  1539. #endif
  1540. }
  1541. else
  1542. {
  1543. if (FFirstIch(ifi.ich-1) && ifi.ich<ichMaxLine)
  1544. goto PChar;
  1545. vfli.cpMac = vcpFetch+cchUsed+ifi.ichFetch-1;
  1546. vfli.ichReal = vfli.ichMac = ifi.ich - 1;
  1547. vfli.dypLine = ifi.dypLineSize;
  1548. vfli.dypFont = dypAscentMac + (vfli.dypBase =
  1549. dypDescentMac);
  1550. vfli.dcpDepend = 1;
  1551. vfli.xpReal = ifi.xpReal = ifi.xp - dxp;
  1552. }
  1553. #else
  1554. if (FFirstIch(ifi.ich - 1) && ifi.ich < ichMaxLine)
  1555. {
  1556. goto PChar;
  1557. }
  1558. vfli.cpMac = vcpFetch + cchUsed + ifi.ichFetch - 1;
  1559. vfli.ichReal = vfli.ichMac = ifi.ich - 1;
  1560. vfli.dypLine = ifi.dypLineSize;
  1561. vfli.dypFont = dypAscentMac + (vfli.dypBase =
  1562. dypDescentMac);
  1563. vfli.dcpDepend = 1;
  1564. vfli.xpReal = ifi.xpReal = ifi.xp - dxp;
  1565. #endif
  1566. goto DoJustify;
  1567. }
  1568. vfli.dcpDepend = vcpFetch + ifi.ichFetch - vfli.cpMac;
  1569. JustBreak:
  1570. if (ifi.chBreak == chNRHFile)
  1571. {
  1572. /* Append a non-required hyphen to the end of the
  1573. line. (Replace zero length tab previously
  1574. inserted) */
  1575. Dfli(CommSz(" Breaking line at OptHyphen\n\r"));
  1576. ifi.xpReal += (vfli.rgdxp[vfli.ichReal - 1] =
  1577. DxpFromCh(chHyphen, fFlmPrinting));
  1578. vfli.xpRight = vfli.xpReal = ifi.xpReal;
  1579. vfli.rgch[vfli.ichReal - 1] = chHyphen;
  1580. vfli.ichMac = vfli.ichReal;
  1581. if (ichpNRH < ichpFormat - 1)
  1582. {
  1583. register struct CHP *pchp =
  1584. &(**vhgchpFormat)[ichpNRH];
  1585. pchp->cchRun++;
  1586. if (pchp->ichRun >= vfli.ichMac)
  1587. {
  1588. pchp->ichRun = vfli.ichMac - 1;
  1589. }
  1590. }
  1591. }
  1592. if (fFlmPrinting)
  1593. {
  1594. vfli.ichMac = vfli.ichReal;
  1595. }
  1596. if (ifi.jc != jcTabLeft)
  1597. {
  1598. Justify(&ifi, xpTab, flm);
  1599. }
  1600. else
  1601. {
  1602. DoJustify:
  1603. if ((ifi.jc = ppap->jc) != jcLeft)
  1604. {
  1605. Dfli(CommSzNum(" DoJustify: xpRight ",ifi.xpRight));
  1606. Justify(&ifi, ifi.xpRight, flm);
  1607. }
  1608. }
  1609. vfli.xpRight = ifi.xpRight;
  1610. EndFormat:
  1611. vfli.ichLastTab = ifi.ichLeft;
  1612. #ifdef CASHMERE
  1613. if (vfli.cpMac == vcpLimParaCache)
  1614. {
  1615. vfli.dypAfter = vpapAbs.dyaAfter / DyaPerPixFormat;
  1616. vfli.dypLine += vfli.dypAfter;
  1617. vfli.dypBase += vfli.dypAfter;
  1618. }
  1619. #endif /* CASHMERE */
  1620. Scribble(5, ' ');
  1621. return;
  1622. }
  1623. else
  1624. {
  1625. PChar:
  1626. /* A printing character */
  1627. ifi.fPrevSpace = false;
  1628. }
  1629. break;
  1630. } /* Switch */
  1631. #ifdef DBCS /* was in KKBUGFIX */
  1632. //
  1633. // [yutakan:04/02/91]
  1634. //
  1635. if(vfOutOfMemory == TRUE)
  1636. return;
  1637. #endif
  1638. }
  1639. } /* for ( ; ; ) */
  1640. Scribble(5, ' ');
  1641. }
  1642. /* J U S T I F Y */
  1643. near Justify(pifi, xpTab, flm)
  1644. struct IFI *pifi;
  1645. unsigned xpTab;
  1646. int flm;
  1647. {
  1648. int dxp;
  1649. int ichT;
  1650. int xpLeft;
  1651. // justified paragraph is restored in Windows 3.1J by Hiraisi
  1652. //#ifdef JAPAN
  1653. // /* In the Kanji Write, there is no justified paragraph. */
  1654. // if (pifi->jc == jcBoth)
  1655. // {
  1656. // /* Assert(FALSE); */
  1657. // pifi->jc = jcLeft;
  1658. // dxp = 0; /* by yutakan / 08/03/91 */
  1659. // }
  1660. //#endif /* ifdef JAPAN */
  1661. xpLeft = pifi->xpLeft;
  1662. switch (pifi->jc)
  1663. {
  1664. CHAR *pch;
  1665. unsigned *pdxp;
  1666. #ifdef CASHMERE
  1667. case jcTabLeft:
  1668. case jcLeft:
  1669. return;
  1670. case jcTabRight:
  1671. dxp = xpTab - pifi->xpReal;
  1672. break;
  1673. case jcTabCenter:
  1674. dxp = (xpTab - xpLeft) - ((pifi->xpReal - xpLeft + 1) >> 1);
  1675. break;
  1676. #endif /* CASHMERE */
  1677. case jcTabDecimal:
  1678. dxp = xpTab - xpLeft;
  1679. for (ichT = pifi->ichLeft + 1; ichT < vfli.ichReal &&
  1680. vfli.rgch[ichT] != vchDecimal; ichT++)
  1681. {
  1682. dxp -= vfli.rgdxp[ichT];
  1683. }
  1684. break;
  1685. case jcCenter:
  1686. if ((dxp = xpTab - pifi->xpReal) <= 0)
  1687. {
  1688. return;
  1689. }
  1690. dxp = dxp >> 1;
  1691. break;
  1692. case jcRight:
  1693. dxp = xpTab - pifi->xpReal;
  1694. break;
  1695. case jcBoth:
  1696. //#if !defined(JAPAN) // added 22 Jun. 1992 by Hiraisi
  1697. #if !defined(JAPAN) && !defined(TAIWAN) && !defined(PRC) // Daniel/MSTC, 1993/02/25, for jcBoth
  1698. if (pifi->cBreak == 0)
  1699. {
  1700. /* Ragged edge forced */
  1701. return;
  1702. }
  1703. #endif
  1704. if ((dxp = xpTab - pifi->xpReal) <= 0)
  1705. {
  1706. /* There is nothing to do. */
  1707. return;
  1708. }
  1709. //#if !defined(JAPAN) // added 22 Jun. 1992 by Hiraisi
  1710. #if !defined(JAPAN) && !defined(TAIWAN) && !defined(PRC)//Daniel/MSTC, 1992,02,25, for jcBoth
  1711. pifi->xp += dxp;
  1712. vfli.xpReal += dxp;
  1713. vfli.dxpExtra = dxp / pifi->cBreak;
  1714. #endif
  1715. /* Rounding becomes a non-existant issue due to brilliant
  1716. re-thinking.
  1717. "What a piece of work is man
  1718. How noble in reason
  1719. In form and movement,
  1720. how abject and admirable..."
  1721. Bill "Shake" Spear [describing Sand Word] */
  1722. {
  1723. #ifdef JAPAN // added 22 Jun. 1992 by Hiraisi
  1724. /*
  1725. * In Japan, we examine the buffer from the beginning of the line.
  1726. * We find some NULLs in the buffer when a char is deleted,
  1727. * but we can ignore all of them.
  1728. */
  1729. register CHAR *pch;
  1730. register int *pdxp;
  1731. CHAR *endPt;
  1732. int dxpT = dxp;
  1733. int cxpQuotient;
  1734. int cNonWideSpaces;
  1735. int ichLeft;
  1736. if( pifi->ichLeft >= 0 ) /* including some tabs in line */
  1737. ichLeft = pifi->ichLeft;
  1738. else
  1739. ichLeft = 0;
  1740. pch = &vfli.rgch[ichLeft];
  1741. pdxp = &vfli.rgdxp[ichLeft];
  1742. endPt = &vfli.rgch[vfli.ichReal];
  1743. if( vfWordWrap ){ /* Word Wrap ON */
  1744. /*
  1745. * We examine whether there is no break between a non-Japanese
  1746. * char and a following Japanese char. The reason is that we
  1747. * need to widen the non-Japanese char (except tab and space)
  1748. * if we can find no break there.
  1749. */
  1750. for( ; pch<endPt ; ){
  1751. if( IsDBCSLeadByte( *pch ) ){
  1752. pch+=2;
  1753. }
  1754. else{
  1755. if( *pch != chSpace && *pch != chTab &&
  1756. !FKana( *pch ) && *pch != NULL ){
  1757. CHAR *ptr;
  1758. for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
  1759. if( IsDBCSLeadByte(*ptr) ){
  1760. iWidenChar++;
  1761. pch+=2;
  1762. }
  1763. else{
  1764. if( FKana(*ptr) ){
  1765. iWidenChar++;
  1766. pch++;
  1767. }
  1768. }
  1769. }
  1770. pch++;
  1771. }
  1772. }
  1773. /*
  1774. * We decrease iWidenChar if last char of the current line
  1775. * is Japanese, because it needs not to be widened.
  1776. */
  1777. if( *(endPt-1) == NULL ){
  1778. for( endPt-- ; *endPt==NULL ; endPt-- );
  1779. endPt++;
  1780. }
  1781. if( IsDBCSLeadByte(*(endPt-2)) ){
  1782. iWidenChar--;
  1783. }
  1784. else{
  1785. if( FKana(*(endPt-1)) )
  1786. iWidenChar--;
  1787. }
  1788. iWidenChar += pifi->cBreak;
  1789. }
  1790. else{ /* Word Wrap OFF */
  1791. /* We widen all chars except last char in the line. */
  1792. int iDBCS, ichReal;
  1793. for( iDBCS=0, ichReal=vfli.ichReal ; pch<endPt ; pch++ ){
  1794. if( IsDBCSLeadByte( *pch ) ){
  1795. pch++;
  1796. iDBCS++;
  1797. }
  1798. else{
  1799. if( *pch == NULL )
  1800. ichReal--;
  1801. }
  1802. }
  1803. iWidenChar = ichReal - ichLeft - iDBCS - 1;
  1804. }
  1805. if( iWidenChar == 0 )
  1806. return;
  1807. pifi->xp += dxp;
  1808. vfli.xpReal += dxp;
  1809. vfli.dxpExtra = dxp / iWidenChar;
  1810. cNonWideSpaces = iWidenChar - (dxp % iWidenChar);
  1811. cxpQuotient = vfli.dxpExtra;
  1812. iNonWideSpaces = cNonWideSpaces;
  1813. vfli.ichFirstWide = 0;
  1814. vfli.fAdjSpace = fTrue;
  1815. pch = &vfli.rgch[ichLeft]; /* Reset pch */
  1816. for( ; ; ){
  1817. if( IsDBCSLeadByte(*pch) ){
  1818. if( vfli.ichFirstWide == 0 ){
  1819. int *pdxpT = pdxp;
  1820. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  1821. }
  1822. *pdxp += cxpQuotient;
  1823. if( --iWidenChar == 0 )
  1824. return;
  1825. if( --cNonWideSpaces == 0 )
  1826. cxpQuotient++;
  1827. pch++;
  1828. pdxp++;
  1829. }
  1830. else{
  1831. if( vfWordWrap ){ /* Word Wrap ON */
  1832. if( *pch == chSpace || FKana(*pch) ){
  1833. if( vfli.ichFirstWide == 0 ){
  1834. int *pdxpT = pdxp;
  1835. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  1836. }
  1837. *pdxp += cxpQuotient;
  1838. if( --iWidenChar == 0 )
  1839. return;
  1840. if( --cNonWideSpaces == 0 )
  1841. cxpQuotient++;
  1842. }
  1843. else{
  1844. if( *pch != chTab && *pch != NULL ){
  1845. CHAR *ptr;
  1846. /*
  1847. * We examine whether the following char of
  1848. * non-Japanese char is Japanese.
  1849. */
  1850. for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
  1851. if( IsDBCSLeadByte(*ptr) || FKana(*ptr) ){
  1852. if( vfli.ichFirstWide == 0 ){
  1853. int *pdxpT = pdxp;
  1854. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  1855. }
  1856. *pdxp += cxpQuotient;
  1857. if( --iWidenChar == 0 )
  1858. return;
  1859. if( --cNonWideSpaces == 0 )
  1860. cxpQuotient++;
  1861. }
  1862. }
  1863. }
  1864. }
  1865. else{ /* Word Wrap OFF */
  1866. if( *pch != NULL ){
  1867. if( vfli.ichFirstWide == 0 ){
  1868. int *pdxpT = pdxp;
  1869. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  1870. }
  1871. *pdxp += cxpQuotient;
  1872. if( --iWidenChar == 0 )
  1873. return;
  1874. if( --cNonWideSpaces == 0 )
  1875. cxpQuotient++;
  1876. }
  1877. }
  1878. }
  1879. pch++;
  1880. pdxp++;
  1881. }
  1882. #elif defined(TAIWAN) || defined(PRC)//Daniel/MSTC, 1992/02/25, for jcBoth
  1883. /*
  1884. * In Japan, we examine the buffer from the beginning of the line.
  1885. * We find some NULLs in the buffer when a char is deleted,
  1886. * but we can ignore all of them.
  1887. */
  1888. register CHAR *pch;
  1889. register int *pdxp;
  1890. CHAR *endPt;
  1891. int dxpT = dxp;
  1892. int cxpQuotient;
  1893. int cNonWideSpaces;
  1894. int ichLeft;
  1895. if( pifi->ichLeft >= 0 ) /* including some tabs in line */
  1896. ichLeft = pifi->ichLeft;
  1897. else ichLeft = 0;
  1898. pch = &vfli.rgch[ichLeft];
  1899. pdxp = &vfli.rgdxp[ichLeft];
  1900. endPt = &vfli.rgch[vfli.ichReal];
  1901. // if( vfWordWrap ){ /* Word Wrap ON */
  1902. /*
  1903. * We examine whether there is no break between a non-Japanese
  1904. * char and a following Japanese char. The reason is that we
  1905. * need to widen the non-Japanese char (except tab and space)
  1906. * if we can find no break there.
  1907. */
  1908. for( ; pch<endPt ; )
  1909. {
  1910. if( IsDBCSLeadByte( *pch ) ) pch+=2;
  1911. else
  1912. {
  1913. if( *pch != chSpace && *pch != chTab && !FKana( *pch ) && *pch != NULL )
  1914. { CHAR *ptr;
  1915. for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
  1916. if( IsDBCSLeadByte(*ptr) )
  1917. {
  1918. iWidenChar++;
  1919. pch+=2;
  1920. }
  1921. else
  1922. {
  1923. if( FKana(*ptr) )
  1924. {
  1925. iWidenChar++;
  1926. pch++;
  1927. }
  1928. }
  1929. }
  1930. pch++;
  1931. }
  1932. }// for
  1933. /*
  1934. * We decrease iWidenChar if last char of the current line
  1935. * is Japanese, because it needs not to be widened.
  1936. */
  1937. if( *(endPt-1) == NULL )
  1938. {
  1939. for( endPt-- ; *endPt==NULL ; endPt-- );
  1940. endPt++;
  1941. }
  1942. if( IsDBCSLeadByte(*(endPt-2)) ) iWidenChar--;
  1943. else
  1944. {
  1945. if( FKana(*(endPt-1)) ) iWidenChar--;
  1946. }
  1947. iWidenChar += pifi->cBreak;
  1948. // } // vfWordWrap
  1949. if( iWidenChar == 0 )
  1950. return;
  1951. pifi->xp += dxp;
  1952. vfli.xpReal += dxp;
  1953. vfli.dxpExtra = dxp / iWidenChar;
  1954. cNonWideSpaces = iWidenChar - (dxp % iWidenChar);
  1955. cxpQuotient = vfli.dxpExtra;
  1956. iNonWideSpaces = cNonWideSpaces;
  1957. vfli.ichFirstWide = 0;
  1958. vfli.fAdjSpace = fTrue;
  1959. pch = &vfli.rgch[ichLeft]; /* Reset pch */
  1960. for( ; ; )
  1961. {
  1962. if( IsDBCSLeadByte(*pch) )
  1963. {
  1964. if( vfli.ichFirstWide == 0 )
  1965. {
  1966. int *pdxpT = pdxp;
  1967. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  1968. }
  1969. *pdxp += cxpQuotient;
  1970. if( --iWidenChar == 0 ) return;
  1971. if( --cNonWideSpaces == 0 ) cxpQuotient++;
  1972. pch++;
  1973. pdxp++;
  1974. }
  1975. else
  1976. {
  1977. // if( vfWordWrap )
  1978. if( 1 )
  1979. { /* Word Wrap ON */
  1980. if( *pch == chSpace || FKana(*pch) )
  1981. {
  1982. if( vfli.ichFirstWide == 0 )
  1983. {
  1984. int *pdxpT = pdxp;
  1985. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  1986. }
  1987. *pdxp += cxpQuotient;
  1988. if( --iWidenChar == 0 ) return;
  1989. if( --cNonWideSpaces == 0 ) cxpQuotient++;
  1990. }
  1991. else
  1992. {
  1993. if( *pch != chTab && *pch != NULL )
  1994. {
  1995. CHAR *ptr;
  1996. /*
  1997. * We examine whether the following char of
  1998. * non-Japanese char is Japanese.
  1999. */
  2000. for( ptr = pch+1 ; *ptr == NULL ; ptr++ );
  2001. if( IsDBCSLeadByte(*ptr) || FKana(*ptr) )
  2002. {
  2003. if( vfli.ichFirstWide == 0 )
  2004. {
  2005. int *pdxpT = pdxp;
  2006. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  2007. }
  2008. *pdxp += cxpQuotient;
  2009. if( --iWidenChar == 0 ) return;
  2010. if( --cNonWideSpaces == 0 ) cxpQuotient++;
  2011. }
  2012. }
  2013. } //else : ==chSpace || FKana()
  2014. } //Word Wrap On
  2015. }
  2016. pch++;
  2017. pdxp++;
  2018. }//for
  2019. #else // not JAPAN
  2020. register CHAR *pch = &vfli.rgch[vfli.ichReal];
  2021. register int *pdxp = &vfli.rgdxp[vfli.ichReal];
  2022. int dxpT = dxp;
  2023. int cBreak = pifi->cBreak;
  2024. int cxpQuotient = (dxpT / cBreak) + 1;
  2025. int cWideSpaces = dxpT % cBreak;
  2026. vfli.fAdjSpace = fTrue;
  2027. for ( ; ; )
  2028. {
  2029. /* Widen blanks */
  2030. --pch;
  2031. --pdxp;
  2032. #if defined(KOREA)
  2033. if ((*pch == chSpace) || FKanjiSpace(*pch, *(pch-1)))
  2034. {
  2035. if (FKanjiSpace(*pch, *(pch-1)))
  2036. --pch;
  2037. #else
  2038. if (*pch == chSpace)
  2039. {
  2040. #endif
  2041. if (cWideSpaces-- == 0)
  2042. {
  2043. int *pdxpT = pdxp + 1;
  2044. while (*pdxpT == 0)
  2045. {
  2046. pdxpT++;
  2047. }
  2048. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  2049. cxpQuotient--;
  2050. }
  2051. *pdxp += cxpQuotient;
  2052. if ((dxpT -= cxpQuotient) <= 0)
  2053. {
  2054. if (pifi->cBreak > 1)
  2055. {
  2056. int *pdxpT = pdxp + 1;
  2057. while (*pdxpT == 0)
  2058. {
  2059. pdxpT++;
  2060. }
  2061. vfli.ichFirstWide = pdxpT - vfli.rgdxp;
  2062. }
  2063. return;
  2064. }
  2065. pifi->cBreak--;
  2066. }
  2067. }
  2068. #endif // JAPAN
  2069. }
  2070. } /* Switch */
  2071. if (dxp <= 0)
  2072. {
  2073. /* Nothing to do */
  2074. return;
  2075. }
  2076. pifi->xp += dxp;
  2077. if (flm & flmPrinting)
  2078. {
  2079. pifi->xpPr += dxp;
  2080. }
  2081. else
  2082. {
  2083. /* This statememt might introduce rounding errors in pifi->xpPr, but
  2084. with luck, they will be small. */
  2085. pifi->xpPr += MultDiv(MultDiv(dxp, czaInch, dxpLogInch), dxpPrPage,
  2086. dxaPrPage);
  2087. }
  2088. if (pifi->ichLeft < 0)
  2089. {
  2090. /* Normal justification */
  2091. vfli.xpLeft += dxp;
  2092. }
  2093. else
  2094. {
  2095. /* Tab justification */
  2096. vfli.rgdxp[pifi->ichLeft] += dxp;
  2097. }
  2098. vfli.xpReal += dxp;
  2099. }
  2100. /* F G R O W F O R M A T H E A P */
  2101. int near FGrowFormatHeap()
  2102. {
  2103. /* Grow vhgchpFormat by 20% */
  2104. int cchpIncr = ichpMacFormat / 5 + 1;
  2105. #ifdef WINHEAP
  2106. if (!LocalReAlloc((HANDLE)vhgchpFormat, (ichpMacFormat + cchpIncr) * cchCHP,
  2107. NONZEROLHND))
  2108. #else /* not WINHEAP */
  2109. if (!FChngSizeH(vhgchpFormat, (ichpMacFormat + cchpIncr) * cwCHP, false))
  2110. #endif /* not WINHEAP */
  2111. {
  2112. /* Sorry, charlie */
  2113. return false;
  2114. }
  2115. ichpMacFormat += cchpIncr;
  2116. return true;
  2117. }
  2118. /* #define DBEMG */
  2119. /* D X P F R O M C H */
  2120. #ifdef DBCS
  2121. /* DxpFromCh() assumes that ch passed is the first byte of a DBCS character
  2122. if it is a part of such character. */
  2123. #endif
  2124. int DxpFromCh(ch, fPrinter)
  2125. int ch;
  2126. int fPrinter;
  2127. {
  2128. int *pdxp; // changed to int (7.23.91) v-dougk
  2129. int dxpDummy; // changed to int (7.23.91) v-dougk
  2130. extern int dxpLogCh;
  2131. extern struct FCE *vpfceScreen;
  2132. /* If the width is not in the width table, then get it. */
  2133. if (ch < chFmiMin)
  2134. {
  2135. switch (ch)
  2136. {
  2137. case chTab:
  2138. case chEol:
  2139. case chReturn:
  2140. case chSect:
  2141. case chNewLine:
  2142. case chNRHFile:
  2143. /* the width for these characters aren't really important */
  2144. pdxp = (CHAR *)(fPrinter ? &vfmiPrint.dxpSpace : &vfmiScreen.dxpSpace);
  2145. break;
  2146. default:
  2147. pdxp = &dxpDummy;
  2148. *pdxp = dxpNil;
  2149. break;
  2150. }
  2151. }
  2152. else if (ch >= chFmiMax)
  2153. {
  2154. /* outside the range we hold in our table - kludge it */
  2155. pdxp = &dxpDummy;
  2156. *pdxp = dxpNil;
  2157. }
  2158. else
  2159. {
  2160. /* inside our table */
  2161. pdxp = (fPrinter ? vfmiPrint.mpchdxp : vfmiScreen.mpchdxp) + ch;
  2162. }
  2163. #ifdef DBCS
  2164. #ifdef KOREA
  2165. if (*pdxp == dxpNil && IsDBCSLeadByte(HIBYTE(ch)) )
  2166. #else
  2167. if (*pdxp == dxpNil && IsDBCSLeadByte(ch) )
  2168. #endif
  2169. {
  2170. int dxp;
  2171. #else
  2172. if (*pdxp == dxpNil)
  2173. {
  2174. int dxp;
  2175. #endif
  2176. #ifdef DBCS
  2177. struct FMI *pfmi;
  2178. #if 0 /*T-HIROYN*/
  2179. int rgchT[cchDBCS]; // changed to int (7.23.91) v-dougk
  2180. #endif
  2181. CHAR rgchT[cchDBCS]; // changed to int (7.23.91) v-dougk
  2182. int dxpT;
  2183. int dxpDBCS;
  2184. pfmi = fPrinter ? (&vfmiPrint) : (&vfmiScreen);
  2185. Assert(pfmi->bDummy == dxpNil);
  2186. if (pfmi->dxpDBCS == dxpNil)
  2187. {
  2188. #ifdef KOREA /* 90.12.26 For variable width by sangl */
  2189. rgchT[0] = HIBYTE(ch);
  2190. rgchT[1] = LOBYTE(ch);
  2191. #else
  2192. /* Get the width from GDI. */
  2193. rgchT[0] = rgchT[1] = ch;
  2194. #endif
  2195. dxpDBCS = (fPrinter ?
  2196. LOWORD(GetTextExtent(vhDCPrinter,
  2197. (LPSTR) rgchT, cchDBCS)) :
  2198. LOWORD(GetTextExtent(vhMDC,
  2199. (LPSTR) rgchT, cchDBCS)));
  2200. #ifndef TEMP_KOREA /* For variable width by sangl 90.12.26 */
  2201. /* Store in fmi, if it fits. */
  2202. if (0 <= dxpDBCS && dxpDBCS < dxpNil)
  2203. #if defined(JAPAN) || defined(KOREA) || defined(TAIWAN) || defined(PRC) //Win3.1 BYTE-->WORD
  2204. pfmi->dxpDBCS = (WORD) dxpDBCS;
  2205. #else
  2206. pfmi->dxpDBCS = (BYTE) dxpDBCS;
  2207. #endif
  2208. #endif
  2209. return (dxpDBCS - pfmi->dxpOverhang);
  2210. }
  2211. else
  2212. return (pfmi->dxpDBCS - pfmi->dxpOverhang);
  2213. }
  2214. #if defined(KOREA)
  2215. else if (*pdxp == dxpNil) {
  2216. #else
  2217. else {
  2218. #endif
  2219. int dxp;
  2220. #endif /* DBCS */
  2221. /* get width from GDI */
  2222. dxp = fPrinter ? LOWORD(GetTextExtent(vhDCPrinter, (LPSTR)&ch, 1)) -
  2223. vfmiPrint.dxpOverhang : LOWORD(GetTextExtent(vhMDC, (LPSTR)&ch, 1)) -
  2224. vfmiScreen.dxpOverhang;
  2225. #ifdef DBEMG
  2226. CommSzNum("Get this.... ", dxp);
  2227. #endif
  2228. //(7.24.91) v-dougk if (dxp >= 0 && dxp < dxpNil)
  2229. {
  2230. /* only store dxp's that fit in a byte */
  2231. *pdxp = dxp;
  2232. }
  2233. #ifdef DBEMG
  2234. {
  2235. char szT[10];
  2236. CommSzSz("fPrinter: ", (fPrinter ? "Printer" : "Screen"));
  2237. if (ch == 0x0D) {
  2238. szT[0] = 'C'; szT[1] = 'R'; szT[2] = '\0';
  2239. }
  2240. else if (ch == 0x0A) {
  2241. szT[0] = 'L'; szT[1] = 'F'; szT[2] = '\0';
  2242. }
  2243. else if (32 <= ch && ch <= 126) {
  2244. szT[0] = ch; szT[1] ='\0';
  2245. }
  2246. else if (FKanji1(ch)) {
  2247. szT[0] = 'K'; szT[1] = 'A'; szT[2] = 'N'; szT[3] = 'J';
  2248. szT[4] = 'I'; szT[5] = '\0';
  2249. }
  2250. else {
  2251. szT[0] = szT[1] = szT[2] = '-'; szT[3] = '\0';
  2252. }
  2253. CommSzSz("Character: ", szT);
  2254. CommSzNum("Dxp: ", (int) dxp);
  2255. CommSzNum("OverHang: ", (int) (fPrinter ? vfmiPrint.dxpOverhang : vfmiScreen.dxpOverhang));
  2256. }
  2257. #endif
  2258. return(dxp);
  2259. }
  2260. #ifdef DBEMG
  2261. {
  2262. char szT[10];
  2263. CommSzSz("fPrinter: ", (fPrinter ? "Printer" : "Screen"));
  2264. if (ch == 0x0D) {
  2265. szT[0] = 'C'; szT[1] = 'R'; szT[2] = '\0';
  2266. }
  2267. else if (ch == 0x0A) {
  2268. szT[0] = 'L'; szT[1] = 'F'; szT[2] = '\0';
  2269. }
  2270. else if (32 <= ch && ch <= 126) {
  2271. szT[0] = ch; szT[1] ='\0';
  2272. }
  2273. else if (FKanji1(ch)) {
  2274. szT[0] = 'K'; szT[1] = 'A'; szT[2] = 'N'; szT[3] = 'J';
  2275. szT[4] = 'I'; szT[5] = '\0';
  2276. }
  2277. else {
  2278. szT[0] = szT[1] = szT[2] = '-'; szT[3] = '\0';
  2279. }
  2280. CommSzSz("Character: ", szT);
  2281. CommSzNum("Dxp: ", (int) *pdxp);
  2282. CommSzNum("OverHang: ", (int) (fPrinter ? vfmiPrint.dxpOverhang : vfmiScreen.dxpOverhang));
  2283. }
  2284. #endif
  2285. return(*pdxp);
  2286. }
  2287. #ifdef DBCS
  2288. //
  2289. // DxpFromCh for DBCS
  2290. // yutakan, 03 Oct 1991
  2291. int DBCSDxpFromCh(ch, ch2, fPrinter)
  2292. int ch;
  2293. int ch2;
  2294. int fPrinter;
  2295. {
  2296. /* T-HIROYN sync us 3.1*/
  2297. int *pdxp; // changed to int (7.23.91) v-dougk
  2298. int dxpDummy; // changed to int (7.23.91) v-dougk
  2299. extern int dxpLogCh;
  2300. extern struct FCE *vpfceScreen;
  2301. /* If the width is not in the width table, then get it. */
  2302. if (ch < chFmiMin)
  2303. {
  2304. switch (ch)
  2305. {
  2306. case chTab:
  2307. case chEol:
  2308. case chReturn:
  2309. case chSect:
  2310. case chNewLine:
  2311. case chNRHFile:
  2312. /* the width for these characters aren't really important */
  2313. pdxp = (CHAR *)(fPrinter ? &vfmiPrint.dxpSpace : &vfmiScreen.dxpSpace);
  2314. break;
  2315. default:
  2316. pdxp = &dxpDummy;
  2317. *pdxp = dxpNil;
  2318. break;
  2319. }
  2320. }
  2321. else if (ch >= chFmiMax)
  2322. {
  2323. /* outside the range we hold in our table - kludge it */
  2324. pdxp = &dxpDummy;
  2325. *pdxp = dxpNil;
  2326. }
  2327. else
  2328. {
  2329. /* inside our table */
  2330. pdxp = (fPrinter ? vfmiPrint.mpchdxp : vfmiScreen.mpchdxp) + ch;
  2331. }
  2332. if (*pdxp == dxpNil )
  2333. {
  2334. int dxp;
  2335. #if defined(TAIWAN) || defined(PRC) //solve BkSp single byte (>0x80) infinite loop problem, MSTC - pisuih, 2/25/93
  2336. // BUG 5477: Echen: add NON FA font, LeadByte + 2nd byte checking
  2337. if( ch2 != 0 && IsDBCSLeadByte(ch) && GetFontAssocStatus(vhMDC))
  2338. #else
  2339. if( IsDBCSLeadByte(ch) )
  2340. #endif //TAIWAN
  2341. {
  2342. struct FMI *pfmi;
  2343. #if defined(TAIWAN) || defined(KOREA) || defined(PRC) //for Bug# 3362, MSTC - pisuih, 2/10/93
  2344. CHAR rgchT[cchDBCS << 1];
  2345. int dxpOverhang;
  2346. #else
  2347. CHAR rgchT[cchDBCS];
  2348. #endif //TAIWAN
  2349. int dxpT;
  2350. int dxpDBCS;
  2351. pfmi = fPrinter ? (&vfmiPrint) : (&vfmiScreen);
  2352. Assert(pfmi->bDummy == dxpNil);
  2353. #if defined(TAIWAN) || defined(KOREA) || defined(PRC) //fix Italic position error while SBCS's overhang != DBCS's overhang
  2354. //for Bug# 3362, MSTC - pisuih, 3/4/93
  2355. //fix Go To page too slow, pisuih, 3/4/93
  2356. if ( (!pfmi->dxpDBCS) || (pfmi->dxpDBCS == dxpNil) )
  2357. {
  2358. rgchT[0] = rgchT[2] = ch;
  2359. rgchT[1] = rgchT[3] = ch2;
  2360. dxpDBCS = LOWORD(GetTextExtent( (fPrinter ? vhDCPrinter : vhMDC),
  2361. (LPSTR) rgchT, cchDBCS ));
  2362. dxpOverhang = (dxpDBCS << 1) - LOWORD( GetTextExtent(
  2363. (fPrinter ? vhDCPrinter : vhMDC), (LPSTR) rgchT, cchDBCS << 1 ));
  2364. //for compatible with SBCS's overhang
  2365. dxpDBCS += (pfmi->dxpOverhang - dxpOverhang);
  2366. /* Store in fmi, if it fits. */
  2367. if (0 <= dxpDBCS && dxpDBCS < dxpNil)
  2368. pfmi->dxpDBCS = (WORD) dxpDBCS;
  2369. return (dxpDBCS - pfmi->dxpOverhang);
  2370. }
  2371. else
  2372. return (pfmi->dxpDBCS - pfmi->dxpOverhang);
  2373. #else
  2374. if(pfmi->dxpDBCS == dxpNil)
  2375. {
  2376. /* Get the width from GDI. */
  2377. rgchT[0] = ch;
  2378. rgchT[1] = ch2;
  2379. dxpDBCS = (fPrinter ?
  2380. LOWORD(GetTextExtent(vhDCPrinter,
  2381. (LPSTR) rgchT, cchDBCS)) :
  2382. LOWORD(GetTextExtent(vhMDC,
  2383. (LPSTR) rgchT, cchDBCS)));
  2384. /* Store in fmi, if it fits. */
  2385. if (0 <= dxpDBCS && dxpDBCS < dxpNil)
  2386. #if defined(JAPAN) || defined(KOREA) //Win3.1 BYTE-->WORD
  2387. pfmi->dxpDBCS = (WORD) dxpDBCS;
  2388. #else
  2389. pfmi->dxpDBCS = (BYTE) dxpDBCS;
  2390. #endif
  2391. return (dxpDBCS - pfmi->dxpOverhang);
  2392. }
  2393. else
  2394. return (pfmi->dxpDBCS - pfmi->dxpOverhang);
  2395. #endif //TAIWAN
  2396. }
  2397. else
  2398. {
  2399. /* get width from GDI */
  2400. dxp = fPrinter ? LOWORD(GetTextExtent(vhDCPrinter, (LPSTR)&ch, 1)) -
  2401. vfmiPrint.dxpOverhang : LOWORD(GetTextExtent(vhMDC, (LPSTR)&ch, 1)) -
  2402. vfmiScreen.dxpOverhang;
  2403. }
  2404. /*T-HIROYN sync us 3.1*/
  2405. //(7.24.91) v-dougk if (dxp >= 0 && dxp < dxpNil)
  2406. {
  2407. /* only store dxp's that fit in a byte */
  2408. *pdxp = dxp;
  2409. }
  2410. return(dxp);
  2411. }
  2412. return(*pdxp);
  2413. }
  2414. #endif
  2415. /* F F I R S T I C H */
  2416. int near FFirstIch(ich)
  2417. int ich;
  2418. {
  2419. /* Returns true iff ich is 0 or preceded only by 0 width characters */
  2420. register int ichT;
  2421. register int *pdxp = &vfli.rgdxp[0];
  2422. for (ichT = 0; ichT < ich; ichT++)
  2423. {
  2424. if (*pdxp++)
  2425. {
  2426. return false;
  2427. }
  2428. }
  2429. return true;
  2430. }
  2431. ValidateMemoryDC()
  2432. {
  2433. /* Attempt to assure that vhMDC and vhDCPrinter are valid. If we have not
  2434. already run out of memory, then vhDCPrinter is guaranteed, but vhMDC may
  2435. fail due to out of memory -- it is the callers responsibility to check for
  2436. vhMDC == NULL. */
  2437. extern int vfOutOfMemory;
  2438. extern HDC vhMDC;
  2439. extern BOOL vfMonochrome;
  2440. extern long rgbText;
  2441. extern struct WWD *pwwdCur;
  2442. /* If we are out of memory, then we shouldn't try to gobble it up by getting
  2443. DC's. */
  2444. if (!vfOutOfMemory)
  2445. {
  2446. if (vhMDC == NULL)
  2447. {
  2448. /* Create a memory DC compatible with the screen if necessary. */
  2449. vhMDC = CreateCompatibleDC(pwwdCur->hDC);
  2450. /* Callers are responsible for checking for vhMDC == NULL case */
  2451. if (vhMDC != NULL)
  2452. {
  2453. /* Put the memory DC in transparent mode. */
  2454. SetBkMode(vhMDC, TRANSPARENT);
  2455. /* If the display is a monochrome device, then set the text
  2456. color for the memory DC. Monochrome bitmaps will not be
  2457. converted to the foreground and background colors in this case,
  2458. we must do the conversion. */
  2459. if (vfMonochrome = (GetDeviceCaps(pwwdCur->hDC, NUMCOLORS) ==
  2460. 2))
  2461. {
  2462. SetTextColor(vhMDC, rgbText);
  2463. }
  2464. }
  2465. }
  2466. /* If the printer DC is NULL then we need to reestablish it. */
  2467. if (vhDCPrinter == NULL)
  2468. {
  2469. GetPrinterDC(FALSE);
  2470. /* GetPrinterDC has already called SetMapperFlags() on vhDCPrinter. */
  2471. }
  2472. }
  2473. }
  2474. #ifdef DBCS
  2475. /* The following two functions are used to determine if a given kanji
  2476. (two byte) character (or 1 byte kana letters) should be admitted
  2477. to the current line without causing the line break though it is
  2478. passed the right margin.
  2479. The table below shows which letters are admitted as a hanging character
  2480. on a line. The table below should be updated in sync with the code
  2481. itself.
  2482. Kanji (2-byte) characters
  2483. letter first byte second byte half width
  2484. hiragana small a 82 9F
  2485. i 82 A1
  2486. u 82 A3
  2487. e 82 A5
  2488. o 82 A7
  2489. tsu 82 C1
  2490. ya 82 E1
  2491. yu 82 E3
  2492. yo 82 E5
  2493. katakana small a 83 40 85 A5
  2494. i 83 42 85 A6
  2495. u 83 44 85 A7
  2496. e 83 46 85 A8
  2497. o 83 48 85 A9
  2498. tsu 83 62 85 AD
  2499. ya 83 83 85 AA
  2500. yu 83 85 85 AB
  2501. yo 83 87 85 AC
  2502. wa 83 8E
  2503. ka 83 95
  2504. ke 83 96
  2505. blank 81 40
  2506. horizontal bar (long) 81 5B 85 AE
  2507. (med) 81 5C
  2508. (short) 81 5D
  2509. touten
  2510. (Japanese comma) 81 41 85 A2
  2511. kuten
  2512. (Japanese period) 81 42 85 9F
  2513. handakuten 81 4B 85 DD
  2514. dakuten 81 4A 85 DC
  2515. kagikakko
  2516. (closing Japanese parenthesis)
  2517. 81 76 85 A1
  2518. " (2-byte) 81 68 85 41
  2519. ' (2-byte) 81 66 85 46
  2520. } (2-byte) 81 70 85 9D
  2521. ] (2-byte) 81 6E 85 7C
  2522. ) (2-byte) 81 6A 85 48
  2523. . (at the center) 81 45 85 A3
  2524. ... 81 63
  2525. .. 81 64
  2526. closing angle bracket 81 72
  2527. closing double angled bracket
  2528. 81 74
  2529. closing double kagikakko
  2530. 81 78
  2531. closing inversed ) 81 7A
  2532. closing half angled bracket
  2533. 81 6C
  2534. thinner ' 81 8C
  2535. thinner " 81 8D
  2536. 1-byte kana characters
  2537. letter byte
  2538. katakana small a A7
  2539. i A8
  2540. u A9
  2541. e AA
  2542. o AB
  2543. tsu AF
  2544. ya AC
  2545. yu AD
  2546. yo AE
  2547. touten
  2548. (Japanese comma) A4
  2549. kuten
  2550. (Japanese period) A1
  2551. handakuten DF
  2552. dakuten DE
  2553. kagikakko
  2554. (closing Japanese parenthesis)
  2555. A3
  2556. . (at the center) A5
  2557. The following 1 or 2 byte characters are treated as a hanging character
  2558. if the previous character is a 2-byte kanji character.
  2559. letter byte
  2560. " 22
  2561. ' 27
  2562. } 7D
  2563. ] 5D
  2564. ) 29
  2565. . 2E
  2566. , 2C
  2567. ; 3B
  2568. : 3A
  2569. ? 3F
  2570. ! 21
  2571. byte 1 byte 2
  2572. . 81 44
  2573. , 81 43
  2574. ; 81 47
  2575. : 81 46
  2576. ? 81 48
  2577. ! 81 49
  2578. . 85 4D
  2579. , 85 4B
  2580. ; 85 4A
  2581. : 85 49
  2582. ? 85 5E
  2583. ! 85 40
  2584. */
  2585. BOOL near FSearchChRgch(ch, rgch, ichLim)
  2586. CHAR ch;
  2587. CHAR *rgch;
  2588. int ichLim;
  2589. {
  2590. int ichMin;
  2591. BOOL fFound;
  2592. fFound = FALSE;
  2593. ichMin = 0;
  2594. while (!fFound && ichMin <= ichLim) {
  2595. int ichMid;
  2596. CHAR chMid;
  2597. /* Save on the dereferencing. */
  2598. chMid = rgch[ichMid = (ichMin + ichLim) >> 1];
  2599. if (ch == chMid) {
  2600. fFound = TRUE;
  2601. }
  2602. else if (ch < chMid) {
  2603. ichLim = ichMid - 1;
  2604. }
  2605. else {
  2606. ichMin = ichMid + 1;
  2607. }
  2608. }
  2609. return (fFound);
  2610. }
  2611. /* FAdmitCh1() returns true if and only if the given ch is a one-byte
  2612. kana code for those letters that can appear beyond the right margin. */
  2613. BOOL near FAdmitCh1(ch)
  2614. CHAR ch;
  2615. {
  2616. #ifdef JAPAN
  2617. if(!vfWordWrap) /*WordWrap off t-Yoshio*/
  2618. return FALSE;
  2619. return (
  2620. (ch == 0xA1) ||
  2621. ((0xA3 <= ch) && (ch <= 0xA5)) ||
  2622. ((0xA7 <= ch) && (ch <= 0xAF)) ||
  2623. ((0xDE <= ch) && (ch <= 0xDF))
  2624. );
  2625. #else
  2626. return(FALSE);
  2627. #endif
  2628. }
  2629. /* FOptAdmitCh1() returns true if and only if the given ch is a
  2630. one-byte character that can be admitted to the end of a line
  2631. beyond the right margin, if it appears after a kanji character. */
  2632. BOOL near FOptAdmitCh1(ch)
  2633. CHAR ch;
  2634. {
  2635. static CHAR rgchOptAdmit1[]
  2636. = {0x21, 0x22, 0x27, 0x29, 0x2C, 0x2E, 0x3A, 0x3B,
  2637. 0x3F, 0x5D, 0x7D};
  2638. #if defined(JAPAN) || defined(KOREA)
  2639. if(!vfWordWrap) /*WordWrap off t-Yoshio*/
  2640. return FALSE;
  2641. #endif
  2642. return (FSearchChRgch(ch, rgchOptAdmit1,
  2643. (sizeof(rgchOptAdmit1) / sizeof(CHAR)) - 1));
  2644. }
  2645. /* FAdmitCh2() returns true if and only if the given (ch1, ch2) combination
  2646. represents a kanji (2-byte) letter that can appear beyond the right
  2647. margin. */
  2648. BOOL near FAdmitCh2(ch1, ch2)
  2649. CHAR ch1, ch2;
  2650. {
  2651. int dch=0;
  2652. #if defined(JAPAN) || defined(KOREA)
  2653. if(!vfWordWrap) /*WordWrap off t-Yoshio*/
  2654. return FALSE;
  2655. #endif
  2656. while((dch < MPDCHRGCHIDX_MAC) && (ch1 != mpdchrgchIdx[dch]))
  2657. dch++;
  2658. if (dch < MPDCHRGCHIDX_MAC) {
  2659. return (FSearchChRgch(ch2, mpdchrgch[dch], mpdchichMax[dch] - 1));
  2660. }
  2661. else {
  2662. return (FALSE);
  2663. }
  2664. }
  2665. /* FOptAdmitCh2() returns true if and only if the given (ch1, ch2) is a
  2666. two-byte character combination that can be admitted to the end of a line
  2667. beyond the right margin, provided it appears after a kanji character. */
  2668. BOOL near FOptAdmitCh2(ch1, ch2)
  2669. CHAR ch1, ch2;
  2670. {
  2671. int i=0;
  2672. #if defined(JAPAN) || defined(KOREA)
  2673. if(!vfWordWrap) /*WordWrap off t-Yoshio*/
  2674. return FALSE;
  2675. #endif
  2676. while ((i < OPTADMIT2IDX_MAC) && (ch1 != OptAdmit2Idx[i]))
  2677. i++;
  2678. if (i < OPTADMIT2IDX_MAC){
  2679. return (FSearchChRgch(ch2, mpdchrgchOptAdmit2[i], OptAdmit2ichMax[i]));
  2680. }
  2681. else {
  2682. return (FALSE);
  2683. }
  2684. }
  2685. /* FOptAdmitCh() returns TRUE if and only if the given (ch1, ch2) can
  2686. be a hanging letter at the end of a line. Otherwise, FALSE. If ch1
  2687. is equal to '\0', ch2 is treated as a 1-byte character code. */
  2688. BOOL FOptAdmitCh(ch1, ch2)
  2689. CHAR ch1, ch2;
  2690. {
  2691. #if defined(JAPAN) || defined(KOREA)
  2692. if(!vfWordWrap) /*WordWrap off t-Yoshio*/
  2693. return FALSE;
  2694. #endif
  2695. if (ch1 == '\0') {
  2696. return ((ch2 == chSpace) || FAdmitCh1(ch2) || FOptAdmitCh1(ch2));
  2697. }
  2698. else {
  2699. return (FKanjiSpace(ch1, ch2) || FAdmitCh2(ch1, ch2) ||
  2700. FOptAdmitCh2(ch1, ch2));
  2701. }
  2702. }
  2703. #endif /* ifdef DBCS */