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.

2822 lines
92 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* disp.c -- MW display routines */
  5. #define NOKEYSTATE
  6. #define NOSYSCOMMANDS
  7. #define NOSHOWWINDOW
  8. //#define NOATOM
  9. #define NOCLIPBOARD
  10. #define NOGDICAPMASKS
  11. #define NOCTLMGR
  12. #define NOWINSTYLES
  13. //#define NOVIRTUALKEYCODES
  14. #ifndef DBCS
  15. #define NOSYSMETRICS
  16. #endif
  17. #define NOMENUS
  18. #define NOSOUND
  19. #define NOCOMM
  20. #define NOOPENFILE
  21. #define NOWH
  22. #define NOWINOFFSETS
  23. #define NOMETAFILE
  24. #ifndef DBCS
  25. #define NOMB
  26. #endif
  27. #define NODRAWTEXT
  28. #include <windows.h>
  29. #define NOUAC
  30. #include "mw.h"
  31. #include "debug.h"
  32. #include "cmddefs.h"
  33. #include "dispdefs.h"
  34. #include "wwdefs.h"
  35. #define NOKCCODES /* Removes all kc code defines */
  36. #include "ch.h"
  37. #include "docdefs.h"
  38. #include "fmtdefs.h"
  39. #include "propdefs.h"
  40. #include "macro.h"
  41. #include "printdef.h"
  42. #include "fontdefs.h"
  43. #if defined(OLE)
  44. #include "obj.h"
  45. #endif
  46. #ifdef DBCS
  47. #include "dbcs.h"
  48. #include "kanji.h"
  49. #endif
  50. #ifdef DBCS_IME
  51. #include <ime.h>
  52. #ifdef JAPAN
  53. #include "prmdefs.h" //IME3.1J
  54. BOOL ConvertEnable = FALSE;
  55. BOOL bClearCall = TRUE;
  56. #endif /* JAPAN */
  57. #endif /* DBCS_IME */
  58. #ifdef CASHMERE /* No VisiMode in WinMemo */
  59. extern int vfVisiMode;
  60. #endif /* CASHMERE */
  61. extern int vcchBlted;
  62. extern int vidxpInsertCache;
  63. extern int vdlIns;
  64. extern int vfInsLast;
  65. extern struct PAP vpapAbs;
  66. extern struct SEP vsepAbs;
  67. extern int rgval[];
  68. extern struct DOD (**hpdocdod)[];
  69. extern typeCP cpMacCur;
  70. extern int vfSelHidden;
  71. extern struct WWD rgwwd[];
  72. extern int wwCur, wwMac;
  73. extern struct FLI vfli;
  74. extern struct SEL selCur;
  75. extern struct WWD *pwwdCur;
  76. extern int docCur;
  77. extern struct CHP (**vhgchpFormat)[];
  78. extern int vichpFormat;
  79. extern typeCP cpMinCur;
  80. extern typeCP cpMinDocument;
  81. extern int vfInsertOn;
  82. extern int vfTextBltValid;
  83. extern typeCP vcpFirstParaCache;
  84. extern typeCP vcpLimParaCache;
  85. extern unsigned vpgn;
  86. extern struct SEP vsepAbs;
  87. extern CHAR stBuf[];
  88. extern typeCP CpEdge();
  89. extern typeCP CpMacText();
  90. extern int vdocPageCache;
  91. extern int vfPictSel;
  92. extern int vfAwfulNoise;
  93. extern int vfSkipNextBlink;
  94. extern int dypMax;
  95. extern HDC vhMDC;
  96. extern HWND vhWndPageInfo;
  97. extern struct FMI vfmiScreen;
  98. extern int docScrap;
  99. extern long rgbBkgrnd;
  100. extern long ropErase;
  101. extern BOOL vfMonochrome;
  102. extern int dxpbmMDC;
  103. extern int dypbmMDC;
  104. extern HBITMAP hbmNull;
  105. extern int vfOutOfMemory;
  106. extern int vfSeeSel;
  107. extern int vfInsEnd; /* Is insert point at end-of-line? */
  108. extern int vipgd;
  109. extern typeCP vcpMinPageCache;
  110. extern typeCP vcpMacPageCache;
  111. /* actual position of the cursor line */
  112. extern int vxpCursLine;
  113. extern int vypCursLine;
  114. extern int vdypCursLine;
  115. extern int vfScrollInval; /* means scroll did not take and UpdateWw must be repeated */
  116. extern BOOL vfDead;
  117. extern HRGN vhrgnClip;
  118. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  119. extern typeCP selUncpFirst;
  120. extern typeCP selUncpLim;
  121. extern HANDLE hImeUnAttrib;
  122. extern int vfImeHidden;
  123. int HiddenTextTop = 0;
  124. int HiddenTextBottom = 0;
  125. //if TRUE we are managing IR_UNDETERMINE
  126. BOOL whileUndetermine = FALSE; //12/28/92
  127. LPSTR Attrib;
  128. WORD AttribPos = 0;
  129. #define IMEDEFCOLORS 6 // IME Define colors
  130. #define IMESPOT 0 // IME Spot background color
  131. #define IMESPOTTEXT 1 // IME Spot text color
  132. #define IMEINPUT 2 // IME Input background color
  133. #define IMEINPUTTEXT 3 // IME Input text color
  134. #define IMEOTHER 4 // IME Other background color
  135. #define IMEOTHERTEXT 5 // IME Other text color
  136. COLORREF rgbIMEHidden[IMEDEFCOLORS] = {0L,0L,0L,0L,0L,0L};
  137. #endif
  138. /* G L O B A L S
  139. int dlsMac = 0;*/
  140. #ifdef DBCS
  141. int donteat = 0; /* propagate not to eat message */
  142. #endif
  143. #if defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  144. #define FKana(_ch) FALSE
  145. #endif
  146. /* D I S P L A Y F L I */
  147. /* Display formatted line in window ww at line dl */
  148. DisplayFli(ww, dl, fDontDisplay)
  149. int ww;
  150. int dl;
  151. int fDontDisplay; /* True if we set up dl info but don't display */
  152. {
  153. typeCP dcp;
  154. typeCP dcpMac;
  155. struct WWD *pwwd = &rgwwd[ww];
  156. HDC hDC = pwwd->hDC;
  157. int xp; /* Current xp to write text */
  158. int yp; /* Current yp to write text */
  159. int xpMin = pwwd->xpMin; /* Minimum xp in window */
  160. int xpMac = pwwd->xpMac; /* Maximum xp in window */
  161. int ypLine; /* Screen yp for current line */
  162. int dxp; /* Width of current run */
  163. int dyp; /* Line height */
  164. int dxpExtra; /* Width of pad for each space */
  165. typeCP cpMin;
  166. typeCP cpMac;
  167. int xpSel; /* xp of the start of the selection */
  168. int dxpSel = 0; /* Width of the selection. */
  169. CHAR chMark = '\0'; /* style character */
  170. struct CHP *pchp;
  171. BOOL fTabsKludge = (vfli.ichLastTab >= 0);
  172. BOOL fInsertOn = FALSE;
  173. int cBreakRun; /* break characters in run (no relation to Dick or Jane) */
  174. #ifdef SMFONT
  175. RECT rcOpaque;
  176. #endif /* SMFONT */
  177. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  178. extern int vfWordWrap; /* WordWrap flag : TRUE=ON, FALSE=OFF */
  179. extern int iNonWideSpaces;
  180. int iRun;
  181. typeCP RealcpFirst;
  182. #elif defined(TAIWAN) || defined(PRC)
  183. extern int vfWordWrap; /* WordWrap flag : TRUE=ON, FALSE=OFF */
  184. extern int iNonWideSpaces;
  185. int iRun;
  186. typeCP RealcpFirst;
  187. #endif
  188. #ifdef DDISP
  189. CommSzNumNum(" DisplayFli: dl/fDontDisplay ", dl, fDontDisplay);
  190. #endif
  191. Assert(ww >= 0 && ww < wwMax);
  192. #ifdef SMFONT
  193. Assert(!fDontDisplay || vfli.fGraphics)
  194. #endif /* SMFONT */
  195. Scribble(5,'D');
  196. /* Fill up EDL and set some useful locals */
  197. {
  198. register struct EDL *pedl = &(**pwwd->hdndl)[dl];
  199. if (dl == vdlIns)
  200. {
  201. /* Overwriting chars blted during fast insert; reset blt count */
  202. vcchBlted = 0;
  203. vidxpInsertCache = -1;
  204. }
  205. pedl->xpLeft = vfli.xpLeft;
  206. pedl->xpMac = vfli.xpReal;
  207. cpMin = pedl->cpMin = vfli.cpMin;
  208. #ifdef JAPAN
  209. RealcpFirst = cpMin;
  210. #endif
  211. pedl->dcpMac = (cpMac = vfli.cpMac) - cpMin;
  212. dyp = pedl->dyp = vfli.dypLine;
  213. pedl->ichCpMin = vfli.ichCpMin;
  214. pedl->dcpDepend = (cpMin == cpMac) ? 0xff : vfli.dcpDepend;
  215. pedl->fValid = TRUE;
  216. pedl->fGraphics = vfli.fGraphics;
  217. pedl->fSplat = vfli.fSplat;
  218. /* The position of current line equals the position of the previous line
  219. + height of this line. */
  220. #ifdef SMFONT
  221. pedl->yp = rcOpaque.bottom = dyp + (ypLine = rcOpaque.top = (dl == 0 ?
  222. pwwd->ypMin : (pedl - 1)->yp));
  223. #else /* not SMFONT */
  224. pedl->yp = dyp + (ypLine = (dl == 0 ? pwwd->ypMin :
  225. (pedl - 1)->yp));
  226. #endif /* SMFONT */
  227. if (pedl->fIchCpIncr = (vfli.ichCpMac != 0))
  228. {
  229. /* Look at final text column */
  230. ++cpMac;
  231. /* Since this is true, we can compress pedl->ichCpMac to 1 bit. */
  232. Assert(vfli.ichCpMac == pedl->ichCpMin + 1);
  233. }
  234. }
  235. if (vfli.doc == docNil)
  236. {
  237. /* This is the space beyond the end mark. */
  238. PatBlt(hDC, 0, ypLine, xpMac, dyp, ropErase);
  239. goto Finished;
  240. }
  241. /* Is there a character in the "style bar"? */
  242. if (cpMin != cpMac)
  243. {
  244. #ifdef CASHMERE
  245. /* This line is not completely empty (not after the end mark); check for
  246. painting marks on the style bar. */
  247. if (cpMin == vcpFirstParaCache && vpapAbs.rhc != 0)
  248. {
  249. /* This is a running-head. */
  250. chMark = chStatRH;
  251. }
  252. else if ((**hpdocdod)[vfli.doc].hpgtb != 0)
  253. #else /* not CASHMERE */
  254. if (vpapAbs.rhc == 0 && (**hpdocdod)[vfli.doc].hpgtb != 0)
  255. #endif /* CASHMERE */
  256. {
  257. if (vdocPageCache != vfli.doc || cpMac > vcpMacPageCache || cpMac <=
  258. vcpMinPageCache)
  259. {
  260. CachePage(vfli.doc, cpMac - 1);
  261. }
  262. /* We are now guaranteed that cpMac is within the cached page. */
  263. if (cpMin <= vcpMinPageCache && (!vfli.fGraphics || vfli.ichCpMin ==
  264. 0))
  265. {
  266. /* This is the first line of new page; show page mark. */
  267. chMark = chStatPage;
  268. }
  269. }
  270. }
  271. #ifdef SMFONT
  272. #ifdef DDISP
  273. /* black out this line to test how efficiently/correctly we
  274. overwrite pixels from previously-resident lines of text */
  275. PatBlt(hDC, 0, ypLine, xpMac, dyp, BLACKNESS);
  276. { long int i; for (i=0; i < 500000; i++) ; }
  277. #endif
  278. /* Calculate dcpMac now, so we might be able to know how much to erase. */
  279. dcpMac = vfli.fSplat ? vfli.ichMac : vfli.ichReal;
  280. /* Erase any character that might be in the style bar. */
  281. dxp = xpSelBar + 1;
  282. if (!vfli.fGraphics)
  283. {
  284. dxp = xpMac; // clear the whole line
  285. }
  286. PatBlt(hDC, 0, ypLine, dxp, dyp, ropErase);
  287. /* If this is graphics then go draw any characters in the style bar. */
  288. if (vfli.fGraphics)
  289. {
  290. goto DrawMark;
  291. }
  292. /* If there are no "real" characters on this line then we can skip alot of
  293. this. */
  294. if (dcpMac == 0)
  295. {
  296. goto EndLine2;
  297. }
  298. #else /* not SMFONT */
  299. if (vfli.fGraphics || fDontDisplay)
  300. {
  301. /* Erase any character that might be in the style bar. */
  302. PatBlt(hDC, 0, ypLine, xpSelBar, dyp, ropErase);
  303. goto DrawMark;
  304. }
  305. #endif /* SMFONT */
  306. ValidateMemoryDC();
  307. if (vhMDC == NULL)
  308. {
  309. Error:
  310. /* Notify the user that an error has occured and simply erase this line.
  311. */
  312. WinFailure();
  313. PatBlt(hDC, xpSelBar, ypLine, xpMac - xpSelBar, dyp, ropErase);
  314. goto Finished;
  315. }
  316. #ifndef SMFONT
  317. /* Create a new bitmap for the memory DC if the current bitmap is not big
  318. enough. */
  319. if (xpMac > dxpbmMDC || dyp > dypbmMDC)
  320. {
  321. HBITMAP hbm;
  322. /* If there is an old bitmap, then delete it. */
  323. if (dxpbmMDC != 0 || dypbmMDC != 0)
  324. {
  325. DeleteObject(SelectObject(vhMDC, hbmNull));
  326. }
  327. /* Create the new bitmap and select it in. */
  328. if ((hbm = CreateBitmap(dxpbmMDC = xpMac, dypbmMDC = dyp, 1, 1,
  329. (LPSTR)NULL)) == NULL)
  330. {
  331. /* There should be a graceful way to recover if the bitmap is ever
  332. NULL (e.g we don't have enough memory for it). */
  333. dxpbmMDC = dypbmMDC = 0;
  334. goto Error;
  335. }
  336. SelectObject(vhMDC, hbm);
  337. }
  338. /* Erase the are of the bitmap we are going to use. */
  339. PatBlt(vhMDC, xpSelBar, 0, xpMac, dyp, vfMonochrome ? ropErase : WHITENESS);
  340. #endif /* not SMFONT */
  341. /* Initialize some of the variables we'll need. */
  342. pchp = &(**vhgchpFormat)[0];
  343. #ifdef SMFONT
  344. xp = rcOpaque.left = rcOpaque.right = vfli.xpLeft + xpSelBar - xpMin + 1;
  345. #else /* not SMFONT */
  346. dcpMac = vfli.fSplat ? vfli.ichMac : vfli.ichReal;
  347. xp = vfli.xpLeft + xpSelBar - xpMin + 1;
  348. #endif /* SMFONT */
  349. dxpExtra = fTabsKludge ? 0 : vfli.dxpExtra;
  350. #ifdef SMFONT
  351. /* If we are horizontally scrolled, then set the clip area to the area
  352. outside of the selection bar. */
  353. if (xpMin != 0)
  354. {
  355. IntersectClipRect(hDC, xpSelBar, rcOpaque.top, xpMac, rcOpaque.bottom);
  356. }
  357. #endif /* SMFONT */
  358. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  359. iRun = 0;
  360. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  361. iRun = 0;
  362. #endif
  363. for (dcp = 0; dcp < dcpMac; pchp++)
  364. {
  365. /* For all runs do: */
  366. int ichFirst; /* First character in the current run */
  367. int cchRun; /* Number of characters in the current run */
  368. dcp = ichFirst = pchp->ichRun;
  369. dcp += pchp->cchRun;
  370. if (dcp > dcpMac)
  371. {
  372. dcp = dcpMac;
  373. }
  374. cchRun = dcp - ichFirst;
  375. /* Compute dxp = sum of width of characters in current run (formerly
  376. DxaFromIcpDcp). */
  377. {
  378. register int *pdxp;
  379. register int cchT = cchRun;
  380. PCH pch = vfli.rgch + ichFirst;
  381. dxp = cBreakRun = 0;
  382. pdxp = &vfli.rgdxp[ichFirst];
  383. while (cchT-- > 0)
  384. {
  385. dxp += *pdxp++;
  386. if (*pch++ == chSpace)
  387. ++cBreakRun;
  388. }
  389. #ifdef DDISP
  390. CommSzNum(" dxp=",dxp);
  391. #endif
  392. }
  393. if (dxp > 0)
  394. {
  395. int cchDone;
  396. PCH pch = &vfli.rgch[ichFirst];
  397. #ifdef JAPAN // added 08 Jul. 1992 by Hiraisi
  398. int *pdxpT = &vfli.rgdxp[ichFirst];
  399. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  400. int *pdxpT = &vfli.rgdxp[ichFirst];
  401. #endif
  402. LoadFont(vfli.doc, pchp, mdFontScreen);
  403. yp = (dyp - (vfli.dypBase + (pchp->hpsPos != 0 ? (pchp->hpsPos <
  404. hpsNegMin ? ypSubSuper : -ypSubSuper) : 0))) -
  405. vfmiScreen.dypBaseline;
  406. /* Note: tabs and other special characters are guaranteed to come at
  407. the start of a run. */
  408. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  409. if( vpapAbs.jc != jcBoth || fTabsKludge )
  410. SetTextJustification(vhMDC, dxpExtra * cBreakRun, cBreakRun);
  411. #elif defined(TAIWAN) || defined(PRC) // Daniel/MSTC, 1993/02/25, for jcBoth
  412. if( vpapAbs.jc != jcBoth)
  413. SetTextJustification(vhMDC, dxpExtra * cBreakRun, cBreakRun);
  414. #else
  415. SetTextJustification(vhMDC, dxpExtra * cBreakRun, cBreakRun);
  416. #endif /* JAPAN */
  417. #ifdef SMFONT
  418. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  419. if( vpapAbs.jc != jcBoth || fTabsKludge )
  420. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  421. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  422. if( vpapAbs.jc != jcBoth)
  423. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  424. #else
  425. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  426. #endif /* JAPAN */
  427. #endif /* SMFONT */
  428. cchDone = 0;
  429. while (cchDone < cchRun)
  430. {
  431. int cch;
  432. /* Does the wide-space zone begin in this run? */
  433. if (vfli.fAdjSpace && (vfli.ichFirstWide < ichFirst + cchRun) &&
  434. (ichFirst + cchDone <= vfli.ichFirstWide))
  435. {
  436. int cchDoneT = cchDone;
  437. /* Is this the beginning of the wide-space zone? */
  438. if (ichFirst + cchDone == vfli.ichFirstWide)
  439. {
  440. /* Reset the width of the spaces. */
  441. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  442. if( vpapAbs.jc != jcBoth || fTabsKludge )
  443. SetTextJustification(vhMDC, ++dxpExtra * cBreakRun,
  444. cBreakRun);
  445. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  446. if( vpapAbs.jc != jcBoth || fTabsKludge )
  447. SetTextJustification(vhMDC, ++dxpExtra * cBreakRun,
  448. cBreakRun);
  449. #else
  450. SetTextJustification(vhMDC, ++dxpExtra * cBreakRun, cBreakRun);
  451. #endif /* JAPAN */
  452. #ifdef SMFONT
  453. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  454. if( vpapAbs.jc != jcBoth || fTabsKludge )
  455. SetTextJustification(hDC, dxpExtra * cBreakRun,
  456. cBreakRun);
  457. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  458. if( vpapAbs.jc != jcBoth)
  459. SetTextJustification(hDC, dxpExtra * cBreakRun,
  460. cBreakRun);
  461. #else
  462. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  463. #endif /* JAPAN */
  464. #endif /* SMFONT */
  465. cch = cchRun - cchDone;
  466. cchDone = cchRun;
  467. }
  468. else
  469. {
  470. cchDone = cch = vfli.ichFirstWide - ichFirst;
  471. }
  472. /* This run is cut short because of a wide space, so we need
  473. to calculate a new width. */
  474. {
  475. register int *pdxp;
  476. register int cchT = cch;
  477. PCH pch = &vfli.rgch[ichFirst + cchDoneT];
  478. dxp = 0;
  479. pdxp = &vfli.rgdxp[ichFirst + cchDoneT];
  480. while (cchT-- > 0)
  481. {
  482. dxp += *pdxp++;
  483. if (*pch++ == chSpace)
  484. ++cBreakRun;
  485. }
  486. }
  487. }
  488. else
  489. {
  490. cchDone = cch = cchRun;
  491. }
  492. while (cch > 0)
  493. {
  494. switch (*pch)
  495. {
  496. CHAR ch;
  497. int dxpT;
  498. case chTab:
  499. #ifdef CASHMERE
  500. /* chLeader contains tab leader character (see
  501. FormatLine) */
  502. if ((ch = pchp->chLeader) != chSpace)
  503. {
  504. int cxpTab;
  505. CHAR rgch[32];
  506. int dxpLeader = CharWidth(ch);
  507. int xpT = xp;
  508. int iLevelT = SaveDC(vhMDC);
  509. SetBytes(&rgch[0], ch, 32);
  510. dxpT = vfli.rgdxp[ichFirst];
  511. cxpTab = ((dxpT + dxpLeader - 1) / dxpLeader + 31)
  512. >> 5;
  513. xp += dxpT;
  514. while (cxpTab-- > 0)
  515. {
  516. TextOut(vhMDC, xpT, yp, (LPSTR)rgch, 32);
  517. xpT += dxpLeader << 5;
  518. }
  519. RestoreDC(vhMDC, iLevelT);
  520. }
  521. else
  522. #endif /* CASHMERE */
  523. {
  524. #ifdef SMFONT
  525. /* Expand the opaque rectangle to include the tab.
  526. */
  527. rcOpaque.right += vfli.rgdxp[ichFirst];
  528. #endif /* SMFONT */
  529. xp += vfli.rgdxp[ichFirst];
  530. }
  531. if (fTabsKludge && ichFirst >= vfli.ichLastTab)
  532. {
  533. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  534. if( vpapAbs.jc != jcBoth )
  535. SetTextJustification(vhMDC, (dxpExtra =
  536. vfli.dxpExtra) * cBreakRun, cBreakRun);
  537. else
  538. dxpExtra = vfli.dxpExtra;
  539. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  540. if( vpapAbs.jc != jcBoth )
  541. SetTextJustification(vhMDC, (dxpExtra =
  542. vfli.dxpExtra) * cBreakRun, cBreakRun);
  543. else
  544. dxpExtra = vfli.dxpExtra;
  545. #else
  546. SetTextJustification(vhMDC, (dxpExtra =
  547. vfli.dxpExtra) * cBreakRun, cBreakRun);
  548. #endif /* JAPAN */
  549. #ifdef SMFONT
  550. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  551. if( vpapAbs.jc != jcBoth )
  552. SetTextJustification(hDC, dxpExtra * cBreakRun,
  553. cBreakRun);
  554. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  555. if( vpapAbs.jc != jcBoth )
  556. SetTextJustification(hDC, dxpExtra * cBreakRun,
  557. cBreakRun);
  558. #else
  559. SetTextJustification(hDC, dxpExtra * cBreakRun, cBreakRun);
  560. #endif /* JAPAN */
  561. #endif /* SMFONT */
  562. fTabsKludge = FALSE;
  563. }
  564. dxp -= vfli.rgdxp[ichFirst];
  565. pch++;
  566. cch--;
  567. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  568. iRun++;
  569. pdxpT++;
  570. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  571. iRun++;
  572. pdxpT++;
  573. #endif
  574. goto EndLoop;
  575. #ifdef CASHMERE
  576. case schPage:
  577. if (!pchp->fSpecial)
  578. {
  579. goto EndLoop;
  580. }
  581. stBuf[0] = CchExpPgn(&stBuf[1], vpgn, vsepAbs.nfcPgn,
  582. flmSandMode, ichMaxLine);
  583. goto DrawSpecial;
  584. case schFootnote:
  585. if (!pchp->fSpecial)
  586. {
  587. goto EndLoop;
  588. }
  589. stBuf[0] = CchExpFtn(&stBuf[1], cpMin + ichFirst,
  590. flmSandMode, ichMaxLine);
  591. DrawSpecial:
  592. #else /* not CASHMERE */
  593. case schPage:
  594. case schFootnote:
  595. if (!pchp->fSpecial)
  596. {
  597. goto EndLoop;
  598. }
  599. stBuf[0] = *pch == schPage && (wwdCurrentDoc.fEditHeader
  600. || wwdCurrentDoc.fEditFooter) ? CchExpPgn(&stBuf[1],
  601. vpgn, 0, flmSandMode, ichMaxLine) :
  602. CchExpUnknown(&stBuf[1], flmSandMode, ichMaxLine);
  603. #endif /* not CASHMERE */
  604. #ifdef SMFONT
  605. /* Calculate the opaque rectangle. */
  606. rcOpaque.right += vfli.rgdxp[ichFirst] +
  607. vfmiScreen.dxpOverhang;
  608. TextOut(hDC, xp, ypLine+yp, &stBuf[1], stBuf[0]);
  609. #else /* not SMFONT */
  610. TextOut(vhMDC, xp, yp, (LPSTR)&stBuf[1], stBuf[0]);
  611. #endif /* SMFONT */
  612. break;
  613. #ifdef DBCS
  614. #if !defined(JAPAN) && !defined(KOREA)
  615. /* Write ver3.1j endmark is 1charcter t-yoshio May 26,92*/
  616. case chMark1:
  617. if(*(pch+1) == chEMark)
  618. { /* This run only contains EndMark */
  619. rcOpaque.right += dxp + vfmiScreen.dxpOverhang;
  620. #if defined (TAIWAN) || defined(PRC) // solve italic font overhang truncation problem, MSTC - pisuih, 2/19/93
  621. TextOut(hDC, xp, (yp>0?(ypLine+yp):ypLine), (LPSTR)pch, cch );
  622. #else
  623. ExtTextOut(hDC, xp, (yp>0?(ypLine+yp):ypLine),
  624. 2, (LPRECT)&rcOpaque,(LPSTR)pch, cch, (LPSTR)NULL);
  625. #endif
  626. pch += cch;
  627. cch = 0;
  628. xp += dxp;
  629. rcOpaque.left
  630. = (rcOpaque.right = xp) + vfmiScreen.dxpOverhang;
  631. }
  632. /* else fall through */
  633. #endif /*JAPAN*/
  634. #endif
  635. default:
  636. goto EndLoop;
  637. }
  638. dxp -= vfli.rgdxp[ichFirst];
  639. #ifdef SMFONT
  640. /* End the line if no more will fit into the window. */
  641. if ((xp += vfli.rgdxp[ichFirst++]) >= xpMac) {
  642. goto EndLine;
  643. }
  644. rcOpaque.left = (rcOpaque.right = xp) +
  645. vfmiScreen.dxpOverhang;
  646. #else /* not SMFONT */
  647. xp += vfli.rgdxp[ichFirst++];
  648. #endif /* SMFONT */
  649. pch++;
  650. cch--;
  651. #ifdef JAPAN // added 09 Jul. 1992 by Hiraisi
  652. pdxpT++;
  653. #endif
  654. }
  655. EndLoop:
  656. #ifdef SMFONT
  657. if (cch == 0)
  658. {
  659. Assert(dxp == 0);
  660. }
  661. else
  662. {
  663. /* Calculate the opaque rectangle. */
  664. rcOpaque.right += dxp + vfmiScreen.dxpOverhang;
  665. #if 0
  666. {
  667. char msg[180];
  668. wsprintf(msg,"putting out %d characters\n\r",cch);
  669. OutputDebugString(msg);
  670. }
  671. #endif
  672. #ifdef JAPAN // added 19 Jun. 1992 by Hiraisi
  673. if( vpapAbs.jc == jcBoth&&!fTabsKludge ) {
  674. CHAR *ptr1, *ptr2;
  675. int len, cnt;
  676. int iExtra, iSpace, iWid;
  677. BOOL bFlag;
  678. typeCP RealcpEnd;
  679. ptr2 = pch;
  680. for( cnt=0 ; cnt < cch ; ) {
  681. ptr1 = ptr2;
  682. iExtra = dxpExtra;
  683. iWid = len = 0;
  684. bFlag = TRUE;
  685. if( IsDBCSLeadByte(*ptr2) ) {
  686. for( ; cnt < cch ; ) {
  687. iWid += *pdxpT;
  688. pdxpT += 2;
  689. cnt += 2;
  690. len += 2;
  691. iRun += 2;
  692. ptr2 += 2;
  693. if( --iNonWideSpaces == 0 ) {
  694. dxpExtra++;
  695. break;
  696. }
  697. if( iRun == dcp - 2 )
  698. break;
  699. if( iRun == dcp ) { /* lastDBC(maybe) */
  700. iExtra = 0;
  701. break;
  702. }
  703. if( !IsDBCSLeadByte(*ptr2) )
  704. break;
  705. }
  706. }
  707. else {
  708. if( FKana( (int)*ptr2) ) {
  709. for( ; cnt < cch ; ) {
  710. iWid += *pdxpT++;
  711. cnt++;
  712. len++;
  713. iRun++;
  714. ptr2++;
  715. if( --iNonWideSpaces == 0 ) {
  716. dxpExtra++;
  717. break;
  718. }
  719. if( iRun == dcp - 1 )
  720. break;
  721. if( iRun == dcp ) { /* last SBC(maybe) */
  722. iExtra = 0;
  723. break;
  724. }
  725. if( !FKana( (int)*ptr2) )
  726. break;
  727. }
  728. }
  729. else {
  730. for( bFlag = FALSE,iSpace = 0; cnt < cch ; ) {
  731. iWid += *pdxpT++;
  732. cnt++;
  733. len++;
  734. iRun++;
  735. if( *ptr2++ == chSpace || !vfWordWrap ) {
  736. iSpace++;
  737. if( --iNonWideSpaces == 0 ) {
  738. dxpExtra++;
  739. break;
  740. }
  741. }
  742. if( iRun == dcp - 1 )
  743. break;
  744. if( iRun == dcp ) { /* lastSBC(maybe) */
  745. iExtra = 0;
  746. break;
  747. }
  748. if( IsDBCSLeadByte(*ptr2 ) ||
  749. FKana((int)*ptr2) )
  750. break;
  751. }
  752. }
  753. }
  754. if( vfWordWrap && !bFlag ) {
  755. SetTextCharacterExtra( hDC, 0 );
  756. SetTextJustification( hDC,
  757. iExtra*iSpace,iSpace);
  758. }
  759. else {
  760. SetTextJustification(hDC,0,0);
  761. SetTextCharacterExtra(hDC,iExtra);
  762. }
  763. /*-TextOut-*/
  764. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  765. /*Undetermine*/
  766. if( (selUncpFirst != selUncpLim) &&
  767. *ptr1 != chEMark) {
  768. RealcpEnd = RealcpFirst + len;
  769. UndetermineString(hDC, xp, ypLine+yp, ptr1,
  770. len, RealcpFirst, RealcpEnd);
  771. } else
  772. TextOut(hDC,xp,ypLine+yp,ptr1,len);
  773. #else
  774. TextOut(hDC,xp,ypLine+yp,ptr1,len);
  775. #endif
  776. RealcpFirst+=len;
  777. xp+=iWid;
  778. }
  779. }
  780. else{
  781. iRun += cch;
  782. SetTextCharacterExtra( hDC, 0 );
  783. /*Undetermine*/
  784. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  785. if((selUncpFirst != selUncpLim) && *pch != chEMark)
  786. UndetermineString( hDC, xp, ypLine+yp,
  787. pch, cch, RealcpFirst, RealcpFirst+cch );
  788. else
  789. /* Output cch characters starting at pch */
  790. TextOut(hDC, xp, ypLine+yp, pch, cch);
  791. #else
  792. /* Output cch characters starting at pch */
  793. TextOut(hDC, xp, ypLine+yp, pch, cch);
  794. #endif
  795. /* End the line if no more will fit into the window. */
  796. xp += dxp;
  797. RealcpFirst+=cch;
  798. }
  799. if (xp >= xpMac)
  800. #elif defined(TAIWAN) || defined(PRC) //Daniel/MSTC, 1993/02/25, for jcBoth
  801. if( vpapAbs.jc == jcBoth) { //&& !fTabsKludge ) {
  802. CHAR *ptr1, *ptr2;
  803. int len, cnt;
  804. int iExtra, iSpace, iWid;
  805. BOOL bFlag;
  806. typeCP RealcpEnd;
  807. ptr2 = pch;
  808. for( cnt=0 ; cnt < cch ; ) {
  809. ptr1 = ptr2;
  810. iExtra = dxpExtra;
  811. iWid = len = 0;
  812. bFlag = TRUE;
  813. if( IsDBCSLeadByte(*ptr2) ) {
  814. for( ; cnt < cch ; ) {
  815. iWid += *pdxpT;
  816. pdxpT += 2;
  817. cnt += 2;
  818. len += 2;
  819. iRun += 2;
  820. ptr2 += 2;
  821. if( --iNonWideSpaces == 0 ) {
  822. dxpExtra++;
  823. break;
  824. }
  825. if( iRun == dcp - 2 )
  826. break;
  827. if( iRun == dcp ) { /* lastDBC(maybe) */
  828. iExtra = 0;
  829. break;
  830. }
  831. if( !IsDBCSLeadByte(*ptr2) )
  832. break;
  833. }
  834. }
  835. else {
  836. if( FKana( (int)*ptr2) ) {
  837. for( ; cnt < cch ; ) {
  838. iWid += *pdxpT++;
  839. cnt++;
  840. len++;
  841. iRun++;
  842. ptr2++;
  843. if( --iNonWideSpaces == 0 ) {
  844. dxpExtra++;
  845. break;
  846. }
  847. if( iRun == dcp - 1 )
  848. break;
  849. if( iRun == dcp ) { /* last SBC(maybe) */
  850. iExtra = 0;
  851. break;
  852. }
  853. if( !FKana( (int)*ptr2) )
  854. break;
  855. }
  856. }
  857. else {
  858. for( bFlag = FALSE,iSpace = 0; cnt < cch ; ) {
  859. iWid += *pdxpT++;
  860. cnt++;
  861. len++;
  862. iRun++;
  863. if( *ptr2++ == chSpace || !vfWordWrap ) {
  864. iSpace++;
  865. if( --iNonWideSpaces == 0 ) {
  866. dxpExtra++;
  867. break;
  868. }
  869. }
  870. if( iRun == dcp - 1 )
  871. break;
  872. if( iRun == dcp ) { /* lastSBC(maybe) */
  873. iExtra = 0;
  874. break;
  875. }
  876. if( IsDBCSLeadByte(*ptr2 ) ||
  877. FKana((int)*ptr2) )
  878. break;
  879. }
  880. }
  881. }
  882. if( vfWordWrap && !bFlag ) {
  883. SetTextCharacterExtra( hDC, 0 );
  884. SetTextJustification( hDC,
  885. iExtra*iSpace,iSpace);
  886. }
  887. else {
  888. SetTextJustification(hDC,0,0);
  889. SetTextCharacterExtra(hDC,iExtra);
  890. }
  891. /*-TextOut-*/
  892. //#if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  893. // /*Undetermine*/
  894. // if( (selUncpFirst != selUncpLim) &&
  895. // *ptr1 != chEMark) {
  896. // RealcpEnd = RealcpFirst + len;
  897. // UndetermineString(hDC, xp, ypLine+yp, ptr1,
  898. // len, RealcpFirst, RealcpEnd);
  899. // } else
  900. // TextOut(hDC,xp,ypLine+yp,ptr1,len);
  901. //#else
  902. TextOut(hDC,xp,ypLine+yp,ptr1,len);
  903. //#endif
  904. RealcpFirst+=len;
  905. xp+=iWid;
  906. }
  907. }
  908. else{
  909. iRun += cch;
  910. SetTextCharacterExtra( hDC, 0 );
  911. /*Undetermine*/
  912. //#if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  913. // if((selUncpFirst != selUncpLim) && *pch != chEMark)
  914. // UndetermineString( hDC, xp, ypLine+yp,
  915. // pch, cch, RealcpFirst, RealcpFirst+cch );
  916. // else
  917. // /* Output cch characters starting at pch */
  918. // TextOut(hDC, xp, ypLine+yp, pch, cch);
  919. //#else
  920. /* Output cch characters starting at pch */
  921. TextOut(hDC, xp, ypLine+yp, pch, cch);
  922. //#endif
  923. /* End the line if no more will fit into the window. */
  924. xp += dxp;
  925. RealcpFirst+=cch;
  926. }
  927. if (xp >= xpMac)
  928. #else
  929. /* Output cch characters starting at pch */
  930. #if defined(KOREA)
  931. if ((cch == 1) && (pch[0] == chEMark))
  932. {
  933. int iPrevBkMode;
  934. iPrevBkMode = SetBkMode(hDC, OPAQUE);
  935. TextOut(hDC, xp, ypLine+yp, pch, cch);
  936. SetBkMode(hDC, iPrevBkMode);
  937. }
  938. else
  939. TextOut(hDC, xp, ypLine+yp, pch, cch);
  940. #else
  941. TextOut(hDC, xp, ypLine+yp, pch, cch);
  942. #endif
  943. /* End the line if no more will fit into the window. */
  944. if ((xp += dxp) >= xpMac)
  945. #endif // JAPAN
  946. {
  947. goto EndLine;
  948. }
  949. rcOpaque.left = (rcOpaque.right = xp) +
  950. vfmiScreen.dxpOverhang;
  951. pch += cch;
  952. }
  953. #else /* not SMFONT */
  954. /* Output cch characters starting at pch */
  955. TextOut(vhMDC, xp, yp, (LPSTR)pch, cch);
  956. xp += dxp;
  957. pch += cch;
  958. #endif /* SMFONT */
  959. } /* end while (cchDone<cchRun) */
  960. } /* end if (dxp>0) */
  961. } /* end for dcp=0..dcpMac */
  962. #ifdef SMFONT
  963. EndLine:
  964. /* Restore the clip region if need be. */
  965. if (xpMin != 0)
  966. {
  967. SelectClipRgn(hDC, NULL);
  968. }
  969. EndLine2:
  970. #endif /* SMFONT */
  971. #ifdef CASHMERE
  972. if (vfVisiMode)
  973. {
  974. AddVisiSpaces(ww, &(**pwwd->hdndl)[dl], vfli.dypBase, vfli.dypAfter +
  975. vfli.dypFont);
  976. }
  977. #endif /* CASHMERE */
  978. vfTextBltValid = FALSE;
  979. if ((ww == wwCur) && (pwwd->doc != docScrap) && !vfSelHidden &&
  980. (selCur.cpLim >= cpMin))
  981. {
  982. if (selCur.cpFirst <= cpMac)
  983. {
  984. /* Show selection */
  985. int xpFirst;
  986. int xpLim;
  987. #ifdef ENABLE
  988. if (vfli.fSplatNext && selCur.cpFirst == selCur.cpLim &&
  989. selCur.cpFirst == cpMac)
  990. {
  991. vfInsEnd = TRUE;
  992. ClearInsertLine();
  993. }
  994. vfInsertOn = FALSE;
  995. #endif /* ENABLE */
  996. if (selCur.cpFirst <= cpMin && selCur.cpLim >= cpMac)
  997. {
  998. xpFirst = vfli.xpLeft;
  999. xpLim = vfli.xpReal;
  1000. }
  1001. else if (selCur.cpFirst < cpMac || (selCur.cpLim == cpMac &&
  1002. vfInsEnd))
  1003. {
  1004. typeCP cpBegin = CpMax(cpMin, selCur.cpFirst);
  1005. typeCP cpEnd = CpMin(cpMac, selCur.cpLim);
  1006. dxp = DxpDiff((int)(cpBegin - cpMin), (int)(cpEnd - cpBegin),
  1007. &xpFirst);
  1008. xpLim = min(xpMin + vfli.xpReal, xpFirst + dxp);
  1009. }
  1010. else
  1011. {
  1012. goto DidntHighlight;
  1013. }
  1014. xpSel = xpSelBar + max(xpFirst - xpMin, 0);
  1015. if (xpLim > xpFirst)
  1016. {
  1017. /* Set highlighting at desired screen position. */
  1018. dxpSel = max(xpLim - max(xpFirst, xpMin), 0);
  1019. }
  1020. else if (selCur.cpFirst == selCur.cpLim && ((selCur.cpLim != cpMac)
  1021. ^ vfInsEnd))
  1022. {
  1023. vfInsertOn = FALSE; /* Because we redisplayed insert pt line */
  1024. #ifdef CASHMERE
  1025. vdypCursLine = min(vfli.dypFont, vfli.dypLine - vfli.dypAfter);
  1026. vypCursLine = ypLine + dyp - vfli.dypAfter;
  1027. #else /* not CASHMERE */
  1028. #ifdef DBCS // Some double byte fonts have bigger character
  1029. // face than the line hight.
  1030. vdypCursLine = min(vfli.dypFont, vfli.dypLine - vfli.dypAfter);
  1031. #else
  1032. vdypCursLine = vfli.dypFont;
  1033. #endif
  1034. vypCursLine = ypLine + dyp;
  1035. #endif /* not CASHMERE */
  1036. vxpCursLine = xpSel;
  1037. /* Start blinking in a while */
  1038. vfSkipNextBlink = TRUE;
  1039. fInsertOn = xpFirst >= xpMin;
  1040. }
  1041. DidntHighlight:;
  1042. }
  1043. }
  1044. #ifdef SMFONT
  1045. /* Invert the selection */
  1046. if (dxpSel != 0) {
  1047. PatBlt(hDC, xpSel, ypLine, dxpSel, dyp, DSTINVERT);
  1048. }
  1049. #else /* not SMFONT */
  1050. /* Blt the line of text onto the screen. */
  1051. PatBlt(vhMDC, 0, 0, xpSelBar, dyp, vfMonochrome ? ropErase : WHITENESS);
  1052. if (dxpSel == 0)
  1053. {
  1054. BitBlt(hDC, 0, ypLine, xpMac, dyp, vhMDC, 0, 0, SRCCOPY);
  1055. }
  1056. else
  1057. {
  1058. BitBlt(hDC, 0, ypLine, xpSel, dyp, vhMDC, 0, 0, SRCCOPY);
  1059. BitBlt(hDC, xpSel, ypLine, dxpSel, dyp, vhMDC, xpSel, 0, NOTSRCCOPY);
  1060. xpSel += dxpSel;
  1061. BitBlt(hDC, xpSel, ypLine, xpMac - xpSel, dyp, vhMDC, xpSel, 0,
  1062. SRCCOPY);
  1063. }
  1064. #endif /* SMFONT */
  1065. /* Draw the insertion bar if necessary. */
  1066. if (fInsertOn)
  1067. {
  1068. DrawInsertLine();
  1069. }
  1070. #if defined(JAPAN) & defined(DBCS_IME) // Set a flag for IME management.
  1071. else
  1072. {
  1073. bClearCall = TRUE;
  1074. }
  1075. #endif
  1076. DrawMark:
  1077. /* Draw the character in the style bar if necessary. */
  1078. if (chMark != '\0')
  1079. {
  1080. #ifdef SYSENDMARK
  1081. #ifdef DBCS // prepare buf for double-byte end mark.
  1082. CHAR rgch[cchKanji];
  1083. #endif
  1084. struct CHP chpT;
  1085. extern struct CHP vchpNormal;
  1086. blt(&vchpNormal, &chpT, cwCHP);
  1087. chpT.ftc = ftcSystem;
  1088. chpT.ftcXtra = 0;
  1089. chpT.hps = hpsDefault;
  1090. /* Draw the style character in the standard font. */
  1091. LoadFont(vfli.doc, &chpT, mdFontScreen);
  1092. #ifdef DBCS // we use double byte end mark.
  1093. #if defined(JAPAN) || defined(KOREA) /*t-yoshio May 26,92*/
  1094. #if defined(KOREA)
  1095. {
  1096. int iPrevBkMode;
  1097. iPrevBkMode = SetBkMode(hDC, OPAQUE);
  1098. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  1099. (LPSTR)&chMark, 1);
  1100. SetBkMode(hDC, iPrevBkMode);
  1101. }
  1102. #else
  1103. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  1104. (LPSTR)&chMark, 1);
  1105. #endif
  1106. #else
  1107. rgch[0] = chMark1;
  1108. rgch[1] = chMark;
  1109. rcOpaque.left = 0;
  1110. rcOpaque.right = DxpFromCh(chMark1,FALSE);
  1111. rcOpaque.top = ypLine;
  1112. rcOpaque.bottom = ypLine+dyp;
  1113. /* When this line string is lower than system font,it remains dust,
  1114. so we must clip this mark. */
  1115. ExtTextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  1116. ETO_CLIPPED, (LPRECT)&rcOpaque,(LPSTR)rgch, cchKanji, (LPSTR)NULL);
  1117. #endif /*JAPAN*/
  1118. #else
  1119. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  1120. (LPSTR)&chMark, 1);
  1121. #endif /* DBCS */
  1122. #else /* ifdef SYSENDMARK */
  1123. /*T-HIROYN sync 3.0 disp.c */
  1124. #if 0
  1125. /* Draw the style character in the standard font. */
  1126. LoadFont(vfli.doc, NULL, mdFontScreen);
  1127. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  1128. (LPSTR)&chMark, 1);
  1129. #endif
  1130. #if defined(JAPAN) || defined(KOREA) /* KenjiK '90-10-26 */
  1131. /* Draw the style character in the standard font. */
  1132. {
  1133. CHAR rgch[cchKanji];
  1134. LoadFont(vfli.doc, NULL, mdFontScreen);
  1135. rgch[0] = chMark1;
  1136. rgch[1] = chMark;
  1137. #if defined(KOREA)
  1138. {
  1139. int iPrevBkMode;
  1140. iPrevBkMode = SetBkMode(hDC, OPAQUE);
  1141. ExtTextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,ETO_CLIPPED, (LPRECT)&rcOpaque,(LPSTR)rgch, cchKanji, (LPSTR)NULL);
  1142. SetBkMode(hDC, iPrevBkMode);
  1143. }
  1144. #else
  1145. ExtTextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,ETO_CLIPPED, (LPRECT)&rcOpaque,(LPSTR)rgch, cchKanji, (LPSTR)NULL);
  1146. #endif
  1147. }
  1148. #else /* JAPAN */
  1149. /* Draw the style character in the standard font. */
  1150. LoadFont(vfli.doc, NULL, mdFontScreen);
  1151. TextOut(hDC, 0, ypLine + dyp - vfli.dypBase - vfmiScreen.dypBaseline,
  1152. (LPSTR)&chMark, 1);
  1153. #endif /* JAPAN */
  1154. #endif /* if-else-def SYSENDMARK */
  1155. }
  1156. if (vfli.fGraphics)
  1157. {
  1158. DisplayGraphics(ww, dl, fDontDisplay);
  1159. }
  1160. Finished:
  1161. Scribble(5,' ');
  1162. }
  1163. /* D X P D I F F */
  1164. DxpDiff(dcpFirst, dcp, pdxpFirst)
  1165. int dcpFirst;
  1166. int dcp;
  1167. int *pdxpFirst;
  1168. {
  1169. #if 1
  1170. register int *pdxp = &vfli.rgdxp[0];
  1171. register int cch;
  1172. int dxp = vfli.xpLeft;
  1173. #ifdef ENABLE /* Not used */
  1174. int ichLim = dcpFirst + dcp;
  1175. #endif
  1176. if (dcp > vfli.ichMac - dcpFirst)
  1177. { /* This should not be, but is when we have a CR */
  1178. //Assert( dcpFirst < vfli.ichMac );
  1179. dcp = vfli.ichMac - dcpFirst;
  1180. }
  1181. for (cch = 0; cch < dcpFirst; ++cch)
  1182. {
  1183. dxp += *pdxp++;
  1184. }
  1185. *pdxpFirst = dxp;
  1186. dxp = 0;
  1187. for (cch = 0; cch < dcp; ++cch)
  1188. {
  1189. dxp += *pdxp++;
  1190. }
  1191. return dxp;
  1192. #else
  1193. int dxp;
  1194. if (dcp > vfli.ichMac - dcpFirst)
  1195. { /* This should not be, but is when we have a CR */
  1196. Assert( dcpFirst < vfli.ichMac );
  1197. dcp = vfli.ichMac - dcpFirst;
  1198. }
  1199. /* first get space up to first character */
  1200. *pdxpFirst = LOWORD(GetTextExtent(hDC,vfli.rgch,dcpFirst)) + vfli.xpLeft;
  1201. /* now get space between first and first+dcp */
  1202. dxp = LOWORD(GetTextExtent(hDC,vfli.rgch+dcpFirst,dcp));
  1203. return dxp;
  1204. #endif
  1205. }
  1206. UpdateDisplay(fAbortOK)
  1207. int fAbortOK;
  1208. {
  1209. int ww;
  1210. if (wwMac <= 0)
  1211. {
  1212. return;
  1213. }
  1214. #ifdef CASHMERE
  1215. for (ww = 0; ww < wwMac; ww++)
  1216. if ( rgwwd[ww].doc != docScrap )
  1217. {
  1218. UpdateWw(ww, fAbortOK);
  1219. if (rgwwd[ww].fDirty || vfOutOfMemory)
  1220. {
  1221. return; /* update has been interrupted */
  1222. }
  1223. }
  1224. #else /* not CASHMERE */
  1225. UpdateWw(wwDocument, fAbortOK);
  1226. if (wwdCurrentDoc.fDirty || vfOutOfMemory)
  1227. {
  1228. /* Update has been interrupted */
  1229. return;
  1230. }
  1231. #endif /* not CASHMERE */
  1232. if (wwdCurrentDoc.fRuler)
  1233. {
  1234. UpdateRuler();
  1235. }
  1236. }
  1237. /* U P D A T E W W */
  1238. UpdateWw(ww, fAbortOK)
  1239. int ww, fAbortOK;
  1240. { /* Redisplay ww as necessary */
  1241. extern int vfWholePictInvalid;
  1242. register struct WWD *pwwd = &rgwwd[ww];
  1243. int dlMac;
  1244. int dlOld, dlNew;
  1245. int doc;
  1246. int ichCp;
  1247. struct EDL *pedlNew;
  1248. register struct EDL *pedl;
  1249. struct EDL (**hdndl)[]=pwwd->hdndl;
  1250. int dypDiff;
  1251. int ypTop;
  1252. int ypFirstInval;
  1253. int dr;
  1254. int fLastNotShown;
  1255. typeCP cp, cpMacWw;
  1256. if (!pwwd->fDirty)
  1257. {
  1258. return;
  1259. }
  1260. if (!((**hpdocdod)[pwwd->doc].fDisplayable))
  1261. return;
  1262. if (fAbortOK && FImportantMsgPresent())
  1263. return;
  1264. #if 0 // how to get first and last cp's in invalid rect?
  1265. #if defined(OLE)
  1266. /*
  1267. Load visible objects. Do it now rather than in DisplayGraphics()
  1268. because here it has less chance of disrupting the state variables
  1269. upon which UpdateWw depends.
  1270. */
  1271. ObjEnumInRange(docCur,cpMinCur,cpMacCur,ObjLoadObjectInDoc);
  1272. #endif
  1273. #endif
  1274. dlMac = pwwd->dlMac;
  1275. ypTop = pwwd->ypMin;
  1276. Assert( ww >= 0 && ww < wwMax );
  1277. vfli.doc = docNil; /* An aid to Fast Insert */
  1278. UpdateInvalid(); /* InvalBand for what Windows considers to be invalid */
  1279. ypFirstInval = pwwd->ypFirstInval;
  1280. #ifndef CASHMERE
  1281. Assert( ww == wwCur ); /* A MEMO-only assumption */
  1282. #endif /* CASHMERE */
  1283. Scribble(5, 'U');
  1284. ValidateMemoryDC(); /* to do any update, we need a good memory DC */
  1285. if (vhMDC == NULL)
  1286. {
  1287. WinFailure();
  1288. return;
  1289. }
  1290. doc = pwwd->doc;
  1291. vfli.doc = docNil;
  1292. if (pwwd->fCpBad)
  1293. {
  1294. /* cp first displayed has not been blessed */
  1295. #ifdef CASHMERE /* Must do this if ww != wwCur assertion is FALSE */
  1296. int wwT = wwCur;
  1297. if (ww != wwCur && wwCur >= 0)
  1298. /* CtrBackTrs cache is only good for wwCur. Treat != case */
  1299. {
  1300. if (pwwdCur->fDirty) /* Do wwCur first, saving cache */
  1301. UpdateWw(wwCur, fAbortOK);
  1302. if (fAbortOK && FImportantMsgPresent())
  1303. return;
  1304. ChangeWw(ww, false);
  1305. CtrBackDypCtr( 0, 0 ); /* Validate pwwdCur->cpFirst */
  1306. ChangeWw(wwT, false);
  1307. }
  1308. else
  1309. #endif /* CASHMERE */
  1310. {
  1311. if (fAbortOK && FImportantMsgPresent())
  1312. return;
  1313. CtrBackDypCtr( 0, 0 ); /* Validate pwwdCur->cpFirst */
  1314. }
  1315. }
  1316. /* check for cpMin accessible in this ww */
  1317. RestartUpdate:
  1318. vfWholePictInvalid = fTrue; /* Tells DisplayGraphics to
  1319. abandon accumulated partial pict rect */
  1320. fLastNotShown = fFalse;
  1321. cp = CpMax(pwwd->cpMin, pwwd->cpFirst);
  1322. cpMacWw = pwwd->cpMac;
  1323. ichCp = pwwd->ichCpFirst;
  1324. /* Note test for dlNew==0 that guarantees that there will be at least
  1325. one dl -- this was added for WRITE because we do not have
  1326. the ability to enforce a minimum window size */
  1327. for (dlNew = dlOld = 0; ypTop < pwwd->ypMac || (dlNew == 0) ; dlNew++)
  1328. /* we have: cp, ichCP: pints to text desired on the coming line dlNew
  1329. ypTop: desired position for top of dlNew -1
  1330. dlOld: next line to be considered for re-use
  1331. */
  1332. /* check for having to extend dndl array */
  1333. {
  1334. if (dlNew >= (int)pwwd->dlMax)
  1335. {
  1336. /* extend the array with uninitialized dl's, increment max, break if no space.
  1337. We assume that dlMac(Old) was <= dlMax, so the dl's will not be looked at
  1338. but used only to store new lines */
  1339. #define ddlIncr 5
  1340. if (!FChngSizeH(hdndl, (pwwd->dlMax + ddlIncr) * cwEDL, fFalse))
  1341. break;
  1342. pwwd->dlMax += ddlIncr;
  1343. }
  1344. /* discard unusable dl's */
  1345. for (; dlOld < dlMac; dlOld++)
  1346. { /* Set dlOld and pedl to the next good dl */
  1347. int ypTopOld, ypOld;
  1348. /* Re-entrant Heap Movement */
  1349. if (fAbortOK && !fLastNotShown && FImportantMsgPresent())
  1350. goto RetInval;
  1351. pedl = &(**hdndl)[dlOld];
  1352. ypOld = pedl->yp;
  1353. /* loop if: invalid, passed over in cp space, passed over in dl space,
  1354. passed over in yp space,
  1355. in invalid band, passed over in ich space */
  1356. if (!pedl->fValid || dlOld < dlNew || pedl->cpMin < cp
  1357. || (ypTopOld = (ypOld - pedl->dyp)) < ypTop
  1358. || (ypOld >= ypFirstInval && ypTopOld <= pwwd->ypLastInval)
  1359. || (pedl->cpMin == cp && pedl->ichCpMin < ichCp))
  1360. continue;
  1361. /* now we have dlOld, an acceptable if not necessarily useful dl.
  1362. now compute dlNew either from scratch or by re-using dlOld. To be
  1363. re-useable, dlOld must have right cp/ichCp pair, plus be totally on screen
  1364. or, if it is a partial line, it must stay still or move down - not up */
  1365. if (pedl->cpMin == cp && pedl->ichCpMin == ichCp &&
  1366. (ypOld <= pwwd->ypMac || ypTopOld <= ypTop))
  1367. {
  1368. /* Re-use this dl */
  1369. int yp = ypTop;
  1370. if (fLastNotShown)
  1371. {
  1372. /* HEAP MOVEMENT */
  1373. DisplayFli(ww, dlNew - 1, fLastNotShown = fFalse);
  1374. pedl = &(**hdndl)[dlOld];
  1375. }
  1376. cp = pedl->cpMin + pedl->dcpMac;
  1377. ichCp = pedl->fIchCpIncr ? pedl->ichCpMin + 1 : 0;
  1378. ypTop += pedl->dyp;
  1379. if (dlOld != dlNew || ypTopOld != yp)
  1380. {
  1381. DypScroll(ww, dlOld, dlNew - dlOld, yp);
  1382. if (vfScrollInval)
  1383. {
  1384. /* There was a popup; invalid region might have changed */
  1385. /* fLastNotShown test is for interrupting picture display */
  1386. /* before we've really displayed it */
  1387. (**hdndl) [dlOld].fValid = fFalse;
  1388. goto Restart1;
  1389. }
  1390. dlMac += dlNew - dlOld;
  1391. }
  1392. dlOld = dlNew + 1;
  1393. goto NextDlNew;
  1394. }
  1395. break;
  1396. }
  1397. /* cpMin > cp, the line is not anywhere so it will have to be formatted
  1398. from scratch */
  1399. if (fAbortOK && !fLastNotShown && FImportantMsgPresent())
  1400. goto RetInval;
  1401. FormatLine(doc, cp, ichCp, cpMacWw, flmSandMode); /* Creates vfli */
  1402. if (vfOutOfMemory)
  1403. goto RetInval;
  1404. ichCp = vfli.ichCpMac;
  1405. cp = vfli.cpMac;
  1406. /* advance invalid band so that update can resume after an interruption */
  1407. pwwd->ypFirstInval = (ypTop += vfli.dypLine);
  1408. pedl = &(**hdndl)[dlOld];
  1409. if (dlOld < dlMac && pedl->cpMin == cp && pedl->ichCpMin == ichCp)
  1410. {
  1411. int dlT = dlOld;
  1412. /* line at dlOld is a valid, existing line that will abutt the line just about
  1413. to be displayed. */
  1414. if (dlOld == dlNew && pedl->yp - pedl->dyp <= ypTop)
  1415. /* the line about to be overwritten will be re-used in the next loop.
  1416. Hence, it is worthwhile to save this line and its dl */
  1417. DypScroll(ww, dlOld++, 1, ypTop);
  1418. else
  1419. /* Move the next line to its abutting position. We know that it has not yet been
  1420. overwritten (yp, dlOld all > than ypTop, dlNew) */
  1421. DypScroll(ww, dlOld, 0, ypTop);
  1422. if (vfScrollInval)
  1423. {
  1424. /* There was a popup; invalid region might have changed */
  1425. /* fLastNotShown test is for interrupting picture display */
  1426. /* before we've really displayed it */
  1427. (**hdndl) [dlT].fValid = fFalse;
  1428. Restart1:
  1429. if (fLastNotShown)
  1430. {
  1431. pwwd->ypFirstInval = pwwd->ypMin;
  1432. }
  1433. ypFirstInval = pwwd->ypFirstInval;
  1434. ypTop = pwwd->ypMin;
  1435. goto RestartUpdate;
  1436. }
  1437. }
  1438. /* true in 3rd param means put off picture redisplay till later */
  1439. /* condition: graphics & not last in picture & not last in y space and
  1440. not in front of a invalid or valid transition in the picture */
  1441. DisplayFli(ww, dlNew, fLastNotShown =
  1442. (vfli.fGraphics && vfli.ichCpMac!=0 && ypTop < pwwd->ypMac));
  1443. NextDlNew:;
  1444. }
  1445. Break1:
  1446. pwwd->dlMac = dlNew;
  1447. #ifdef CASHMERE
  1448. /* condition is here to avoid swapping */
  1449. if (pwwd->fSplit && rgwwd[pwwd->ww].fFtn)
  1450. CalcFtnLimits(pwwd);
  1451. #endif /* CASHMERE */
  1452. SetCurWwVScrollPos(); /* Set Scroll bar position */
  1453. vfTextBltValid = false;
  1454. /* reset invalid indications */
  1455. pwwd->fDirty = false;
  1456. pwwd->ypFirstInval = ypMaxAll;
  1457. pwwd->ypLastInval = 0; /* so that max in InvalBand will work */
  1458. Scribble(5, ' ');
  1459. goto Validate;
  1460. /* Before returning from an interrupt, invalidate lines that were overwritten
  1461. within the present update. */
  1462. RetInval:
  1463. Scribble(5, ' ');
  1464. for (; dlOld < dlMac; dlOld++)
  1465. {
  1466. pedl = &(**hdndl)[dlOld];
  1467. if ((pedl->yp - pedl->dyp) < ypTop)
  1468. pedl->fValid = fFalse;
  1469. else
  1470. break;
  1471. }
  1472. Validate: ;
  1473. #ifdef ENABLE /* We will let UpdateInvalid handle this in case
  1474. further invalidation occurred during the update */
  1475. { /* Tell Windows that the part we updated is valid */
  1476. RECT rc;
  1477. rc.left = 0;
  1478. rc.top = pwwd->ypMin;
  1479. rc.right = pwwd->xpMac;
  1480. rc.bottom = imin( pwwd->ypMac, ypTop );
  1481. ValidateRect( pwwd->wwptr, (LPRECT)&rc );
  1482. }
  1483. #endif
  1484. }
  1485. /* D Y P S C R O L L */
  1486. DypScroll(ww, dlFirst, ddl, ypTo)
  1487. int ww, dlFirst, ddl, ypTo;
  1488. {
  1489. /* Scroll dl's in a window, from dlFirst to end, down ddl lines (or up -ddl).
  1490. Bitmap is moved from top of dlFirst to ypTo. The yp's of the dl's are updated.
  1491. Returns the amount scrolled. (positive means down). */
  1492. register struct WWD *pwwd = &rgwwd[ww];
  1493. int dlMac;
  1494. int dlT;
  1495. int ypFrom;
  1496. int dypChange;
  1497. int cdlBelow;
  1498. struct EDL *pedl;
  1499. struct EDL *pedlT;
  1500. /* Do not call procedures while dndl is loaded up to avoid heap movement */
  1501. struct EDL *dndl = &(**(pwwd->hdndl))[0];
  1502. Assert( ww >= 0 && ww < wwMax );
  1503. vfScrollInval = fFalse;
  1504. /* Number of dl's below (and including) the first one to be scrolled */
  1505. cdlBelow = pwwd->dlMac - dlFirst;
  1506. pwwd->dlMac = min(pwwd->dlMac + ddl, pwwd->dlMax);
  1507. cdlBelow = max(0, min(cdlBelow, pwwd->dlMac - ddl - dlFirst));
  1508. pedlT = &dndl[dlFirst];
  1509. ypFrom = pedlT->yp - pedlT->dyp;
  1510. /* Length of area to be moved */
  1511. dypChange = ypTo - ypFrom;
  1512. if (cdlBelow > 0)
  1513. {
  1514. int dlTo = dlFirst + ddl;
  1515. int ypMac = pwwd->ypMac;
  1516. pedlT = &dndl[dlTo];
  1517. if (ddl != 0)
  1518. {
  1519. blt(&dndl[dlFirst], pedlT, cwEDL * cdlBelow);
  1520. }
  1521. for (dlT = dlTo; dlT < pwwd->dlMac; ++dlT, ++pedlT)
  1522. {
  1523. if (dypChange < 0 && pedlT->yp > ypMac)
  1524. {
  1525. /* Invalidate dl's that are pulled in from the ozone below ypMac
  1526. */
  1527. pedlT->fValid = fFalse;
  1528. }
  1529. else
  1530. {
  1531. pedlT->yp += dypChange;
  1532. }
  1533. }
  1534. }
  1535. if (dypChange != 0)
  1536. {
  1537. RECT rc;
  1538. SetRect( (LPRECT)&rc, 0, min(ypFrom, ypTo),
  1539. pwwd->xpMac, pwwd->ypMac );
  1540. Assert( ww == wwCur ); /* A MEMO-only assumption */
  1541. ScrollCurWw( &rc, 0, dypChange );
  1542. }
  1543. return dypChange;
  1544. }
  1545. FImportantMsgPresent()
  1546. {
  1547. /* If the next message is important enough to interrupt a screen update, we
  1548. return TRUE; if it can wait, we return FALSE */
  1549. BOOL fToggledKey;
  1550. extern MSG vmsgLast;
  1551. #ifdef DEBUG
  1552. unsigned wHeapVal = *(pLocalHeap + 1);
  1553. Assert( wHeapVal == 0 ); /* Heap should not be frozen */
  1554. #endif
  1555. #ifdef DBCS
  1556. if( donteat )
  1557. return TRUE;
  1558. #endif
  1559. while (PeekMessage((LPMSG) &vmsgLast, NULL, NULL, NULL, PM_NOREMOVE))
  1560. {
  1561. #if defined(JAPAN) & defined(DBCS_IME)
  1562. /* If IME Cnv window open,we have to avoid ourselves to get into AlphaMode.
  1563. ** So we do getmessage here to fill vmsgLast with app queue message.
  1564. */
  1565. extern BOOL bImeCnvOpen;
  1566. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  1567. if( bImeCnvOpen || vfImeHidden) {
  1568. #else
  1569. if( bImeCnvOpen ) {
  1570. #endif //JAPAN & IME_HIDDEN
  1571. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1572. donteat = TRUE;
  1573. return TRUE;
  1574. }
  1575. #endif
  1576. /*T-HIROYN sync 3.1 disp.c */
  1577. #if 0
  1578. /* Filter uninteresting or easily handled events */
  1579. if (fToggledKey = FCheckToggleKeyMessage(&vmsgLast) ||
  1580. (vmsgLast.message == WM_KEYUP && vmsgLast.hwnd == wwdCurrentDoc.wwptr))
  1581. {
  1582. if (((vmsgLast.wParam == VK_MENU) || (vmsgLast.wParam == VK_CONTROL)))
  1583. return TRUE;
  1584. #endif
  1585. #ifdef JAPAN // 03/22/93
  1586. #ifdef PENWIN // 03/22/93
  1587. if (((vmsgLast.message == WM_KEYDOWN) || (vmsgLast.message == WM_KEYUP)
  1588. || (vmsgLast.message == WM_SYSKEYDOWN) || (vmsgLast.message == WM_SYSKEYUP))
  1589. && ((vmsgLast.wParam == VK_MENU) || (vmsgLast.wParam == VK_CONTROL)))
  1590. #else //PENWIN
  1591. if (((vmsgLast.wParam == VK_MENU) || (vmsgLast.wParam == VK_CONTROL)))
  1592. #endif
  1593. #elif defined(KOREA)
  1594. #define VK_PROCESSKEY 0xE5 // New finalize message. bklee.
  1595. // bug #3191, In HWin3.1, WM_NCLBUTTONDOWN message is reached this if statement.
  1596. // Because HTBOTTOMDOWN's value is same with VK_CONTROL's, we can't resize write window
  1597. if (((vmsgLast.message == WM_KEYDOWN) || (vmsgLast.message == WM_KEYUP)
  1598. || (vmsgLast.message == WM_SYSKEYDOWN) || (vmsgLast.message == WM_SYSKEYUP))
  1599. && ((vmsgLast.wParam == VK_MENU) ||
  1600. (vmsgLast.wParam == VK_CONTROL) ||
  1601. (vmsgLast.wParam == VK_PROCESSKEY) ))
  1602. #else //JAPAN
  1603. if (((vmsgLast.wParam == VK_MENU) || (vmsgLast.wParam == VK_CONTROL)))
  1604. #endif
  1605. {
  1606. if (vmsgLast.wParam == VK_CONTROL)
  1607. {
  1608. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1609. SetShiftFlags();
  1610. }
  1611. return TRUE;
  1612. }
  1613. /* Filter uninteresting or easily handled events */
  1614. else if (fToggledKey = FCheckToggleKeyMessage(&vmsgLast) ||
  1615. (vmsgLast.message == WM_KEYUP && vmsgLast.hwnd == wwdCurrentDoc.wwptr))
  1616. {
  1617. /* This is so the Windows keyboard interface mechanism will see toggle
  1618. key and key-up transitions */
  1619. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1620. #ifdef WIN30
  1621. /* PeekMessage has been changed in Win 3.0 so that GetKeyState()
  1622. called from FCheckToggleKeyMessage() is really only valid if
  1623. you've done a PeekMessage(...,PM_REMOVE) or GetMessage() first.
  1624. That is, while the FCheckToggleKeyMessage() call might succeed
  1625. above, it will NOT have set the vfShiftKey/vfCommandKey flags
  1626. correctly -- so we do it here ..pault */
  1627. if (fToggledKey)
  1628. FCheckToggleKeyMessage(&vmsgLast);
  1629. #endif
  1630. if (vmsgLast.hwnd != wwdCurrentDoc.wwptr)
  1631. {
  1632. /* Just in case a modeless dialog's window proc cares */
  1633. TranslateMessage((LPMSG)&vmsgLast);
  1634. DispatchMessage((LPMSG)&vmsgLast);
  1635. }
  1636. #ifdef DBCS /* I hate it */
  1637. if (vmsgLast.message == WM_CHAR
  1638. #ifdef JAPAN
  1639. // We've been reported by one of OEM about LED not disapearing
  1640. // problem.
  1641. // they know it is bug of write. So I added this code from win2.x
  1642. // write source. 27 sep 91 Yutakan
  1643. || (vmsgLast.message == WM_KEYUP && vmsgLast.wParam == VK_KANA)
  1644. #endif
  1645. #ifdef KOREA
  1646. || vmsgLast.message == WM_INTERIM
  1647. #endif
  1648. || vmsgLast.message == WM_KEYDOWN) {
  1649. donteat = TRUE;
  1650. return( TRUE );
  1651. } /* else Ok, you are KEYUP message. do normal */
  1652. #endif
  1653. }
  1654. else
  1655. {
  1656. switch (vmsgLast.message)
  1657. {
  1658. case WM_MOUSEMOVE:
  1659. #ifdef KOREA
  1660. case WM_NCMOUSEMOVE:
  1661. #endif
  1662. /* Process mouse move messages immediately; they are not really
  1663. important. NOTE: This assumes that we have not captured all mouse
  1664. events; in which case, they are important. */
  1665. DispatchMessage((LPMSG)&vmsgLast);
  1666. case WM_TIMER:
  1667. case WM_SYSTIMER:
  1668. /* Remove timer and mouse move messages from the queue. */
  1669. GetMessage((LPMSG) &vmsgLast, NULL, NULL, NULL);
  1670. break;
  1671. default:
  1672. Assert( *(pLocalHeap+1) == 0 ); /* Heap should still not be frozen */
  1673. return (TRUE);
  1674. }
  1675. }
  1676. }
  1677. Assert( *(pLocalHeap + 1) == 0 ); /* Heap should still not be frozen */
  1678. return (FALSE);
  1679. }
  1680. /* C P B E G I N L I N E */
  1681. typeCP CpBeginLine(pdl, cp)
  1682. int *pdl;
  1683. typeCP cp;
  1684. { /* return the cp and dl containing cp */
  1685. int dlMin, dlLim;
  1686. typeCP cpGuess;
  1687. struct EDL *dndl;
  1688. do
  1689. {
  1690. UpdateWw(wwCur, false);
  1691. PutCpInWwVert(cp); /* Ensure cp on screen */
  1692. } while (pwwdCur->fDirty && !vfOutOfMemory);
  1693. dndl = &(**(pwwdCur->hdndl))[0];
  1694. dlMin = 0;
  1695. dlLim = pwwdCur->dlMac;
  1696. while (dlMin + 1 < dlLim)
  1697. { /* Binary search the ww */
  1698. int dlGuess = (dlMin + dlLim) >> 1;
  1699. struct EDL *pedl = &dndl[dlGuess];
  1700. if ((cpGuess = pedl->cpMin) <= cp && (cpGuess != cp || pedl->ichCpMin == 0))
  1701. { /* guess is low or right */
  1702. dlMin = dlGuess;
  1703. if (cp == cpGuess && pedl->cpMin + pedl->dcpMac != cp)
  1704. break; /* Got it right */
  1705. }
  1706. else /* Guess is high */
  1707. dlLim = dlGuess;
  1708. }
  1709. *pdl = dlMin;
  1710. return dndl[dlMin].cpMin;
  1711. }
  1712. /* T O G G L E S E L */
  1713. ToggleSel(cpFirst, cpLim, fOn)
  1714. typeCP cpFirst, cpLim; /* selection bounds */
  1715. int fOn;
  1716. { /* Flip selection highlighting on and off */
  1717. extern int vfPMS;
  1718. struct EDL *pedl;
  1719. int dlT;
  1720. int xpMin;
  1721. int dxpRoom;
  1722. int xpFirst;
  1723. int xpLim;
  1724. int fInsertPoint = (cpFirst == cpLim);
  1725. if (vfSelHidden || cpFirst > cpLim || cpLim < /*cp0*/ cpMinCur || vfDead)
  1726. return;
  1727. if ( vfPictSel && vfPMS &&
  1728. (CachePara( docCur, cpFirst ), vpapAbs.fGraphics) &&
  1729. (vcpLimParaCache == cpLim) )
  1730. { /* Don't show inversion if we're moving or sizing a picture */
  1731. return;
  1732. }
  1733. dxpRoom = pwwdCur->xpMac - xpSelBar;
  1734. xpMin = pwwdCur->xpMin;
  1735. for (dlT = 0; dlT < pwwdCur->dlMac; dlT++)
  1736. {
  1737. typeCP cpMin, cpMac; /* line bounds */
  1738. pedl = &(**(pwwdCur->hdndl))[dlT];
  1739. if (!pedl->fValid)
  1740. continue;
  1741. cpMin = pedl->cpMin;
  1742. if (cpMin > cpLim || cpMin > cpMacCur || (cpMin == cpLim && cpLim != cpFirst))
  1743. break;
  1744. cpMac = cpMin + pedl->dcpMac;
  1745. if (cpFirst <= cpMin && cpLim >= cpMac)
  1746. {
  1747. /* entire line is highlighted */
  1748. xpFirst = pedl->xpLeft;
  1749. if (pedl->fGraphics && cpLim == cpMac && cpMin == cpMac)
  1750. /* Special kludge for graphics paras */
  1751. xpLim = xpFirst;
  1752. else
  1753. xpLim = pedl->xpMac;
  1754. }
  1755. else if (fInsertPoint && cpFirst == cpMac && vfInsEnd)
  1756. { /* Special kludge for an insert point at the end of a line */
  1757. xpLim = xpFirst = pedl->xpMac;
  1758. }
  1759. else if (cpFirst < cpMac)
  1760. {
  1761. /* Bite the bullet */
  1762. int dxp;
  1763. typeCP cpBegin = CpMax(cpMin, cpFirst);
  1764. typeCP cpEnd = CpMin(cpMac, cpLim);
  1765. FormatLine(docCur, cpMin, pedl->ichCpMin, cpMacCur, flmSandMode);
  1766. dxp = DxpDiff((int) (cpBegin - cpMin),
  1767. (int) (cpEnd - cpBegin), &xpFirst);
  1768. xpLim = xpFirst + dxp;
  1769. /* reload pedl because procedures were called */
  1770. pedl = &(**(pwwdCur->hdndl))[dlT];
  1771. }
  1772. else
  1773. continue;
  1774. /* now we have: pedl valid, xpFirst, xpLast describe highlight */
  1775. /* xpFirst = max(xpFirst, xpMin); */
  1776. xpLim = min(xpLim, xpMin + pedl->xpMac);
  1777. if (xpLim > xpFirst)
  1778. {
  1779. if (xpLim > xpMin)
  1780. {
  1781. RECT rc;
  1782. rc.top = pedl->yp - pedl->dyp;
  1783. rc.left = xpSelBar + max(xpFirst - xpMin, 0);
  1784. rc.bottom = pedl->yp;
  1785. rc.right = xpSelBar + xpLim - xpMin;
  1786. InvertRect( wwdCurrentDoc.hDC, (LPRECT)&rc);
  1787. }
  1788. }
  1789. /* ToggleSel modified 7/28/85 -- added explicit check for fInsertPoint, since
  1790. the xpLim == xpFirst test sometimes succeeded bogusly when a selection
  1791. was extended backwards. BL */
  1792. else if (fInsertPoint && (xpLim == xpFirst)) /* Insertion point */
  1793. {
  1794. /* vfli should usually be cached already, so will be fast. */
  1795. int yp = pedl->yp;
  1796. FormatLine(docCur, cpMin, pedl->ichCpMin, cpMacCur, flmSandMode);
  1797. if (fOn ^ vfInsertOn)
  1798. {
  1799. if (!vfInsertOn)
  1800. {
  1801. vxpCursLine = xpSelBar + xpFirst - xpMin;
  1802. vypCursLine = yp - vfli.dypAfter;
  1803. vdypCursLine = min(vfli.dypFont, vfli.dypLine - vfli.dypAfter);
  1804. /* Start blinking in a while */
  1805. vfSkipNextBlink = TRUE;
  1806. }
  1807. DrawInsertLine();
  1808. }
  1809. return;
  1810. }
  1811. }
  1812. }
  1813. /* T R A S H W W */
  1814. TrashWw(ww)
  1815. { /* Invalidate all dl's in ww */
  1816. Assert( ww >= 0 && ww < wwMax );
  1817. InvalBand(&rgwwd[ww], 0, ypMaxAll);
  1818. }
  1819. /* I N V A L B A N D */
  1820. /* invalidate the band ypFirst, ypLast inclusive */
  1821. InvalBand(pwwd, ypFirst, ypLast)
  1822. struct WWD *pwwd; int ypFirst, ypLast;
  1823. {
  1824. /* this covers some peculiar rects received from update event after a
  1825. window resize by 1 pixel. CS */
  1826. if (ypLast < 0 || ypFirst == ypLast) return;
  1827. pwwd->fDirty = true;
  1828. pwwd->ypFirstInval = min(pwwd->ypFirstInval, ypFirst);
  1829. pwwd->ypLastInval = max(ypLast, pwwd->ypLastInval);
  1830. }
  1831. /* T R A S H A L L W W S */
  1832. TrashAllWws()
  1833. { /* trash them all */
  1834. int ww;
  1835. #ifdef CASHMERE
  1836. for (ww = 0; ww < wwMac; ++ww)
  1837. TrashWw(ww);
  1838. #else
  1839. TrashWw( wwDocument );
  1840. #endif
  1841. vfli.doc = docNil; /* Mark vfli invalid */
  1842. }
  1843. /* T U R N O F F S E L */
  1844. TurnOffSel()
  1845. { /* Remove sel highlighting from screen */
  1846. /* HideSel has no effect */
  1847. if (!vfSelHidden)
  1848. {
  1849. ToggleSel(selCur.cpFirst, selCur.cpLim, false);
  1850. vfSelHidden = true;
  1851. }
  1852. }
  1853. #ifdef JAPAN
  1854. /* We handle IME convert window. */
  1855. //int FontHeight = 0; 01/19/93
  1856. // 03/29/93 int ImePosSize = 0; //01/19/93
  1857. int ImePosSize = 256; //03/29/93 #5484
  1858. BOOL bGetFocus = FALSE;
  1859. // Handle to the IME communication block - 061491 Yukini
  1860. HANDLE hImeMem = NULL;
  1861. // to prevent unwanted caret traveling - 061591 Yukini
  1862. BOOL bForceBlock = FALSE;
  1863. // To avoid ilreagal setting for IME rectangle
  1864. static BOOL bResetIMERect=FALSE;
  1865. static BOOL bDefaultBlock = FALSE; //IME3.1J t-hiroyn
  1866. /*
  1867. * ForceImeBlock controls IME input display to the screen.
  1868. * When Write program is writing string to the screen, the caret
  1869. * doesn't move with string. After completing text display,
  1870. * then caret is moved to appropriate position. During this
  1871. * period, if user type something by using IME, char is displayed on the
  1872. * screen. This makes mixing ugly result. This routine will
  1873. * prevent this. Yukini
  1874. */
  1875. void ForceImeBlock( hWnd, bFlag )
  1876. HWND hWnd;
  1877. BOOL bFlag;
  1878. {
  1879. WORD x, y;
  1880. LPIMESTRUCT lpmem;
  1881. if (bForceBlock = bFlag) {
  1882. if (lpmem = (LPIMESTRUCT)GlobalLock(hImeMem)) {
  1883. /* Move bounding rectangle to out of the world */
  1884. lpmem->fnc = IME_MOVECONVERTWINDOW;
  1885. x = GetSystemMetrics(SM_CXSCREEN);
  1886. y = GetSystemMetrics(SM_CYSCREEN);
  1887. lpmem->wParam = MCW_SCREEN | MCW_RECT;
  1888. #if 1 //01/19/93
  1889. lpmem->lParam1 = (DWORD)MAKELONG(x+x/2,y+y/2);
  1890. lpmem->lParam2 = (DWORD)MAKELONG(x+x/2,y+y/2);
  1891. lpmem->lParam3 = (DWORD)MAKELONG(x*2,y*2);
  1892. #else
  1893. lpmem->lParam1 = (DWORD)MAKELONG(x+1,y+1);
  1894. lpmem->lParam2 = (DWORD)MAKELONG(x+1,y+1);
  1895. lpmem->lParam3 = (DWORD)MAKELONG(x*2,y*2);
  1896. #endif
  1897. GlobalUnlock(hImeMem);
  1898. MySendIMEMessageEx(hWnd,MAKELONG(hImeMem,NULL));
  1899. bResetIMERect = FALSE;
  1900. }
  1901. }
  1902. }
  1903. void DefaultImeBlock(hWnd)
  1904. HWND hWnd;
  1905. {
  1906. LPIMESTRUCT lpmem;
  1907. if (bDefaultBlock == FALSE) {
  1908. if (lpmem = (LPIMESTRUCT)GlobalLock(hImeMem)) {
  1909. /* Move bounding rectangle to default */
  1910. lpmem->fnc = IME_MOVECONVERTWINDOW;
  1911. lpmem->wParam = MCW_DEFAULT;
  1912. GlobalUnlock(hImeMem);
  1913. MySendIMEMessageEx(hWnd,MAKELONG(hImeMem,NULL));
  1914. bResetIMERect = FALSE;
  1915. }
  1916. }
  1917. }
  1918. /* use these veriables to optimize IME call. This will prevent task switching
  1919. * overhead. - Yukini
  1920. */
  1921. static RECT rcOldRect = {-1, -1, -1, -1};
  1922. static DWORD dwCurpos = -1;
  1923. static WORD wModeMCW = MCW_DEFAULT;
  1924. void SetIMEConvertWindow(hWnd,x,y,bFlag)
  1925. HWND hWnd;
  1926. int x,y;
  1927. BOOL bFlag;
  1928. {
  1929. LPIMESTRUCT lpmem;
  1930. //Yukini:HANDLE hIMEBlock;
  1931. DWORD dwXY = MAKELONG(x,y);
  1932. BOOL bRetSendIme;
  1933. RECT rcRect;
  1934. extern BOOL bImeCnvOpen; // Yutakan:08/06/91
  1935. /* Do nothing if in text drawing to the screen */
  1936. if (bForceBlock)
  1937. return;
  1938. /* we allocate the Ime communication area. freeing of this
  1939. * area will be done by wrap up routine MmwDestroy() of Quit.C.
  1940. * This will improve the performance than previous code. - Yukini
  1941. */
  1942. if (hImeMem == NULL) {
  1943. if ((hImeMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE|GMEM_LOWER,
  1944. (DWORD)sizeof(IMESTRUCT))) == NULL)
  1945. return; // something wrong
  1946. }
  1947. //Yukini: /* Get comunication area with IME */
  1948. //Yukini: hIMEBlock=GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_LOWER,
  1949. //Yukini: (DWORD)sizeof(IMESTRUCT));
  1950. //Yukini: if(!hIMEBlock) return;
  1951. if(!bGetFocus)
  1952. bFlag = FALSE;
  1953. GetWindowRect(hWnd,&rcRect);
  1954. // [yutakan:08/06/91] IF out of Window Rect, force MCW_DEFAULT.
  1955. // if(rcRect.top > y || rcRect.bottom < y) bFlag = TRUE;
  1956. //
  1957. if (bFlag) {
  1958. /* Add ResetIMERect check . If we've not done MOVECONVERTWINDOW after
  1959. ** ForceIMEblock(), don't pass by SendIMEMessage to avoid ilreagal setting
  1960. ** for bounding rectangle. [Yutakan.]
  1961. */
  1962. // bResetIMERect FALSE when just after ForceImeBlock()
  1963. if ( bResetIMERect == TRUE
  1964. && dwCurpos == dwXY && EqualRect(&rcRect, &rcOldRect)){
  1965. //OutputDebugString("Write:optimized\r\n");
  1966. return;
  1967. }
  1968. } else
  1969. dwCurpos = -1; // invalidate cache
  1970. //Yukini: lpmem = (LPIMESTRUCT)GlobalLock(hIMEBlock);
  1971. //Yukini: lpmem->fnc = IME_MOVECONVERTWINDOW;
  1972. //Yukini: lpmem->wParam = bFlag?MCW_WINDOW:MCW_DEFAULT;
  1973. //Yukini: lpmem->lParam1 = (DWORD)MAKELONG(x,y);
  1974. //Yukini: GlobalUnlock(hIMEBlock);
  1975. //Yukini: SendIMEMessage(hWnd,MAKELONG(hIMEBlock,NULL));
  1976. //Yukini: GlobalFree(hIMEBlock);
  1977. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  1978. if(vfImeHidden) {
  1979. DWORD dwXY1, dwXY2, dwXY3;
  1980. int x1,x2,x3,y1,y2,y3;
  1981. RECT hiRect;
  1982. //12/28/92
  1983. if(whileUndetermine == TRUE) // we are managing IR_UNDETERMINE
  1984. return;
  1985. CopyRect(&hiRect, &rcRect);
  1986. if(x < 0) x = 0;
  1987. x1 = x + hiRect.left;
  1988. y1 = (vypCursLine - vdypCursLine) + hiRect.top;
  1989. if(y1 < 0) y1 = 0;
  1990. x2 = hiRect.left;
  1991. if(HiddenTextTop == 0)
  1992. y2 = y1;
  1993. else
  1994. y2 = hiRect.top + HiddenTextTop;
  1995. x3 = hiRect.right;
  1996. if(vdypCursLine <= 0)
  1997. y3 = y1 + (19+1);
  1998. else {
  1999. if(HiddenTextBottom == 0)
  2000. y3 = y1 + (vdypCursLine+1);
  2001. else
  2002. y3 = hiRect.top + HiddenTextBottom + 1;
  2003. if(y3 < (y1 + (vdypCursLine+1)))
  2004. y3 = y1 + (vdypCursLine+1);
  2005. }
  2006. if(y2 > y1)
  2007. y2 = y1;
  2008. if(x3 <= x1 || y3 <= y1)
  2009. goto dontHidden;
  2010. if(x3 <= x2 || y3 <= y2)
  2011. goto dontHidden;
  2012. dwXY1 = MAKELONG(x1, y1);
  2013. dwXY2 = MAKELONG(x2, y2);
  2014. dwXY3 = MAKELONG(x3, y3);
  2015. if (lpmem = (LPIMESTRUCT)GlobalLock(hImeMem)) {
  2016. lpmem->fnc = IME_MOVECONVERTWINDOW;
  2017. lpmem->wParam = MCW_HIDDEN;
  2018. dwCurpos = dwXY;
  2019. CopyRect(&rcOldRect, &rcRect);
  2020. lpmem->lParam1 = dwXY1;
  2021. lpmem->lParam2 = dwXY2;
  2022. lpmem->lParam3 = dwXY3;
  2023. GlobalUnlock(hImeMem);
  2024. bResetIMERect = TRUE;
  2025. if(MySendIMEMessageEx(hWnd,MAKELONG(hImeMem,NULL))) {
  2026. vfImeHidden = 1; //Hidden OK
  2027. return;
  2028. } else {
  2029. vfImeHidden = 0; //Hidden ERR we set MCW_WINDOW
  2030. }
  2031. }
  2032. }
  2033. dontHidden:
  2034. if(selUncpLim > selUncpFirst) {
  2035. return;
  2036. }
  2037. #endif
  2038. if (lpmem = (LPIMESTRUCT)GlobalLock(hImeMem)) {
  2039. lpmem->fnc = IME_MOVECONVERTWINDOW;
  2040. if ((lpmem->wParam = bFlag ? MCW_WINDOW : MCW_DEFAULT) == MCW_WINDOW) {
  2041. /* update previous state */
  2042. dwCurpos = dwXY;
  2043. CopyRect(&rcOldRect, &rcRect);
  2044. lpmem->lParam1 = dwXY;
  2045. wModeMCW = MCW_WINDOW; //01/25/93
  2046. } else {
  2047. wModeMCW = MCW_DEFAULT; //01/25/93
  2048. }
  2049. GlobalUnlock(hImeMem);
  2050. if(FALSE == MySendIMEMessageEx(hWnd,MAKELONG(hImeMem,NULL)))
  2051. wModeMCW = MCW_DEFAULT; //01/25/93
  2052. bResetIMERect = TRUE; // yutakan:08/06/91
  2053. }
  2054. }
  2055. HANDLE hImeSetFont = NULL;
  2056. BOOL bImeFontEx = FALSE; //T-HIROYN 02/25/93
  2057. SetImeFont(HWND hWnd)
  2058. {
  2059. LPIMESTRUCT lpmem;
  2060. HANDLE hImeLogfont;
  2061. LOGFONT lf;
  2062. LPLOGFONT lpLogfont;
  2063. HANDLE hfont;
  2064. void IMEManage(BOOL);
  2065. //Get IME use LOGFONT
  2066. if (FALSE == GetLogfontImeFont((LPLOGFONT)(&lf)))
  2067. return;
  2068. if(TRUE == bImeFontEx) {
  2069. if ((hImeLogfont = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_LOWER,
  2070. (DWORD)sizeof(LOGFONT))) == NULL)
  2071. return; // something wrong
  2072. if (lpmem = (LPIMESTRUCT)GlobalLock(hImeMem)) {
  2073. lpmem->fnc = IME_SETCONVERSIONFONTEX;
  2074. lpmem->lParam1 = 0L;
  2075. if (lpLogfont = (LPLOGFONT)GlobalLock(hImeLogfont)) {
  2076. bltbx((LPLOGFONT)(&lf), lpLogfont, sizeof(LOGFONT));
  2077. lpmem->lParam1 = MAKELONG(hImeLogfont,NULL);
  2078. GlobalUnlock(hImeLogfont);
  2079. }
  2080. GlobalUnlock(hImeMem);
  2081. MySendIMEMessageEx(hWnd,MAKELONG(hImeMem,NULL));
  2082. }
  2083. GlobalFree(hImeLogfont);
  2084. } else {
  2085. hfont = CreateFontIndirect(&lf);
  2086. if (lpmem = (LPIMESTRUCT)GlobalLock(hImeMem)) {
  2087. lpmem->fnc = IME_SETCONVERSIONFONT;
  2088. lpmem->wParam = hfont;
  2089. GlobalUnlock(hImeMem);
  2090. MySendIMEMessageEx(hWnd,MAKELONG(hImeMem,NULL));
  2091. }
  2092. // prev font deleate;
  2093. if(hImeSetFont != NULL) {
  2094. HDC hdc;
  2095. HANDLE oldhfont;
  2096. hdc = GetDC(NULL);
  2097. oldhfont = SelectObject(hdc,hImeSetFont);
  2098. SelectObject(hdc,oldhfont);
  2099. DeleteObject(hImeSetFont);
  2100. ReleaseDC(NULL, hdc);
  2101. }
  2102. hImeSetFont = hfont;
  2103. }
  2104. //display:
  2105. bResetIMERect = FALSE;
  2106. IMEManage( FALSE );
  2107. }
  2108. int GetLogfontImeFont(lplf)
  2109. LPLOGFONT lplf;
  2110. {
  2111. extern struct FCE *vpfceScreen;
  2112. extern struct CHP vchpSel;
  2113. struct CHP chp;
  2114. blt(&vchpSel, &chp, cwCHP); /* CHP for use in comparisons */
  2115. //change CHARSET to KANJI_CHARSET
  2116. {
  2117. int ftc;
  2118. if( ftcNil != (ftc = GetKanjiFtc(&chp))) {
  2119. ApplyCLooks(&chp, sprmCFtc, ftc);
  2120. }
  2121. }
  2122. LoadFont(docCur, &chp, mdFontJam);
  2123. bltbcx(lplf, 0, sizeof(LOGFONT));
  2124. GetObject(vpfceScreen->hfont, sizeof(LOGFONT), lplf);
  2125. //Ime SETCONVERSIONWINDOW set point (vypCursLine - ImePosSize)
  2126. ImePosSize = vfmiScreen.dypBaseline + vfli.dypBase;
  2127. if(chp.hpsPos != 0 ) {
  2128. if (chp.hpsPos < hpsNegMin)
  2129. ImePosSize += ypSubSuper;
  2130. else
  2131. ImePosSize -= ypSubSuper;
  2132. }
  2133. return TRUE;
  2134. }
  2135. void
  2136. IMEManage( bFlag )
  2137. BOOL bFlag; /* Flag to indicate real default or virtual default in case
  2138. of requesting IME convert line to be default. Real default
  2139. (value TRUE) is selected when I am loosing the focus. In
  2140. this case, IME convert line will be default. Virtual
  2141. default (value FALSE) is selected when I lost a caret
  2142. position. In this case, IME convert line will be out of
  2143. the screen. You can type characters, but not displayed
  2144. to the screen correctly. Yukini
  2145. */
  2146. {
  2147. int x,y;
  2148. BOOL bCE = ConvertEnable;
  2149. /*IME3.1J
  2150. if(!FontHeight)
  2151. {
  2152. TEXTMETRIC tm;
  2153. GetTextMetrics(wwdCurrentDoc.hDC,&tm);
  2154. FontHeight = tm.tmHeight;
  2155. }
  2156. */
  2157. x = vxpCursLine;
  2158. // y = vypCursLine-(vdypCursLine+FontHeight)/2; IME3.1J
  2159. // y = vypCursLine - FontHeight;
  2160. if(ImePosSize > vdypCursLine)
  2161. y = vypCursLine - vdypCursLine;
  2162. else
  2163. y = vypCursLine - ImePosSize;
  2164. if (x < 0 || y < 0)
  2165. bCE = FALSE; /* Sometime caret position will be
  2166. less than zero. Do no set IME
  2167. window in this case. Yukini */
  2168. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  2169. if (bCE == FALSE && bFlag == FALSE && bForceBlock == FALSE
  2170. && 0 == vfImeHidden) {
  2171. #else
  2172. if (bCE == FALSE && bFlag == FALSE && bForceBlock == FALSE) {
  2173. #endif
  2174. // get out of the world, babe.
  2175. //IME3.1J
  2176. if( vypCursLine > 0 && ImePosSize > vypCursLine ) {
  2177. DefaultImeBlock( wwdCurrentDoc.wwptr); //t-hiroyn
  2178. bDefaultBlock = TRUE; //IME3.1J
  2179. } else {
  2180. ForceImeBlock( wwdCurrentDoc.wwptr, TRUE );
  2181. bForceBlock = FALSE;
  2182. bDefaultBlock = FALSE; //IME3.1J
  2183. }
  2184. // yutakan:08/16/91 dwCurpos = 1; // invalidate optimize cache
  2185. dwCurpos = -1;
  2186. } else {
  2187. SetIMEConvertWindow(wwdCurrentDoc.wwptr, x, y, bCE);
  2188. bDefaultBlock = FALSE; //IME3.1J
  2189. }
  2190. }
  2191. #endif // JAPAN
  2192. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  2193. //IME3.1J call by MENU selecting.
  2194. ChangeImeConversionMode()
  2195. {
  2196. extern BOOL bImeCnvOpen;
  2197. vfImeHidden = (vfImeHidden ? 0 : 1);
  2198. // 12/28/92 if(vfImeHidden)
  2199. // bImeCnvOpen = TRUE;
  2200. bResetIMERect = FALSE;
  2201. IMEManage( FALSE );
  2202. }
  2203. #endif
  2204. /* D R A W I N S E R T L I N E */
  2205. DrawInsertLine()
  2206. {
  2207. #if defined(JAPAN) & defined(DBCS_IME)
  2208. extern BOOL bImeCnvOpen;
  2209. #if defined(IME_HIDDEN)
  2210. extern BOOL ImeClearInsert;
  2211. #endif
  2212. #endif
  2213. /* Draw (in Xor mode) a vertical bar at screen position v*CursLine */
  2214. /* Toggles both the display and the vfInsertOn flag */
  2215. /* Adjustments in cursor draw must be reflected in DisplayFli, above */
  2216. /* Last-minute correction for a bug: assure that the insert line
  2217. does not extend above ypMin */
  2218. if (!vfInsertOn && vdypCursLine > vypCursLine - wwdCurrentDoc.ypMin)
  2219. vdypCursLine = vypCursLine - wwdCurrentDoc.ypMin;
  2220. /* Tell GDI to invert the caret line */
  2221. //#3221 01/25/93
  2222. #if defined(JAPAN) & defined(DBCS_IME)
  2223. #if defined(IME_HIDDEN)
  2224. if(ImeClearInsert || (bImeCnvOpen && wModeMCW == MCW_WINDOW) ) {
  2225. #else
  2226. if(bImeCnvOpen && wModeMCW == MCW_WINDOW) {
  2227. #endif
  2228. if(vfInsertOn) {
  2229. PatBlt( wwdCurrentDoc.hDC, vxpCursLine,
  2230. vypCursLine - vdypCursLine, 2, vdypCursLine , DSTINVERT );
  2231. vfInsertOn = 1 - vfInsertOn;
  2232. }
  2233. } else {
  2234. PatBlt( wwdCurrentDoc.hDC, vxpCursLine,
  2235. vypCursLine - vdypCursLine, 2, vdypCursLine , DSTINVERT );
  2236. vfInsertOn = 1 - vfInsertOn;
  2237. }
  2238. #else
  2239. PatBlt( wwdCurrentDoc.hDC, vxpCursLine, vypCursLine - vdypCursLine,
  2240. 2, vdypCursLine , DSTINVERT );
  2241. vfInsertOn = 1 - vfInsertOn;
  2242. #endif
  2243. /*T-HIROYN sync 3.0 disp.c */
  2244. #ifdef JAPAN /* KenjiK '90-10-30 */
  2245. if(bClearCall)
  2246. {
  2247. if((vxpCursLine>=0) && (vxpCursLine<=wwdCurrentDoc.xpMac)
  2248. && (vypCursLine>=0) && (vypCursLine<=wwdCurrentDoc.ypMac))
  2249. ConvertEnable = TRUE;
  2250. }
  2251. IMEManage( FALSE );
  2252. #endif
  2253. }
  2254. /* C L E A R I N S E R T L I N E */
  2255. ClearInsertLine()
  2256. {
  2257. #if defined(JAPAN) & defined(DBCS_IME)
  2258. /* So we do some IME manage when clearning the line */
  2259. if((vxpCursLine<0) || (vxpCursLine>=wwdCurrentDoc.xpMac)
  2260. || (vypCursLine<0) || (vypCursLine>=wwdCurrentDoc.ypMac)) {
  2261. ConvertEnable = FALSE;
  2262. //OutputDebugString("ClearInsertLine\r\n");
  2263. }
  2264. bClearCall = FALSE;
  2265. if ( vfInsertOn) DrawInsertLine();
  2266. else IMEManage( FALSE );
  2267. bClearCall = TRUE;
  2268. #else
  2269. if ( vfInsertOn) DrawInsertLine();
  2270. #endif
  2271. }
  2272. #if defined(JAPAN) & defined(IME_HIDDEN) //IME3.1J
  2273. UndetermineTextOut(HDC hDC, int xp, int yp, PCH ptr, int cch, LPSTR Attrib)
  2274. {
  2275. int Length;
  2276. long rgbBack;
  2277. long rgbText;
  2278. int bkMode;
  2279. PCH ptr1 = ptr;
  2280. TEXTMETRIC tm;
  2281. GetTextMetrics(hDC, &tm);
  2282. bkMode = SetBkMode(hDC, OPAQUE);
  2283. rgbBack = GetBkColor(hDC);
  2284. rgbText = GetTextColor(hDC);
  2285. while( cch ) {
  2286. switch((*Attrib) & 0x03)
  2287. {
  2288. case 1:
  2289. SetBkColor(hDC,
  2290. GetNearestColor(hDC, rgbIMEHidden[IMESPOT]));
  2291. SetTextColor(hDC,
  2292. GetNearestColor(hDC, rgbIMEHidden[IMESPOTTEXT]));
  2293. // 12/28/92
  2294. if(HiddenTextTop == 0)
  2295. HiddenTextTop = yp;
  2296. if(HiddenTextTop > yp)
  2297. HiddenTextTop = yp;
  2298. if(HiddenTextBottom == 0)
  2299. HiddenTextBottom = yp + tm.tmHeight;
  2300. if(HiddenTextBottom > (yp + tm.tmHeight))
  2301. HiddenTextBottom = yp + tm.tmHeight;
  2302. break;
  2303. case 0:
  2304. SetBkColor(hDC,
  2305. GetNearestColor(hDC, rgbIMEHidden[IMEINPUT]));
  2306. SetTextColor(hDC,
  2307. GetNearestColor(hDC, rgbIMEHidden[IMEINPUTTEXT]));
  2308. break;
  2309. case 2:
  2310. default:
  2311. SetBkColor(hDC,
  2312. GetNearestColor(hDC, rgbIMEHidden[IMEOTHER]));
  2313. SetTextColor(hDC,
  2314. GetNearestColor(hDC, rgbIMEHidden[IMEOTHERTEXT]));
  2315. break;
  2316. }
  2317. Length = ( (IsDBCSLeadByte((BYTE)(*ptr1)) ) ? 2 : 1 );
  2318. TextOut(hDC, xp, yp, ptr1, Length);
  2319. xp += LOWORD(GetTextExtent(hDC, ptr1, Length));
  2320. xp-=tm.tmOverhang;
  2321. ptr1+=Length;
  2322. Attrib+=Length;
  2323. AttribPos+=Length;
  2324. cch-=Length;
  2325. }
  2326. SetBkColor(hDC,rgbBack);
  2327. SetTextColor(hDC,rgbText);
  2328. SetBkMode(hDC, bkMode);
  2329. }
  2330. UndetermineString(HDC hDC, int xp, int yp, PCH ptr, int cch, typeCP cpFirst,
  2331. typeCP cpEnd)
  2332. {
  2333. int Length;
  2334. int len = cch;
  2335. PCH ptr1;
  2336. TEXTMETRIC tm;
  2337. GetTextMetrics(hDC, &tm);
  2338. ptr1 = ptr;
  2339. if((cpEnd <= selUncpFirst) || (cpFirst >= selUncpLim))
  2340. TextOut(hDC, xp, yp, ptr1, len);
  2341. else {
  2342. Attrib = GlobalLock(hImeUnAttrib);
  2343. if(cpFirst < selUncpFirst) {
  2344. Length = selUncpFirst - cpFirst;
  2345. TextOut(hDC, xp, yp, ptr1, Length);
  2346. xp+=LOWORD(GetTextExtent(hDC, ptr1, Length));
  2347. xp-=tm.tmOverhang;
  2348. len-=Length;
  2349. ptr1+=Length;
  2350. }
  2351. if(selUncpLim <= cpEnd) {
  2352. if(cpFirst > selUncpFirst) {
  2353. Length = (int)(selUncpLim - cpFirst);
  2354. Attrib += (cpFirst-selUncpFirst);
  2355. }
  2356. else {
  2357. Length = (int)(selUncpLim - selUncpFirst);
  2358. }
  2359. UndetermineTextOut(hDC, xp, yp, ptr1, Length, Attrib);
  2360. AttribPos = 0;
  2361. xp+=LOWORD(GetTextExtent(hDC, ptr1, Length));
  2362. xp-=tm.tmOverhang;
  2363. ptr1+=Length;
  2364. len-=Length;
  2365. if ( Length = (int)(cpEnd - selUncpLim) ) {
  2366. TextOut(hDC, xp, yp, ptr1, Length);
  2367. }
  2368. }
  2369. else if(Attrib) {
  2370. if(cpFirst > selUncpFirst) {
  2371. Attrib += (cpFirst-selUncpFirst);
  2372. }
  2373. UndetermineTextOut(hDC, xp, yp, ptr1,len, Attrib);
  2374. }
  2375. GlobalUnlock(hImeUnAttrib);
  2376. Attrib = NULL;
  2377. }
  2378. }
  2379. DoHiddenRectSend()
  2380. {
  2381. bResetIMERect = FALSE;
  2382. IMEManage( FALSE );
  2383. }
  2384. GetImeHiddenTextColors()
  2385. {
  2386. COLORREF NEAR PASCAL GetIMEColor(WORD);
  2387. int i;
  2388. for (i = 0; i < IMEDEFCOLORS; i++)
  2389. rgbIMEHidden[i] = GetIMEColor(i);
  2390. }
  2391. /*
  2392. GetIMEColor -
  2393. Retrieve IME color scheme from [colors] in win.ini
  2394. */
  2395. #define MAX_SCHEMESIZE 190
  2396. COLORREF NEAR PASCAL GetIMEColor(WORD wIndex)
  2397. {
  2398. static char *pszWinStrings[IMEDEFCOLORS] = {
  2399. "IMESpot",
  2400. "IMESpotText",
  2401. "IMEInput",
  2402. "IMEInputText",
  2403. "IMEOther",
  2404. "IMEOtherText"};
  2405. BYTE szTemp[MAX_SCHEMESIZE];
  2406. LPBYTE szLP;
  2407. COLORREF colRGB;
  2408. int i, v;
  2409. if (wIndex >= IMEDEFCOLORS)
  2410. return RGB(0,0,0);
  2411. GetProfileString("colors",
  2412. pszWinStrings[wIndex],
  2413. "",
  2414. szTemp,
  2415. MAX_SCHEMESIZE);
  2416. if (!lstrlen(szTemp)) {
  2417. switch(wIndex) {
  2418. case IMESPOT:
  2419. return GetSysColor(COLOR_HIGHLIGHTTEXT);
  2420. case IMESPOTTEXT:
  2421. return GetSysColor(COLOR_HIGHLIGHT);
  2422. case IMEINPUT:
  2423. return GetSysColor(COLOR_WINDOW);
  2424. case IMEINPUTTEXT:
  2425. return GetSysColor(COLOR_HIGHLIGHT);
  2426. case IMEOTHER:
  2427. return GetSysColor(COLOR_WINDOW);
  2428. case IMEOTHERTEXT:
  2429. return GetSysColor(COLOR_HIGHLIGHT);
  2430. }
  2431. }
  2432. colRGB = RGB(0,0,0);
  2433. szLP = szTemp;
  2434. for (i = 0; i < 3; i++) {
  2435. v = 0;
  2436. while(*szLP < '0' || *szLP > '9') szLP++;
  2437. while(*szLP >= '0' && *szLP <= '9') v = v * 10 + (*szLP++ - '0');
  2438. switch(i) {
  2439. case 0:
  2440. colRGB |= RGB(v,0,0);
  2441. break;
  2442. case 1:
  2443. colRGB |= RGB(0,v,0);
  2444. break;
  2445. case 2:
  2446. colRGB |= RGB(0,0,v);
  2447. break;
  2448. }
  2449. }
  2450. return colRGB;
  2451. }
  2452. #endif