Source code of Windows XP (NT5)
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.

512 lines
18 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* These routines are the guts of the text print code. */
  5. #define NOGDICAPMASKS
  6. #define NOVIRTUALKEYCODES
  7. #define NOWINMESSAGES
  8. #define NOWINSTYLES
  9. #define NOSYSMETRICS
  10. #define NOICON
  11. #define NOKEYSTATE
  12. #define NOSYSCOMMANDS
  13. #define NOSHOWWINDOW
  14. #define NOATOM
  15. #define NOFONT
  16. #define NOBRUSH
  17. #define NOCLIPBOARD
  18. #define NOCOLOR
  19. #define NOCREATESTRUCT
  20. #define NOCTLMGR
  21. #define NODRAWTEXT
  22. #define NOMB
  23. #define NOOPENFILE
  24. #define NOPEN
  25. #define NOREGION
  26. #define NOSCROLL
  27. #define NOSOUND
  28. #define NOWH
  29. #define NOWINOFFSETS
  30. #define NOWNDCLASS
  31. #define NOCOMM
  32. #include <windows.h>
  33. #include "mw.h"
  34. #include "printdef.h"
  35. #include "fmtdefs.h"
  36. #include "propdefs.h"
  37. #include "fontdefs.h"
  38. #include "docdefs.h"
  39. #define NOKCCODES
  40. #include "ch.h"
  41. #include "debug.h"
  42. #include "str.h"
  43. #if defined(JAPAN) || defined(KOREA) // added 01 Jul. 1992 by Hiraisi
  44. #include "kanji.h"
  45. #endif
  46. BOOL FPrintBand(doc, hrgpld, cpld, prcBand)
  47. int doc;
  48. struct PLD (**hrgpld)[];
  49. int cpld;
  50. PRECT prcBand;
  51. {
  52. /* This routine prints the lines in document doc that any part of which fall
  53. in the rectange *prcBand. The first cpld print line descriptors in hrgpld
  54. describe the current page in the document that will be printed. TRUE is
  55. returned if the band is printed, FALSE otherwise. */
  56. void PrintGraphics(int, int);
  57. void near PrintFli(int, int);
  58. extern struct DOD (**hpdocdod)[];
  59. extern struct FLI vfli;
  60. extern int vfOutOfMemory;
  61. extern FARPROC lpFPrContinue;
  62. int ipld;
  63. typeCP cpMac = (**hpdocdod)[doc].cpMac;
  64. for (ipld = 0; ipld < cpld; ipld++)
  65. {
  66. register struct PLD *ppld;
  67. /* Check for user cancellation. */
  68. if (!(*lpFPrContinue)(NULL, wNotSpooler))
  69. {
  70. return (FALSE);
  71. }
  72. /* Is this line within the band? */
  73. ppld = &(**hrgpld)[ipld];
  74. if (ppld->rc.top < prcBand->bottom && ppld->rc.bottom > prcBand->top &&
  75. ppld->rc.left < prcBand->right && ppld->rc.right > prcBand->left)
  76. {
  77. /* Format this line for the printer. */
  78. FormatLine(doc, ppld->cp, ppld->ichCp, cpMac, flmPrinting);
  79. /* If memory failure occurred, then punt. */
  80. if (vfOutOfMemory)
  81. {
  82. return (FALSE);
  83. }
  84. /* Reset the pointer to the print line descriptors (possible heap
  85. movement in FormatLine()). */
  86. ppld = &(**hrgpld)[ipld];
  87. /* Print this line. */
  88. if (vfli.fGraphics)
  89. {
  90. PrintGraphics(ppld->rc.left, ppld->rc.top);
  91. }
  92. else
  93. {
  94. PrintFli(ppld->rc.left, ppld->rc.top);
  95. }
  96. }
  97. }
  98. return (TRUE);
  99. }
  100. void near PrintFli(xpPrint, ypPrint)
  101. int xpPrint;
  102. int ypPrint;
  103. {
  104. /* This routine prints the line of text stored in the vfli structure at
  105. position (xpPrint, ypPrint). */
  106. #ifdef KOREA // jinwoo: 92, 9, 28
  107. /* process Subscript separatedly from descent 920605 KDLEE*/
  108. extern int isSubs;
  109. #endif /* KOREA */
  110. extern HDC vhDCPrinter;
  111. extern struct FLI vfli;
  112. extern struct DOD (**hpdocdod)[];
  113. extern struct CHP (**vhgchpFormat)[];
  114. extern int dxpPrPage;
  115. extern int dypPrPage;
  116. extern int ypSubSuperPr;
  117. extern CHAR stBuf[];
  118. extern struct FMI vfmiPrint;
  119. extern typeCP cpMinDocument;
  120. extern int vpgn;
  121. int dcp;
  122. int dxp; /* Width of current run */
  123. int dxpExtra; /* Width of pad for each space */
  124. int yp; /* Y-coordinate to print at. */
  125. struct CHP *pchp; /* CHP associated with the current run */
  126. BOOL fTabsKludge = (vfli.ichLastTab >= 0);
  127. int cBreakRun; /* break characters in run (no relation to Dick or Jane) */
  128. #if defined(JAPAN) || defined(KOREA) // added 04 Jul. 1992 by Hiraisi
  129. extern struct PAP vpapAbs;
  130. extern int vfWordWrap; /* WordWrap flag : TRUE=ON, FALSE=OFF */
  131. extern int iNonWideSpaces;
  132. int iRun;
  133. #endif
  134. Scribble(5,'P');
  135. Assert(vhDCPrinter);
  136. pchp = &(**vhgchpFormat)[0];
  137. dxpExtra = fTabsKludge ? 0 : vfli.dxpExtra;
  138. #if defined(JAPAN) || defined(KOREA) // added 04 Jul. 1992 by Hiraisi
  139. iRun = 0;
  140. #endif
  141. for (dcp = 0; dcp < vfli.ichReal; pchp++)
  142. {
  143. /* For all runs do: */
  144. int ichFirst; /* First character in the current run */
  145. int cchRun; /* Number of characters in the current run */
  146. dcp = ichFirst = pchp->ichRun;
  147. dcp += pchp->cchRun;
  148. if (dcp > vfli.ichReal)
  149. {
  150. dcp = vfli.ichReal;
  151. }
  152. cchRun = dcp - ichFirst;
  153. /* Compute dxp = sum of width of characters in current run (formerly
  154. DxpFromIcpDcp). */
  155. {
  156. register int *pdxp;
  157. register int cchT = cchRun;
  158. PCH pch = vfli.rgch + ichFirst;
  159. dxp = cBreakRun = 0;
  160. pdxp = &vfli.rgdxp[ichFirst];
  161. while (cchT-- > 0)
  162. {
  163. dxp += *pdxp++;
  164. if (*pch++ == chSpace)
  165. ++cBreakRun;
  166. }
  167. }
  168. if (dxp > 0)
  169. {
  170. int cchDone;
  171. PCH pch = &vfli.rgch[ichFirst];
  172. #if defined(JAPAN) || defined(KOREA) // added 08 Jul. 1992 by Hiraisi
  173. int *pdxpT = &vfli.rgdxp[ichFirst];
  174. #endif
  175. LoadFont(vfli.doc, pchp, mdFontPrint);
  176. #ifdef KOREA /* 920605 KDLEE */ // jinwoo: 92, 9, 28
  177. #ifdef NODESC
  178. yp = ypPrint+vfli.dypLine - (vfli.dypBase + (pchp->hpsPos != 0 ? (pchp->hpsPos <
  179. hpsNegMin ? ypSubSuperPr : -ypSubSuperPr) : 0)) -
  180. vfmiPrint.dypBaseline - ( isSubs ? ypSubSuperPr : 0 );
  181. #else /* NODESC */
  182. yp = ypPrint + vfli.dypLine - vfli.dypBase - (pchp->hpsPos != 0 ?
  183. (pchp->hpsPos < hpsNegMin ? ypSubSuperPr : -ypSubSuperPr) : 0) -
  184. vfmiPrint.dypBaseline;
  185. #endif /* NODESC */
  186. #else /* KOREA */
  187. yp = ypPrint + vfli.dypLine - vfli.dypBase - (pchp->hpsPos != 0 ?
  188. (pchp->hpsPos < hpsNegMin ? ypSubSuperPr : -ypSubSuperPr) : 0) -
  189. vfmiPrint.dypBaseline;
  190. #endif /* KOREA */
  191. /* Note: tabs and other special characters are guaranteed to come at
  192. the start of a run. */
  193. #ifdef JAPAN // added 01 Jul. 1992 by Hiraisi
  194. if( vpapAbs.jc != jcBoth || fTabsKludge )
  195. SetTextJustification(vhDCPrinter, dxpExtra*cBreakRun, cBreakRun);
  196. #else
  197. SetTextJustification(vhDCPrinter, dxpExtra * cBreakRun, cBreakRun);
  198. #endif /* JAPAN */
  199. cchDone = 0;
  200. while (cchDone < cchRun)
  201. {
  202. int cch;
  203. /* Does the wide-space zone begin in this run? */
  204. if (vfli.fAdjSpace && (vfli.ichFirstWide < ichFirst + cchRun) &&
  205. (ichFirst + cchDone <= vfli.ichFirstWide))
  206. {
  207. int cchDoneT = cchDone;
  208. /* Is this the beginning of the wide-space zone? */
  209. if (ichFirst + cchDone == vfli.ichFirstWide)
  210. {
  211. /* Reset the width of the spaces. */
  212. #ifdef JAPAN // added 01 Jul. 1992 by Hiraisi
  213. if( vpapAbs.jc != jcBoth || fTabsKludge )
  214. SetTextJustification(vhDCPrinter, ++dxpExtra*cBreakRun, cBreakRun);
  215. #else
  216. SetTextJustification(vhDCPrinter, ++dxpExtra * cBreakRun, cBreakRun);
  217. #endif /* JAPAN */
  218. cch = cchRun - cchDone;
  219. cchDone = cchRun;
  220. }
  221. else
  222. {
  223. cchDone = cch = vfli.ichFirstWide - ichFirst;
  224. }
  225. /* This run is cut short because of a wide space, so we need
  226. to calculate a new width. */
  227. {
  228. register int *pdxp;
  229. register int cchT = cch;
  230. PCH pch = &vfli.rgch[ichFirst + cchDoneT];
  231. dxp = 0;
  232. pdxp = &vfli.rgdxp[ichFirst + cchDoneT];
  233. while (cchT-- > 0)
  234. {
  235. dxp += *pdxp++;
  236. if (*pch++ == chSpace)
  237. ++cBreakRun;
  238. }
  239. }
  240. }
  241. else
  242. {
  243. cchDone = cch = cchRun;
  244. }
  245. while (cch > 0)
  246. {
  247. switch (*pch)
  248. {
  249. CHAR ch;
  250. int dxpT;
  251. case chTab:
  252. #ifdef CASHMERE
  253. /* chLeader contains tab leader character (see
  254. FormatLine) */
  255. if ((ch = pchp->chLeader) != chSpace)
  256. {
  257. int cxpTab;
  258. CHAR rgch[32];
  259. int dxpLeader = DxpFromCh(ch, TRUE);
  260. int xp = xpPrint;
  261. int iLevelT = SaveDC(vhDCPrinter);
  262. SetBytes(&rgch[0], ch, 32);
  263. dxpT = vfli.rgdxp[ichFirst];
  264. cxpTab = ((dxpT + dxpLeader - 1) / dxpLeader + 31)
  265. >> 5;
  266. #ifdef CLIP
  267. IntersectClipRect(vhDCPrinter, xpPrint, 0, xpPrint +
  268. dxpT, vfli.dypLine);
  269. #endif
  270. while (cxpTab-- > 0)
  271. {
  272. TextOut(vhDCPrinter, xp, yp, (LPSTR)rgch,
  273. 32);
  274. xp += dxpLeader << 5;
  275. }
  276. RestoreDC(vhDCPrinter, iLevelT);
  277. xpPrint += dxpT;
  278. }
  279. else
  280. #endif /* CASHMERE */
  281. {
  282. xpPrint += vfli.rgdxp[ichFirst];
  283. }
  284. if (fTabsKludge && ichFirst >= vfli.ichLastTab)
  285. {
  286. #ifdef JAPAN // added 01 Jul. 1992 by Hiraisi
  287. if( vpapAbs.jc != jcBoth )
  288. SetTextJustification(vhDCPrinter, (dxpExtra =
  289. vfli.dxpExtra) *cBreakRun, cBreakRun);
  290. else
  291. dxpExtra = vfli.dxpExtra;
  292. #else
  293. SetTextJustification(vhDCPrinter, (dxpExtra =
  294. vfli.dxpExtra) * cBreakRun, cBreakRun);
  295. #endif /* JAPAN */
  296. fTabsKludge = FALSE;
  297. }
  298. dxp -= vfli.rgdxp[ichFirst];
  299. pch++;
  300. cch--;
  301. #if defined(JAPAN) || defined(KOREA) // added 04 Jul. 1992 by Hiraisi
  302. iRun++;
  303. pdxpT++;
  304. #endif
  305. goto EndLoop;
  306. #ifdef CASHMERE
  307. case schPage:
  308. if (!pchp->fSpecial)
  309. {
  310. goto EndLoop;
  311. }
  312. stBuf[0] = CchExpPgn(&stBuf[1], vpgn, vsepAbs.nfcPgn,
  313. flmPrinting, ichMaxLine);
  314. goto DrawSpecial;
  315. case schFootnote:
  316. if (!pchp->fSpecial)
  317. {
  318. goto EndLoop;
  319. }
  320. stBuf[0] = CchExpFtn(&stBuf[1], cpMin + ichFirst,
  321. flmPrinting, ichMaxLine);
  322. DrawSpecial:
  323. #else /* not CASHMERE */
  324. case schPage:
  325. case schFootnote:
  326. if (!pchp->fSpecial)
  327. {
  328. goto EndLoop;
  329. }
  330. stBuf[0] = *pch == schPage && vfli.cpMin + ichFirst <
  331. cpMinDocument ? CchExpPgn(&stBuf[1], vpgn, 0,
  332. flmPrinting, ichMaxLine) : CchExpUnknown(&stBuf[1],
  333. flmPrinting, ichMaxLine);
  334. #endif /* not CASHMERE */
  335. TextOut(vhDCPrinter, xpPrint, yp, (LPSTR)&stBuf[1],
  336. stBuf[0]);
  337. break;
  338. default:
  339. goto EndLoop;
  340. }
  341. dxp -= vfli.rgdxp[ichFirst];
  342. xpPrint += vfli.rgdxp[ichFirst++];
  343. pch++;
  344. cch--;
  345. #if defined(JAPAN) || defined(KOREA) // added 09 Jul. 1992 by Hiraisi
  346. pdxpT++;
  347. #endif
  348. }
  349. EndLoop:
  350. /* Output cch characters starting at pch */
  351. #if 0
  352. {
  353. char msg[180];
  354. wsprintf(msg,"putting out %d characters\n\r",cch);
  355. OutputDebugString(msg);
  356. }
  357. #endif
  358. #ifdef JAPAN // added 01 Jul. 1992 by Hiraisi
  359. if( vpapAbs.jc == jcBoth && !fTabsKludge ){
  360. CHAR *ptr1, *ptr2;
  361. int len, cnt;
  362. int iExtra, iSpace, iWid;
  363. BOOL bFlag;
  364. ptr2 = pch;
  365. for( cnt=0 ; cnt<cch ; ){
  366. ptr1 = ptr2;
  367. iExtra = dxpExtra;
  368. iWid = len = 0;
  369. bFlag = TRUE;
  370. if( IsDBCSLeadByte( *ptr2 ) ){
  371. for( ; cnt<cch ; ){
  372. iWid += *pdxpT;
  373. pdxpT+=2;
  374. cnt+=2;
  375. len += 2;
  376. iRun += 2;
  377. ptr2 += 2;
  378. if( --iNonWideSpaces == 0){
  379. dxpExtra++;
  380. break;
  381. }
  382. if( iRun == dcp-2 )
  383. break;
  384. if( iRun == dcp ){ /* last DBC (maybe) */
  385. iExtra = 0;
  386. break;
  387. }
  388. if( !IsDBCSLeadByte( *ptr2 ) )
  389. break;
  390. }
  391. }
  392. else{
  393. if( FKana( (int)*ptr2 ) ){
  394. for( ; cnt<cch ; ){
  395. iWid += *pdxpT++;
  396. cnt++;
  397. len++;
  398. iRun++;
  399. ptr2++;
  400. if( --iNonWideSpaces == 0){
  401. dxpExtra++;
  402. break;
  403. }
  404. if( iRun == dcp-1 )
  405. break;
  406. if( iRun == dcp ){ /* last SBC (maybe) */
  407. iExtra = 0;
  408. break;
  409. }
  410. if( !FKana( (int)*ptr2 ) )
  411. break;
  412. }
  413. }
  414. else{
  415. for( bFlag=FALSE,iSpace = 0 ; cnt<cch ; ){
  416. iWid += *pdxpT++;
  417. cnt++;
  418. len++;
  419. iRun++;
  420. if( *ptr2++ == chSpace || !vfWordWrap ){
  421. iSpace++;
  422. if( --iNonWideSpaces == 0){
  423. dxpExtra;
  424. break;
  425. }
  426. }
  427. if( iRun == dcp-1 )
  428. break;
  429. if( iRun == dcp ){ /* last SBC (maybe) */
  430. iExtra = 0;
  431. break;
  432. }
  433. if( IsDBCSLeadByte( *ptr2 ) ||
  434. FKana( (int)*ptr2 ) )
  435. break;
  436. }
  437. }
  438. }
  439. if( vfWordWrap && !bFlag ){
  440. SetTextCharacterExtra( vhDCPrinter, 0 );
  441. SetTextJustification(vhDCPrinter, iExtra*iSpace,
  442. iSpace);
  443. }
  444. else{
  445. SetTextJustification( vhDCPrinter, 0, 0 );
  446. SetTextCharacterExtra( vhDCPrinter, iExtra );
  447. }
  448. TextOut(vhDCPrinter, xpPrint, yp, ptr1, len);
  449. xpPrint += iWid;
  450. }
  451. }
  452. else{
  453. iRun += cch;
  454. SetTextCharacterExtra( vhDCPrinter, 0 );
  455. TextOut(vhDCPrinter, xpPrint, yp, pch, cch);
  456. xpPrint += dxp;
  457. }
  458. #else
  459. TextOut(vhDCPrinter, xpPrint, yp, (LPSTR)pch, cch);
  460. xpPrint += dxp;
  461. #endif
  462. pch += cch;
  463. }
  464. }
  465. }
  466. Scribble(5,' ');
  467. }