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.

798 lines
24 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. /* picture.c -- MW format and display routines for pictures */
  5. //#define NOGDICAPMASKS
  6. #define NOWINMESSAGES
  7. #define NOVIRTUALKEYCODES
  8. #define NOWINSTYLES
  9. #define NOCLIPBOARD
  10. #define NOCTLMGR
  11. #define NOSYSMETRICS
  12. #define NOMENUS
  13. #define NOICON
  14. #define NOKEYSTATE
  15. //#define NOATOM
  16. #define NOCREATESTRUCT
  17. #define NODRAWTEXT
  18. #define NOFONT
  19. #define NOMB
  20. #define NOMENUS
  21. #define NOOPENFILE
  22. #define NOREGION
  23. #define NOSCROLL
  24. #define NOSOUND
  25. #define NOWH
  26. #define NOWINOFFSETS
  27. #define NOWNDCLASS
  28. #define NOCOMM
  29. #include <windows.h>
  30. #include "mw.h"
  31. #define NOKCCODES
  32. #include "ch.h"
  33. #include "docdefs.h"
  34. #include "fmtdefs.h"
  35. #include "dispdefs.h"
  36. #include "cmddefs.h"
  37. #include "propdefs.h"
  38. #include "stcdefs.h"
  39. #include "wwdefs.h"
  40. #include "filedefs.h"
  41. #include "editdefs.h"
  42. /* #include "str.h" */
  43. #include "prmdefs.h"
  44. /* #include "fkpdefs.h" */
  45. /* #include "macro.h" */
  46. #include "winddefs.h"
  47. #if defined(OLE)
  48. #include "obj.h"
  49. #endif
  50. extern typeCP cpMacCur;
  51. extern int docCur;
  52. extern int vfSelHidden;
  53. extern struct WWD rgwwd[];
  54. extern int wwCur;
  55. extern int wwMac;
  56. extern struct FLI vfli;
  57. extern struct SEL selCur;
  58. extern struct WWD *pwwdCur;
  59. extern struct PAP vpapCache;
  60. extern typeCP vcpFirstParaCache;
  61. extern typeCP vcpLimParaCache;
  62. extern int vfPictSel;
  63. extern struct PAP vpapAbs;
  64. extern struct SEP vsepAbs;
  65. extern struct SEP vsepPage;
  66. extern struct DOD (**hpdocdod)[];
  67. extern unsigned cwHeapFree;
  68. extern int vfInsertOn;
  69. extern int vfPMS;
  70. extern int dxpLogInch;
  71. extern int dypLogInch;
  72. extern int dxaPrPage;
  73. extern int dyaPrPage;
  74. extern int dxpPrPage;
  75. extern int dypPrPage;
  76. extern HBRUSH hbrBkgrnd;
  77. extern long ropErase;
  78. extern int vdocBitmapCache;
  79. extern typeCP vcpBitmapCache;
  80. extern HBITMAP vhbmBitmapCache;
  81. extern BOOL vfBMBitmapCache;
  82. extern HCURSOR vhcIBeam;
  83. extern BOOL vfMonochrome;
  84. /* Used in this module only */
  85. #ifdef DEBUG
  86. #define STATIC static
  87. #else
  88. #define STATIC
  89. #endif
  90. STATIC RECT rcPictInvalid; /* Rectangle (in window coords) that needs refresh */
  91. int vfWholePictInvalid = TRUE;
  92. FreeBitmapCache()
  93. {
  94. vdocBitmapCache = docNil;
  95. if (vhbmBitmapCache != NULL)
  96. {
  97. DeleteObject( vhbmBitmapCache );
  98. vhbmBitmapCache = NULL;
  99. }
  100. }
  101. MarkInvalidDlPict( ww, dlPict )
  102. int ww;
  103. int dlPict;
  104. { /* Mark the passed dl (presumed to be part of a picture) as requiring
  105. eventual update, when DisplayGraphics is called */
  106. register struct WWD *pwwd = &rgwwd [ww];
  107. struct EDL (**hdndl)[] = pwwd->hdndl;
  108. struct EDL *pedl = &(**hdndl)[ dlPict ];
  109. RECT rcDl;
  110. SetRect( (LPRECT) &rcDl, 0, pedl->yp - pedl->dyp,
  111. pwwd->xpMac, pedl->yp );
  112. if (vfWholePictInvalid)
  113. {
  114. CopyRect( (LPRECT) &rcPictInvalid, (LPRECT) &rcDl );
  115. vfWholePictInvalid = FALSE;
  116. }
  117. else
  118. {
  119. RECT rcT;
  120. rcT = rcPictInvalid; /* Necessary? i.e. can UnionRect handle
  121. source == destination */
  122. UnionRect( (LPRECT) &rcPictInvalid, (LPRECT) &rcT, (LPRECT) &rcDl );
  123. }
  124. }
  125. DisplayGraphics( ww, dl, fDontDisplay )
  126. int ww;
  127. int dl;
  128. int fDontDisplay;
  129. { /* Display a line of graphics info */
  130. struct WWD *pwwd = &rgwwd[ww];
  131. struct EDL *pedl;
  132. typeCP cpPictStart;
  133. typeCP cp;
  134. typeCP cpMac = (**hpdocdod)[vfli.doc].cpMac;
  135. struct PICINFOX picInfo;
  136. RECT rcEnclose;
  137. RECT rcPict;
  138. HANDLE hBits=NULL;
  139. HDC hMDC=NULL;
  140. HDC hMDCCache=NULL;
  141. HANDLE hbm=NULL;
  142. HDC hDC=pwwd->hDC;
  143. int cchRun;
  144. unsigned long cbPict=0;
  145. int dxpOrig; /* Size of picture in the original */
  146. int dypOrig;
  147. int dxpDisplay; /* Size of picture as we want to show it */
  148. int dypDisplay;
  149. int fBitmap;
  150. int ilevel=0;
  151. /* THIS ROUTINE COULD USE SOME GDI-CALL ERROR CHECKING! ..pault */
  152. int fDrew=false;
  153. /* In the case of monochrome devices, this raster op will map white in
  154. the bitmap to the background color and black to the foreground color. */
  155. #define ropMonoBm 0x00990066
  156. Assert( dl >= 0 && dl < pwwd->dlMax );
  157. MarkInvalidDlPict( ww, dl );
  158. if (fDontDisplay)
  159. {
  160. return;
  161. }
  162. Diag(CommSz("DisplayGraphics: \n\r"));
  163. FreezeHp();
  164. pedl = &(**(pwwd->hdndl))[dl];
  165. cpPictStart=pedl->cpMin;
  166. GetPicInfo( cpPictStart, cpMac, vfli.doc, &picInfo );
  167. /* Compute desired display size of picture (in device pixels) */
  168. ComputePictRect( &rcPict, &picInfo, pedl, ww );
  169. dxpDisplay = rcPict.right - rcPict.left;
  170. dypDisplay = rcPict.bottom - rcPict.top;
  171. /* Compute original size of picture (in device pixels) */
  172. /* MM_ANISOTROPIC and MM_ISOTROPIC pictures have no original size */
  173. switch ( picInfo.mfp.mm ) {
  174. case MM_ISOTROPIC:
  175. case MM_ANISOTROPIC:
  176. break;
  177. case MM_BITMAP:
  178. dxpOrig = picInfo.bm.bmWidth;
  179. dypOrig = picInfo.bm.bmHeight;
  180. break;
  181. #if defined(OLE)
  182. case MM_OLE:
  183. {
  184. extern BOOL vfObjDisplaying;
  185. if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
  186. goto DontDraw;
  187. /* just to be safe */
  188. if (!CheckPointer(lpOBJ_QUERY_INFO(&picInfo),1))
  189. goto DontDraw;
  190. if (lpOBJ_QUERY_OBJECT(&picInfo) == NULL)
  191. {
  192. typeCP cpRet;
  193. /* this can require memory, so unlock heap */
  194. MeltHp();
  195. vfObjDisplaying = TRUE;
  196. cpRet = ObjLoadObjectInDoc(&picInfo,vfli.doc,cpPictStart);
  197. vfObjDisplaying = FALSE;
  198. FreezeHp();
  199. pedl = &(**(pwwd->hdndl))[dl];
  200. if (cpRet == cp0)
  201. goto DontDraw;
  202. }
  203. }
  204. break;
  205. #endif
  206. default:
  207. dxpOrig = PxlConvert( picInfo.mfp.mm, picInfo.mfp.xExt,
  208. GetDeviceCaps( hDC, HORZRES ),
  209. GetDeviceCaps( hDC, HORZSIZE ) );
  210. dypOrig = PxlConvert( picInfo.mfp.mm, picInfo.mfp.yExt,
  211. GetDeviceCaps( hDC, VERTRES ),
  212. GetDeviceCaps( hDC, VERTSIZE ) );
  213. if (! (dxpOrig && dypOrig) )
  214. {
  215. goto DontDraw;
  216. }
  217. break;
  218. }
  219. /* Save DC as a guard against DC attribute alteration by a metafile */
  220. #ifdef WINDOWS_BUG_FIXED /* Currently 0 is a valid level for Own DC's */
  221. if ((ilevel=SaveDC( hDC )) == 0)
  222. goto DontDraw;
  223. #endif
  224. ilevel = SaveDC( hDC );
  225. SetStretchBltMode( hDC, BLACKONWHITE );
  226. /* Clip out top bar, selection bar */
  227. IntersectClipRect( hDC, ((wwCur == wwClipboard) ? 0 : xpSelBar),
  228. pwwdCur->ypMin, pwwdCur->xpMac, pwwdCur->ypMac );
  229. if (!vfWholePictInvalid)
  230. /* Repainting less than the whole picture; clip out
  231. what we're not drawing */
  232. IntersectClipRect( hDC, rcPictInvalid.left, rcPictInvalid.top,
  233. rcPictInvalid.right, rcPictInvalid.bottom );
  234. /* Build rcEnclose, a rect enclosing the picture that
  235. includes the "space before" and "space after" fields */
  236. rcEnclose.left = xpSelBar;
  237. if ((rcEnclose.top = rcPict.top -
  238. DypFromDya( vpapAbs.dyaBefore, FALSE )) < pwwd->ypMin)
  239. rcEnclose.top = pwwd->ypMin;
  240. rcEnclose.right = pwwd->xpMac;
  241. if ((rcEnclose.bottom = rcPict.bottom +
  242. DypFromDya( vpapAbs.dyaAfter, FALSE )) > pwwd->ypMac)
  243. rcEnclose.bottom = pwwd->ypMac;
  244. /* White out enclosing rect */
  245. PatBlt( hDC, rcEnclose.left, rcEnclose.top,
  246. rcEnclose.right - rcEnclose.left,
  247. rcEnclose.bottom - rcEnclose.top, ropErase );
  248. /* If we have it cached, do display the easy way */
  249. if (pwwd->doc == vdocBitmapCache && cpPictStart == vcpBitmapCache)
  250. {
  251. Assert( pwwd->doc != docNil && vhbmBitmapCache != NULL);
  252. if ( ((hMDC = CreateCompatibleDC( hDC )) != NULL) &&
  253. SelectObject( hMDC, vhbmBitmapCache ))
  254. {
  255. Diag(CommSz("DisplayGraphics: BitBlt\n\r"));
  256. BitBlt( hDC, rcPict.left, rcPict.top, dxpDisplay, dypDisplay,
  257. hMDC, 0, 0, vfMonochrome && vfBMBitmapCache ?
  258. ropMonoBm : SRCCOPY );
  259. fDrew = TRUE;
  260. goto DontDraw;
  261. }
  262. else
  263. { /* Using the cache failed -- empty it
  264. (SelectObject will fail if bitmap was discarded) */
  265. FreeBitmapCache();
  266. }
  267. }
  268. StartLongOp(); /* Put up an hourglass */
  269. /* Build up all bytes associated with the picture (except the header)
  270. into the global Windows handle hBits */
  271. if ( picInfo.mfp.mm != MM_OLE)
  272. {
  273. if ((hBits=GlobalAlloc( GMEM_MOVEABLE, (long)picInfo.cbSize )) == NULL)
  274. { /* Not enough global heap space to load bitmap/metafile */
  275. goto DontDraw;
  276. }
  277. #ifdef DCLIP
  278. {
  279. char rgch[200];
  280. wsprintf(rgch,"DisplayGraphics: picinfo.cbSize %lu \n\r", picInfo.cbSize);
  281. CommSz(rgch);
  282. }
  283. #endif
  284. for ( cbPict = 0, cp = cpPictStart + picInfo.cbHeader;
  285. cbPict < picInfo.cbSize;
  286. cbPict += cchRun, cp += (typeCP) cchRun )
  287. {
  288. CHAR rgch[ 256 ];
  289. #if WINVER >= 0x300
  290. HPCH lpch;
  291. #else
  292. LPCH lpch;
  293. #endif
  294. #define ulmin(a,b) ((unsigned long)(a) < (unsigned long)(b) ? \
  295. (unsigned long)(a) : (unsigned long)(b))
  296. FetchRgch( &cchRun, rgch, vfli.doc, cp, cpMac,
  297. (int) ulmin( picInfo.cbSize - cbPict, 256 ) );
  298. if ((lpch=GlobalLock( hBits )) != NULL)
  299. {
  300. #ifdef DCLIP
  301. {
  302. char rgch[200];
  303. wsprintf(rgch," copying %d bytes from %lX to %lX \n\r",cchRun,(LPSTR)rgch,lpch+cbPict);
  304. CommSz(rgch);
  305. }
  306. {
  307. char rgchT[200];
  308. int i;
  309. for (i = 0; i< min(20,cchRun); i++,i++)
  310. {
  311. wsprintf(rgchT,"%X ",* (int *) &(rgch[i]));
  312. CommSz(rgchT);
  313. }
  314. CommSz("\n\r");
  315. }
  316. #endif
  317. #if WINVER >= 0x300
  318. bltbh( (LPSTR)rgch, lpch+cbPict, cchRun );
  319. #else
  320. bltbx( (LPSTR)rgch, lpch+cbPict, cchRun );
  321. #endif
  322. GlobalUnlock( hBits );
  323. }
  324. else
  325. {
  326. goto DontDraw;
  327. }
  328. }
  329. }
  330. /* Display the picture */
  331. MeltHp();
  332. #if defined(OLE)
  333. /* CASE 0: OLE */
  334. if (picInfo.mfp.mm == MM_OLE)
  335. {
  336. Diag(CommSz("Case 0:\n\r"));
  337. if (ObjDisplayObjectInDoc(&picInfo, vfli.doc, cpPictStart,
  338. hDC, &rcPict) == FALSE)
  339. goto DontDraw;
  340. fDrew = true;
  341. }
  342. else
  343. #endif
  344. /* CASE 1: Bitmap */
  345. if (fBitmap = (picInfo.mfp.mm == MM_BITMAP))
  346. {
  347. Diag(CommSz("Case 1: \n\r"));
  348. if ( ((hMDC = CreateCompatibleDC( hDC )) != NULL) &&
  349. ((picInfo.bm.bmBits = GlobalLock( hBits )) != NULL) &&
  350. ((hbm=CreateBitmapIndirect((LPBITMAP)&picInfo.bm))!=NULL))
  351. {
  352. picInfo.bm.bmBits = NULL;
  353. GlobalUnlock( hBits );
  354. GlobalFree( hBits ); /* Free handle to bits to allow max room */
  355. hBits = NULL;
  356. SelectObject( hMDC, hbm );
  357. goto CacheIt;
  358. }
  359. }
  360. /* Case 2: non-scalable metafile pictures which we are, for
  361. user interface consistency, scaling by force using StretchBlt */
  362. else if ( ((dxpDisplay != dxpOrig) || (dypDisplay != dypOrig)) &&
  363. (picInfo.mfp.mm != MM_ISOTROPIC) &&
  364. (picInfo.mfp.mm != MM_ANISOTROPIC) )
  365. {
  366. Diag(CommSz("Case 2: \n\r"));
  367. if (((hMDC=CreateCompatibleDC( hDC)) != NULL) &&
  368. ((hbm=CreateCompatibleBitmap( hDC, dxpOrig, dypOrig ))!=NULL) &&
  369. SelectObject( hMDC, hbm ) && SelectObject( hMDC, hbrBkgrnd ))
  370. {
  371. extern int vfOutOfMemory;
  372. PatBlt( hMDC, 0, 0, dxpOrig, dypOrig, ropErase );
  373. SetMapMode( hMDC, picInfo.mfp.mm );
  374. /* To cover StretchBlt calls within the metafile */
  375. SetStretchBltMode( hMDC, BLACKONWHITE );
  376. PlayMetaFile( hMDC, hBits );
  377. /* Because we pass pixels to StretchBlt */
  378. SetMapMode( hMDC, MM_TEXT );
  379. CacheIt: Assert( hbm != NULL && hMDC != NULL );
  380. if (vfOutOfMemory)
  381. goto NoCache;
  382. #ifndef NOCACHE
  383. FreeBitmapCache();
  384. /* Among other things, this code caches the current picture.
  385. Notice that there are two assumptions: (1) all bitmaps are
  386. monochrome, and (2) a newly created memory DC has a monochrome
  387. bitmap selected in. */
  388. if ( ((hMDCCache = CreateCompatibleDC( hDC )) != NULL) &&
  389. ((vhbmBitmapCache = CreateDiscardableBitmap(
  390. fBitmap ? hMDCCache : hDC, dxpDisplay, dypDisplay )) !=
  391. NULL) &&
  392. SelectObject( hMDCCache, vhbmBitmapCache ))
  393. {
  394. if (!StretchBlt( hMDCCache, 0, 0, dxpDisplay,
  395. dypDisplay, hMDC, 0, 0, dxpOrig, dypOrig, SRCCOPY ))
  396. { /* may get here if memory is low */
  397. DeleteDC( hMDCCache );
  398. hMDCCache = NULL;
  399. DeleteObject( vhbmBitmapCache );
  400. vhbmBitmapCache = NULL;
  401. goto NoCache;
  402. }
  403. #ifdef DCLIP
  404. if (vfMonochrome && fBitmap)
  405. CommSzNum("BitBlt using ropMonoBm == ",ropMonoBm);
  406. #endif
  407. BitBlt( hDC, rcPict.left, rcPict.top, dxpDisplay,
  408. dypDisplay, hMDCCache, 0, 0, vfMonochrome && fBitmap ?
  409. ropMonoBm : SRCCOPY );
  410. /* Cached bitmap OK, make cache valid */
  411. vdocBitmapCache = pwwd->doc;
  412. vcpBitmapCache = cpPictStart;
  413. vfBMBitmapCache = fBitmap;
  414. }
  415. else
  416. #endif /* ndef NOCACHE */
  417. {
  418. NoCache:
  419. StretchBlt( hDC, rcPict.left, rcPict.top,
  420. dxpDisplay, dypDisplay,
  421. hMDC, 0, 0, dxpOrig, dypOrig, vfMonochrome &&
  422. fBitmap ? ropMonoBm : SRCCOPY );
  423. }
  424. fDrew = TRUE;
  425. }
  426. }
  427. /* Case 3: A metafile picture which can be directly scaled
  428. or does not need to be because its size has not changed */
  429. else
  430. {
  431. fDrew = true;
  432. Diag(CommSz("Case 3:\n\r"));
  433. SetMapMode( hDC, picInfo.mfp.mm );
  434. SetViewportOrg( hDC, rcPict.left, rcPict.top );
  435. switch( picInfo.mfp.mm ) {
  436. case MM_ISOTROPIC:
  437. if (picInfo.mfp.xExt && picInfo.mfp.yExt)
  438. /* So we get the correct shape rectangle when
  439. SetViewportExt gets called */
  440. SetWindowExt( hDC, picInfo.mfp.xExt, picInfo.mfp.yExt );
  441. /* FALL THROUGH */
  442. case MM_ANISOTROPIC:
  443. /** (9.17.91) v-dougk
  444. Set the window extent in case the metafile is bad
  445. and doesn't call it itself. This will prevent
  446. possible gpfaults in GDI
  447. **/
  448. SetWindowExt( hDC, dxpDisplay, dypDisplay );
  449. SetViewportExt( hDC, dxpDisplay, dypDisplay );
  450. break;
  451. }
  452. PlayMetaFile( hDC, hBits );
  453. }
  454. DontDraw:
  455. /* Clean up */
  456. if ( *(pLocalHeap+1) )
  457. MeltHp();
  458. if (ilevel > 0)
  459. RestoreDC( hDC, ilevel );
  460. if (hMDCCache != NULL)
  461. DeleteDC( hMDCCache );
  462. if (hMDC != NULL)
  463. DeleteDC( hMDC );
  464. if (hbm != NULL)
  465. DeleteObject( hbm );
  466. if (hBits != NULL)
  467. {
  468. if (fBitmap && picInfo.bm.bmBits != NULL)
  469. GlobalUnlock( hBits );
  470. GlobalFree( hBits );
  471. }
  472. if (!fDrew)
  473. {
  474. void DrawBlank(HDC hDC, RECT FAR *rc);
  475. DrawBlank(hDC,&rcPict);
  476. }
  477. /* Invert the selection */
  478. if (ww == wwDocument && !vfSelHidden && !vfPMS)
  479. {
  480. extern int vypCursLine;
  481. ilevel = SaveDC( hDC ); /* Because of clip calls below */
  482. if (!vfWholePictInvalid)
  483. /* Repainting less than the whole picture; clip out
  484. what we're not drawing */
  485. IntersectClipRect( hDC, rcPictInvalid.left, rcPictInvalid.top,
  486. rcPictInvalid.right, rcPictInvalid.bottom );
  487. /* Clip out top bar, selection bar */
  488. IntersectClipRect( hDC, xpSelBar,
  489. pwwdCur->ypMin, pwwdCur->xpMac, pwwdCur->ypMac );
  490. if (selCur.cpLim > cpPictStart && selCur.cpFirst <= cpPictStart)
  491. { /* Take into account 'space before' field */
  492. rcEnclose.left = rcPict.left;
  493. rcEnclose.right = rcPict.right;
  494. InvertRect( hDC, (LPRECT) &rcEnclose );
  495. }
  496. else if ((selCur.cpLim == selCur.cpFirst) &&
  497. (selCur.cpFirst == cpPictStart) &&
  498. (vfWholePictInvalid || rcPictInvalid.top < vypCursLine))
  499. { /* We erased the insert point */
  500. vfInsertOn = fFalse;
  501. }
  502. RestoreDC( hDC, ilevel );
  503. }
  504. vfWholePictInvalid = TRUE; /* Next picture, start invalidation anew */
  505. {
  506. extern int vfPMS;
  507. extern HCURSOR vhcPMS;
  508. EndLongOp( vfPMS ? vhcPMS : vhcIBeam );
  509. }
  510. }
  511. #ifdef ENABLE /* Don't use this anymore */
  512. int
  513. FPointInPict(pt)
  514. POINT pt;
  515. { /* Return true if point is within the picture frame */
  516. struct EDL *pedl;
  517. struct PICINFOX picInfo;
  518. RECT rcPict;
  519. GetPicInfo(selCur.cpFirst, cpMacCur, docCur, &picInfo);
  520. if (!FGetPictPedl(&pedl))
  521. return false;
  522. ComputePictRect( &rcPict, &picInfo, pedl, wwCur );
  523. return PtInRect( (LPRECT)&rcPict, pt );
  524. }
  525. #endif /* ENABLE */
  526. /* C O M P U T E P I C T R E C T */
  527. ComputePictRect( prc, ppicInfo, pedl, ww )
  528. RECT *prc;
  529. register struct PICINFOX *ppicInfo;
  530. struct EDL *pedl;
  531. int ww;
  532. { /* Compute rect containing picture indicated by passed ppicInfo,
  533. pedl, in the indicated ww. Return the computed rect through
  534. prc. picInfo structure is not altered. */
  535. int dypTop, xaLeft;
  536. struct WWD *pwwd = &rgwwd[ww];
  537. int xaStart;
  538. int dxaText, dxa;
  539. int dxpSize, dypSize;
  540. int dxaSize, dyaSize;
  541. CacheSectPic(pwwd->doc, pedl->cpMin);
  542. if (ppicInfo->mfp.mm == MM_BITMAP && ((ppicInfo->dxaSize == 0) ||
  543. (ppicInfo->dyaSize == 0)))
  544. {
  545. GetBitmapSize( &dxpSize, &dypSize, ppicInfo, FALSE );
  546. dxaSize = DxaFromDxp( dxpSize, FALSE );
  547. dyaSize = DyaFromDyp( dypSize, FALSE );
  548. }
  549. #if defined(OLE)
  550. else if (ppicInfo->mfp.mm == MM_OLE)
  551. {
  552. dxpSize = DxpFromDxa(ppicInfo->dxaSize, FALSE );
  553. dypSize = DypFromDya(ppicInfo->dyaSize, FALSE );
  554. dxpSize = MultDiv( dxpSize, ppicInfo->mx, mxMultByOne );
  555. dypSize = MultDiv( dypSize, ppicInfo->my, myMultByOne );
  556. dxaSize = DxaFromDxp( dxpSize, FALSE );
  557. dyaSize = DyaFromDyp( dypSize, FALSE );
  558. }
  559. #endif
  560. else
  561. {
  562. dxpSize = DxpFromDxa( dxaSize = ppicInfo->dxaSize, FALSE );
  563. dypSize = DypFromDya( dyaSize = ppicInfo->dyaSize, FALSE );
  564. }
  565. dypTop = pedl->dcpMac != 0 ?
  566. /* Last line of picture */
  567. DypFromDya( dyaSize + vpapAbs.dyaAfter, FALSE ) :
  568. (pedl->ichCpMin + 1) * dypPicSizeMin;
  569. dypTop = pedl->yp - dypTop;
  570. xaStart = DxaFromDxp( xpSelBar - (int) pwwd->xpMin, FALSE );
  571. dxaText = vsepAbs.dxaText;
  572. switch (vpapAbs.jc)
  573. {
  574. case jcBoth:
  575. case jcLeft:
  576. dxa = ppicInfo->dxaOffset;
  577. break;
  578. case jcCenter:
  579. dxa = (dxaText - (int)vpapAbs.dxaRight + (int)vpapAbs.dxaLeft -
  580. dxaSize) / 2;
  581. break;
  582. case jcRight:
  583. dxa = dxaText - (int)vpapAbs.dxaRight - dxaSize;
  584. break;
  585. }
  586. xaLeft = xaStart + max( (int)vpapAbs.dxaLeft, dxa );
  587. prc->right = (prc->left = DxpFromDxa( xaLeft, FALSE )) + dxpSize;
  588. prc->bottom = (prc->top = dypTop) + dypSize;
  589. }
  590. FGetPictPedl(ppedl)
  591. struct EDL **ppedl;
  592. {
  593. int dlLim = pwwdCur->dlMac;
  594. int dl;
  595. typeCP cpFirst = selCur.cpFirst;
  596. struct EDL *pedl;
  597. //Assert(vfPictSel);
  598. if (!vfPictSel)
  599. return FALSE;
  600. pedl = &(**(pwwdCur->hdndl)[0]);
  601. for (dl = 0; dl < dlLim; ++dl, ++pedl)
  602. {
  603. //if (!pedl->fValid)
  604. //return false;
  605. if (pedl->cpMin == cpFirst)
  606. break;
  607. }
  608. if (dl >= dlLim)
  609. return false; /* No part of picture is on screen */
  610. *ppedl = pedl;
  611. return true;
  612. }
  613. /* C P W I N G R A P H I C */
  614. typeCP CpWinGraphic(pwwd)
  615. struct WWD *pwwd;
  616. {
  617. int cdlPict, dl;
  618. struct EDL *dndl = &(**(pwwd->hdndl))[0];
  619. Assert( !pwwd->fDirty ); /* So we can rely on dl info */
  620. CachePara(pwwd->doc, dndl->cpMin);
  621. for (dl = 0; (dl < pwwd->dlMac - 1 && dndl[dl].fIchCpIncr); ++dl)
  622. ;
  623. Assert(dndl[dl].fGraphics);
  624. cdlPict = dndl[dl].ichCpMin + 1;
  625. return (dndl[0].cpMin +
  626. (vcpLimParaCache - vcpFirstParaCache) * dndl[0].ichCpMin / cdlPict);
  627. }
  628. CacheSectPic(doc, cp)
  629. int doc;
  630. typeCP cp;
  631. { /* Cache section and para props, taking into account that footnotes take props
  632. from the reference point */
  633. #ifdef FOOTNOTES
  634. struct DOD *pdod = &(**hpdocdod)[doc];
  635. struct FNTB (**hfntb) = pdod->hfntb;
  636. #endif
  637. CachePara(doc, cp);
  638. #ifdef FOOTNOTES
  639. if ( (hfntb != 0) && (cp >= (**hfntb).rgfnd[0].cpFtn) )
  640. CacheSect( doc, CpRefFromFtn( doc, cp ) )
  641. else
  642. #endif
  643. CacheSect(doc, cp); /* Normal text */
  644. }
  645. void DrawBlank(HDC hDC, RECT FAR *rc)
  646. { /* To tell us when the draw tried but failed */
  647. int xpMid=rc->left + (rc->right-rc->left)/2;
  648. int ypMid=rc->top + (rc->bottom - rc->top)/2;
  649. int dxpQ=(rc->right-rc->left)/4;
  650. int dypQ=(rc->bottom-rc->top)/4;
  651. HPEN hOldPen;
  652. HBRUSH hOldBrush;
  653. hOldPen = SelectObject( hDC, GetStockObject( BLACK_PEN ) );
  654. hOldBrush = SelectObject( hDC, GetStockObject( WHITE_BRUSH ) );
  655. Rectangle(hDC,rc->left,rc->top,rc->right,rc->bottom);
  656. MoveTo( hDC, rc->left, rc->top );
  657. LineTo( hDC, rc->right, rc->bottom );
  658. MoveTo( hDC, rc->left, rc->bottom );
  659. LineTo( hDC, rc->right, rc->top );
  660. MoveTo( hDC, xpMid, rc->top );
  661. LineTo( hDC, xpMid, rc->bottom );
  662. MoveTo( hDC, rc->left, ypMid );
  663. LineTo( hDC, rc->right, ypMid );
  664. Ellipse( hDC,
  665. xpMid-dxpQ, ypMid-dypQ,
  666. xpMid+dxpQ, ypMid+dypQ );
  667. SelectObject( hDC, hOldPen );
  668. SelectObject( hDC, hOldBrush );
  669. }
  670.