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.

478 lines
10 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1998 Microsoft Corporation
  4. *
  5. * Abstract:
  6. *
  7. * Pen API related declarations
  8. *
  9. * Revision History:
  10. *
  11. * 12/09/1998 andrewgo
  12. * Flesh out pen interfaces.
  13. *
  14. * 12/08/1998 andrewgo
  15. * Created it.
  16. *
  17. \**************************************************************************/
  18. #ifndef _PEN_HPP
  19. #define _PEN_HPP
  20. //--------------------------------------------------------------------------
  21. // Abstract base class for various pen types
  22. //--------------------------------------------------------------------------
  23. class GpLineTexture;
  24. class GpCustomLineCap;
  25. class GpPen : public GpObject
  26. {
  27. protected:
  28. VOID SetValid(BOOL valid)
  29. {
  30. GpObject::SetValid(valid ? ObjectTagPen : ObjectTagInvalid);
  31. }
  32. public:
  33. // Constructors
  34. GpPen(
  35. const GpColor& color,
  36. REAL penWidth,
  37. GpUnit unit = UnitWorld
  38. );
  39. GpPen(
  40. const GpBrush* brush,
  41. REAL penWidth,
  42. GpUnit = UnitWorld
  43. );
  44. GpPen(
  45. GpLineTexture* lineTexture,
  46. REAL penWidth,
  47. GpUnit = UnitWorld
  48. );
  49. // Make a copy of the pen object
  50. GpPen* Clone();
  51. // Virtual destructor
  52. virtual ~GpPen()
  53. {
  54. if(Brush)
  55. delete Brush;
  56. if(DevicePen.CustomStartCap)
  57. delete DevicePen.CustomStartCap;
  58. if(DevicePen.CustomEndCap)
  59. delete DevicePen.CustomEndCap;
  60. GpFree(DevicePen.DashArray);
  61. GpFree(DevicePen.CompoundArray);
  62. }
  63. // Get the lock object
  64. GpLockable *GetObjectLock() const
  65. {
  66. return &Lockable;
  67. }
  68. // Check if the pen object is valid
  69. virtual BOOL IsValid() const
  70. {
  71. return GpObject::IsValid(ObjectTagPen);
  72. }
  73. // Determine if pens are equivalent
  74. virtual BOOL IsEqual(const GpPen * pen) const;
  75. virtual ObjectType GetObjectType() const { return ObjectTypePen; }
  76. virtual UINT GetDataSize() const;
  77. virtual GpStatus GetData(IStream * stream) const;
  78. virtual GpStatus SetData(const BYTE * dataBuffer, UINT size);
  79. virtual GpStatus ColorAdjust(
  80. GpRecolor * recolor,
  81. ColorAdjustType type
  82. );
  83. // Set/get fill attributes
  84. VOID Set(
  85. const GpColor& color,
  86. REAL penWidth,
  87. GpUnit = UnitWorld
  88. );
  89. GpStatus SetColor(GpColor* color);
  90. GpStatus GetColor(ARGB *argb) const;
  91. GpStatus SetBrush(GpBrush* brush);
  92. GpBrush* GetBrush()
  93. {
  94. return Brush;
  95. }
  96. GpBrush* GetClonedBrush()
  97. {
  98. if(Brush)
  99. {
  100. return Brush->Clone();
  101. }
  102. else
  103. return NULL;
  104. }
  105. GpPenType GetPenType();
  106. GpStatus SetLineTexture(GpLineTexture* lineTexture);
  107. GpLineTexture* GetLineTexture();
  108. // Set/get pen transform
  109. GpStatus SetTransform(const GpMatrix& matrix)
  110. {
  111. GpStatus status = Ok;
  112. // Keep the transform invertible
  113. if (matrix.IsInvertible())
  114. {
  115. DevicePen.Xform = matrix;
  116. UpdateUid();
  117. }
  118. else
  119. status = InvalidParameter;
  120. return status;
  121. }
  122. GpStatus GetTransform(GpMatrix* matrix) const
  123. {
  124. *matrix = DevicePen.Xform;
  125. return Ok;
  126. }
  127. GpStatus ResetTransform()
  128. {
  129. if (!DevicePen.Xform.IsIdentity())
  130. {
  131. DevicePen.Xform.Reset();
  132. UpdateUid();
  133. }
  134. return Ok;
  135. }
  136. GpStatus MultiplyTransform(const GpMatrix& matrix,
  137. GpMatrixOrder order = MatrixOrderPrepend);
  138. GpStatus TranslateTransform(REAL dx, REAL dy,
  139. GpMatrixOrder order = MatrixOrderPrepend)
  140. {
  141. DevicePen.Xform.Translate(dx, dy, order);
  142. UpdateUid();
  143. return Ok;
  144. }
  145. GpStatus ScaleTransform(REAL sx, REAL sy,
  146. GpMatrixOrder order = MatrixOrderPrepend)
  147. {
  148. DevicePen.Xform.Scale(sx, sy, order);
  149. UpdateUid();
  150. return Ok;
  151. }
  152. GpStatus RotateTransform(REAL angle,
  153. GpMatrixOrder order = MatrixOrderPrepend)
  154. {
  155. DevicePen.Xform.Rotate(angle, order);
  156. UpdateUid();
  157. return Ok;
  158. }
  159. // See if the pen has a non-identity transform.
  160. BOOL HasTransform() const
  161. {
  162. return !DevicePen.Xform.IsIdentity();
  163. }
  164. // Set/get line caps: start, end, and dash
  165. VOID SetStartCap(GpLineCap startCap)
  166. {
  167. DevicePen.StartCap = startCap;
  168. if(DevicePen.CustomStartCap)
  169. {
  170. delete DevicePen.CustomStartCap;
  171. DevicePen.CustomStartCap = NULL;
  172. }
  173. UpdateUid();
  174. }
  175. VOID SetEndCap(GpLineCap endCap)
  176. {
  177. DevicePen.EndCap = endCap;
  178. if(DevicePen.CustomEndCap)
  179. {
  180. delete DevicePen.CustomEndCap;
  181. DevicePen.CustomEndCap = NULL;
  182. }
  183. UpdateUid();
  184. }
  185. GpLineCap GetStartCap() const
  186. {
  187. return DevicePen.StartCap;
  188. }
  189. GpLineCap GetEndCap() const
  190. {
  191. return DevicePen.EndCap;
  192. }
  193. VOID SetLineCap(GpLineCap startCap, GpLineCap endCap, GpDashCap dashCap)
  194. {
  195. DevicePen.StartCap = startCap;
  196. DevicePen.EndCap = endCap;
  197. SetDashCap(dashCap);
  198. UpdateUid();
  199. }
  200. GpStatus SetCustomStartCap(const GpCustomLineCap* customCap);
  201. GpStatus GetCustomStartCap(GpCustomLineCap** customCap);
  202. GpStatus SetCustomEndCap(const GpCustomLineCap* customCap);
  203. GpStatus GetCustomEndCap(GpCustomLineCap** customCap);
  204. // Set/get line join
  205. VOID SetLineJoin(GpLineJoin lineJoin)
  206. {
  207. DevicePen.Join = lineJoin;
  208. UpdateUid();
  209. }
  210. GpLineJoin GetLineJoin() const
  211. {
  212. return DevicePen.Join;
  213. }
  214. VOID SetMiterLimit(REAL miterLimit)
  215. {
  216. DevicePen.MiterLimit = max(1.0f, miterLimit);
  217. UpdateUid();
  218. }
  219. REAL GetMiterLimit() const
  220. {
  221. return DevicePen.MiterLimit;
  222. }
  223. GpStatus SetPenAlignment(GpPenAlignment penMode)
  224. {
  225. // Compound Inset pens aren't implemented yet.
  226. // The code for correctly handling minimum width compound sub lines
  227. // is missing.
  228. if((penMode==PenAlignmentInset) &&
  229. (DevicePen.CompoundCount!=0))
  230. {
  231. return NotImplemented;
  232. }
  233. DevicePen.PenAlignment = penMode;
  234. UpdateUid();
  235. return Ok;
  236. }
  237. GpPenAlignment GetPenAlignment() const
  238. {
  239. return DevicePen.PenAlignment;
  240. }
  241. // Set/get dash attributes
  242. GpDashStyle GetDashStyle() const
  243. {
  244. return DevicePen.DashStyle;
  245. }
  246. GpDashCap GetDashCap() const
  247. {
  248. // Note: Internally we use a GpLineCap type to store the dash cap type.
  249. // So we need to convert between GpLineCap and GpDashCap.
  250. // However, we should change the internal usage to GpDashCap in v2.
  251. // - JBronsk
  252. GpDashCap dashCap = DashCapFlat;
  253. switch (DevicePen.DashCap)
  254. {
  255. case LineCapRound:
  256. dashCap = DashCapRound;
  257. break;
  258. case LineCapTriangle:
  259. dashCap = DashCapTriangle;
  260. break;
  261. // all others map to DashCapFlat
  262. }
  263. return dashCap;
  264. }
  265. VOID SetDashCap(GpDashCap dashCap);
  266. GpStatus SetDashStyle(GpDashStyle dashStyle);
  267. VOID SetDashOffset(REAL dashOffset)
  268. {
  269. DevicePen.DashOffset = dashOffset;
  270. UpdateUid();
  271. }
  272. REAL GetDashOffset() const
  273. {
  274. return DevicePen.DashOffset;
  275. }
  276. INT GetDashCount() const
  277. {
  278. return DevicePen.DashCount;
  279. }
  280. GpStatus GetDashArray(REAL* dashArray, INT count) const;
  281. DpPen * GetDevicePen()
  282. {
  283. return & DevicePen;
  284. }
  285. VOID SetWidth(REAL penWidth)
  286. {
  287. DevicePen.Width = penWidth;
  288. UpdateUid();
  289. }
  290. REAL GetWidth() const
  291. {
  292. return DevicePen.Width;
  293. }
  294. REAL GetMaximumJoinWidth(
  295. REAL sharpestAngle,
  296. const GpMatrix* matrix,
  297. REAL dpiX,
  298. REAL dpiY) const;
  299. REAL GetMaximumCapWidth(
  300. const GpMatrix* matrix,
  301. REAL dpiX,
  302. REAL dpiY) const;
  303. VOID SetUnit(GpUnit unit)
  304. {
  305. // UnitDisplay is device-dependent and cannot be used for a pen size
  306. ASSERT(unit != UnitDisplay);
  307. DevicePen.Unit = unit;
  308. UpdateUid();
  309. }
  310. GpUnit GetUnit() const
  311. {
  312. return DevicePen.Unit;
  313. }
  314. GpStatus SetDashArray(const REAL* dashArray, INT count);
  315. INT GetCompoundCount() const
  316. {
  317. return DevicePen.CompoundCount;
  318. }
  319. GpStatus SetCompoundArray(const REAL* compoundArray, INT count);
  320. GpStatus GetCompoundArray(REAL* compoundArray, INT count);
  321. BOOL IsOpaque() const
  322. {
  323. return Brush->IsOpaque();
  324. }
  325. BOOL IsSolid() const
  326. {
  327. return Brush->IsSolid();
  328. }
  329. COLORREF ToCOLORREF() const
  330. {
  331. return Brush->ToCOLORREF();
  332. }
  333. REAL GetCapDelta();
  334. static GpPen * GetPen(const DpPen * pen)
  335. {
  336. return (GpPen *) ((BYTE *) pen - offsetof(GpPen, DevicePen));
  337. }
  338. static REAL ComputeMiterLength(
  339. REAL angle,
  340. REAL miterLimit
  341. );
  342. VOID
  343. AdjustDashArrayForCaps(
  344. REAL dashUnit,
  345. REAL *dashArray,
  346. INT dashCount
  347. ) const;
  348. REAL
  349. GetDashCapInsetLength(
  350. REAL dashUnit
  351. ) const;
  352. private:
  353. VOID InitDefaultState(REAL penWidth, GpUnit unit);
  354. GpStatus SetDashStyleWithDashCap(GpDashStyle dashStyle, GpLineCap dashCap);
  355. // GetMaximumWidth is used only for UnitWorld.
  356. GpStatus GetMaximumWidth(REAL* width, const GpMatrix* matrix) const;
  357. protected:
  358. mutable GpLockable Lockable;
  359. GpBrush * Brush;
  360. DpPen DevicePen;
  361. GpPen()
  362. {
  363. DevicePen.InitDefaults();
  364. SetValid(TRUE);
  365. }
  366. GpPen(const GpPen* pen);
  367. };
  368. #endif _PEN_HPP