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.

433 lines
9.4 KiB

  1. //
  2. // PAGE.CPP
  3. // WB Page Handling
  4. //
  5. // Copyright Microsoft 1998-
  6. //
  7. // PRECOMP
  8. #include "precomp.h"
  9. //
  10. //
  11. // Function: Draw
  12. //
  13. // Purpose: Draw the contents of the page into the specified device
  14. // context.
  15. //
  16. //
  17. void PG_Draw(WorkspaceObj* pWorkspace, HDC hDC)
  18. {
  19. T126Obj * pObj = NULL;
  20. WBPOSITION pos = NULL;
  21. if(pWorkspace)
  22. {
  23. pos = pWorkspace->GetHeadPosition();
  24. }
  25. while(pos)
  26. {
  27. pObj = (T126Obj*)pWorkspace->GetNextObject(pos);
  28. if(pObj)
  29. {
  30. pObj->Draw(hDC, FALSE, TRUE);
  31. }
  32. }
  33. }
  34. //
  35. //
  36. // Function: First (crect)
  37. //
  38. // Purpose: Return the first object in the page (bottommost Z-order)
  39. // that intersects the bounding rectangle
  40. //
  41. //
  42. T126Obj* PG_First(WorkspaceObj * pWorkSpc,LPCRECT pRectUpdate, BOOL bCheckReallyHit)
  43. {
  44. BOOL empty = TRUE;
  45. T126Obj* pGraphic = NULL;
  46. RECT rc;
  47. MLZ_EntryOut(ZONE_FUNCTION, "PG_First");
  48. if(pWorkSpc)
  49. {
  50. pGraphic = pWorkSpc->GetHead();
  51. }
  52. if(pGraphic == NULL)
  53. {
  54. return NULL;
  55. }
  56. if (pRectUpdate == NULL)
  57. {
  58. // We have got what we want
  59. TRACE_MSG(("Got the object we want"));
  60. }
  61. else
  62. {
  63. WBPOSITION pos = pWorkSpc->GetHeadPosition();
  64. pGraphic->GetBoundsRect(&rc);
  65. empty = !::IntersectRect(&rc, &rc, pRectUpdate);
  66. if (empty)
  67. {
  68. TRACE_MSG(("First object not needed - go to next"));
  69. pGraphic = PG_Next(pWorkSpc, pos, pRectUpdate, bCheckReallyHit);
  70. }
  71. else
  72. {
  73. if(bCheckReallyHit)
  74. {
  75. // do a real object hit test since we
  76. // know its bounding rect has hit
  77. if( !pGraphic->CheckReallyHit( pRectUpdate ) )
  78. {
  79. pGraphic = PG_Next(pWorkSpc, pos, pRectUpdate, TRUE); // look again
  80. }
  81. }
  82. }
  83. }
  84. return(pGraphic);
  85. }
  86. //
  87. //
  88. // Function: Next
  89. //
  90. // Purpose: Return the next graphic in the page (going up through the
  91. // Z-order). GetFirst must have been called before this
  92. // member.
  93. //
  94. T126Obj* PG_Next(WorkspaceObj* pWorkSpc, WBPOSITION& pos, LPCRECT pRectUpdate, BOOL bCheckReallyHit)
  95. {
  96. BOOL empty = TRUE;
  97. T126Obj* pGraphic = NULL;
  98. RECT rc;
  99. MLZ_EntryOut(ZONE_FUNCTION, "PG_Next");
  100. while (pos)
  101. {
  102. if(pWorkSpc)
  103. {
  104. pGraphic = pWorkSpc->GetNextObject(pos);
  105. }
  106. if (pRectUpdate == NULL)
  107. {
  108. // We have got what we want
  109. TRACE_MSG(("Got the object we want"));
  110. break;
  111. }
  112. else
  113. {
  114. if(pGraphic)
  115. {
  116. pGraphic->GetBoundsRect(&rc);
  117. empty = !::IntersectRect(&rc, &rc, pRectUpdate);
  118. }
  119. if (!empty)
  120. {
  121. if( bCheckReallyHit )
  122. {
  123. // do a real object hit test since we
  124. // know its bounding rect has hit
  125. if( pGraphic && pGraphic->CheckReallyHit( pRectUpdate ) )
  126. {
  127. break;
  128. }
  129. else
  130. {
  131. pGraphic = NULL; // look again
  132. }
  133. }
  134. else
  135. {
  136. break; // found it
  137. }
  138. }
  139. else
  140. {
  141. pGraphic = NULL;
  142. }
  143. }
  144. }
  145. return(pGraphic);
  146. }
  147. //
  148. //
  149. // Function: Last
  150. //
  151. // Purpose: Select the last object whose bounding rectangle contains
  152. // the point specified.
  153. //
  154. //
  155. T126Obj* PG_SelectLast
  156. (
  157. WorkspaceObj * pWorkSpc,
  158. POINT point
  159. )
  160. {
  161. RECT rectHit;
  162. T126Obj* pGraphic = NULL;
  163. if(pWorkSpc)
  164. {
  165. pGraphic = pWorkSpc->GetTail();
  166. }
  167. if(pGraphic == NULL)
  168. {
  169. return NULL;
  170. }
  171. WBPOSITION pos = pWorkSpc->GetTailPosition();
  172. MAKE_HIT_RECT(rectHit, point);
  173. if (!pGraphic->CheckReallyHit( &rectHit ))
  174. {
  175. // have to look some more
  176. pGraphic = PG_SelectPrevious(pWorkSpc, pos, point);
  177. }
  178. return(pGraphic);
  179. }
  180. //
  181. //
  182. // Function: Previous
  183. //
  184. // Purpose: Select the previous object whose bounding rectangle contains
  185. // the point specified.
  186. //
  187. //
  188. T126Obj* PG_SelectPrevious(WorkspaceObj* pWorkspace, WBPOSITION& pos, POINT point)
  189. {
  190. RECT rectHit;
  191. T126Obj* pGraphic = NULL;
  192. MLZ_EntryOut(ZONE_FUNCTION, "PG_Previous");
  193. MAKE_HIT_RECT(rectHit, point );
  194. while (pos)
  195. {
  196. if(pWorkspace)
  197. {
  198. pGraphic = pWorkspace->GetPreviousObject(pos);
  199. }
  200. if( pGraphic && pGraphic->CheckReallyHit( &rectHit ) )
  201. {
  202. break;
  203. }
  204. pGraphic = NULL;
  205. }
  206. return(pGraphic);
  207. }
  208. //CHANGED BY RAND
  209. #define WB_MIN_PRINT_MARGIN_SIZE (30)
  210. //
  211. //
  212. // Function: Print
  213. //
  214. // Purpose: Print the contents of the page to the specified printer. The
  215. // contents are scaled to "best fit" on the page. i.e. the
  216. // largest scaling factor that preserves the aspect ratio of
  217. // the page is used.
  218. //
  219. //
  220. void PG_Print(WorkspaceObj* pWorkspace,HDC hdc, LPCRECT lprcPrint)
  221. {
  222. int pageWidth;
  223. int pageHeight;
  224. int areaHeight;
  225. int areaWidth;
  226. int areaAspectRatio;
  227. int pageAspectRatio;
  228. int nPhysOffsetX;
  229. int nPhysOffsetY;
  230. int nPhysWidth;
  231. int nPhysHeight;
  232. int nVOffsetX;
  233. int nVOffsetY;
  234. // get physical printer params
  235. nPhysOffsetX = GetDeviceCaps(hdc, PHYSICALOFFSETX );
  236. nPhysOffsetY = GetDeviceCaps(hdc, PHYSICALOFFSETY );
  237. nPhysWidth = GetDeviceCaps(hdc, PHYSICALWIDTH );
  238. nPhysHeight = GetDeviceCaps(hdc, PHYSICALHEIGHT );
  239. // calc correct printer area (allow for bugs in some drivers...)
  240. if( nPhysOffsetX <= 0 )
  241. {
  242. nPhysOffsetX = WB_MIN_PRINT_MARGIN_SIZE;
  243. nVOffsetX = nPhysOffsetX;
  244. }
  245. else
  246. nVOffsetX = 0;
  247. if( nPhysOffsetY <= 0 )
  248. {
  249. nPhysOffsetY = WB_MIN_PRINT_MARGIN_SIZE;
  250. nVOffsetY = nPhysOffsetY;
  251. }
  252. else
  253. nVOffsetY = 0;
  254. // get and adjust printer page area
  255. pageWidth = GetDeviceCaps(hdc, HORZRES );
  256. pageHeight = GetDeviceCaps(hdc, VERTRES );
  257. if( pageWidth >= (nPhysWidth - nPhysOffsetX) )
  258. {
  259. // HORZRES is lying to us, compensate
  260. pageWidth = nPhysWidth - 2*nPhysOffsetX;
  261. }
  262. if( pageHeight >= (nPhysHeight - nPhysOffsetY) )
  263. {
  264. // VERTRES is lying to us, compensate
  265. pageHeight = nPhysHeight - 2*nPhysOffsetY;
  266. }
  267. // adjust printer area to get max fit for Whiteboard page
  268. areaWidth = lprcPrint->right - lprcPrint->left;
  269. areaHeight = lprcPrint->bottom - lprcPrint->top;
  270. areaAspectRatio = ((100 * areaHeight + (areaWidth/2))/(areaWidth));
  271. pageAspectRatio = ((100 * pageHeight + (pageWidth/2))/(pageWidth));
  272. if (areaAspectRatio < pageAspectRatio)
  273. pageHeight = ((pageWidth * areaHeight + (areaWidth/2))/areaWidth);
  274. else
  275. if (areaAspectRatio > pageAspectRatio)
  276. pageWidth = ((pageHeight * areaWidth + (areaHeight/2))/areaHeight);
  277. // set up xforms
  278. ::SetMapMode(hdc, MM_ANISOTROPIC );
  279. ::SetWindowExtEx(hdc, areaWidth, areaHeight,NULL );
  280. ::SetWindowOrgEx(hdc, 0,0, NULL );
  281. ::SetViewportExtEx(hdc, pageWidth, pageHeight, NULL );
  282. ::SetViewportOrgEx(hdc, nVOffsetX, nVOffsetY, NULL );
  283. // draw the page
  284. PG_Draw(pWorkspace, hdc);
  285. }
  286. //
  287. //
  288. // Function: PG_InitializePalettes
  289. //
  290. // Purpose: Create palettes for display and print (if necessary)
  291. //
  292. //
  293. void PG_InitializePalettes(void)
  294. {
  295. MLZ_EntryOut(ZONE_FUNCTION, "PG_InitializePalettes");
  296. // If the palettes are not yet initialized - initialize them now
  297. if (!g_bPalettesInitialized)
  298. {
  299. ASSERT(!g_hRainbowPaletteDisplay);
  300. // Get the number of colors supported by the screen
  301. // We only need an info DC for this, not a full DC
  302. HDC hdc;
  303. hdc = ::CreateIC("DISPLAY", NULL, NULL, NULL);
  304. if (!hdc)
  305. {
  306. return;
  307. }
  308. // Determine whether the device supports palettes
  309. int iBitsPixel = ::GetDeviceCaps(hdc, BITSPIXEL);
  310. int iPlanes = ::GetDeviceCaps(hdc, PLANES);
  311. int iNumColors = iBitsPixel * iPlanes;
  312. ::DeleteDC(hdc);
  313. // If we need the palette, create it.
  314. // We only need the palette on a 8bpp machine. Anything less (4bpp)
  315. // and there will be no palette, anything more is a pure color display.
  316. if ((iNumColors == 8) &&
  317. (g_hRainbowPaletteDisplay = CreateColorPalette()))
  318. {
  319. // Show that we want to use the palette
  320. g_bUsePalettes = TRUE;
  321. }
  322. else
  323. {
  324. g_bUsePalettes = FALSE;
  325. }
  326. // Show that we have now initialized the palette information
  327. g_bPalettesInitialized = TRUE;
  328. }
  329. }
  330. //
  331. //
  332. // Function: PG_GetPalette
  333. //
  334. // Purpose: Return the palette for use with this page.
  335. // This object is temporary and should not be stored.
  336. //
  337. //
  338. HPALETTE PG_GetPalette(void)
  339. {
  340. MLZ_EntryOut(ZONE_FUNCTION, "PG_GetPalette");
  341. // If the palettes are not yet initialized - initialize them now
  342. PG_InitializePalettes();
  343. if (g_bUsePalettes)
  344. {
  345. // If we are using a non-default palette, set the return value
  346. return(g_hRainbowPaletteDisplay);
  347. }
  348. else
  349. {
  350. return(NULL);
  351. }
  352. }
  353. void PG_ReinitPalettes(void)
  354. {
  355. MLZ_EntryOut(ZONE_FUNCTION, "PG_ReinitPalettes");
  356. if (g_hRainbowPaletteDisplay)
  357. {
  358. if (g_pDraw->m_hDCCached)
  359. {
  360. // Select out the rainbow palette so we can delete it
  361. ::SelectPalette(g_pDraw->m_hDCCached, (HPALETTE)::GetStockObject(DEFAULT_PALETTE), TRUE);
  362. }
  363. ::DeletePalette(g_hRainbowPaletteDisplay);
  364. g_hRainbowPaletteDisplay = NULL;
  365. }
  366. g_bPalettesInitialized = FALSE;
  367. PG_InitializePalettes();
  368. }