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.

241 lines
6.4 KiB

  1. extern "C"
  2. {
  3. #include "precomp.h"
  4. }
  5. #include "wtypes.h"
  6. #include "objbase.h"
  7. #include "gdiplus.h"
  8. extern "C" BOOL bInvertxform(PXFORM pxformSrc, PXFORM pxformDest);
  9. extern "C" BOOL bXformWorkhorse(PPOINTL aptl, DWORD nCount, PXFORM pXform);
  10. using namespace Gdiplus;
  11. inline REAL
  12. GetDistance(
  13. GpPointF & p1,
  14. GpPointF & p2
  15. )
  16. {
  17. double dx = (double)p2.X - p1.X;
  18. double dy = (double)p2.Y - p1.Y;
  19. return (REAL)sqrt((dx * dx) + (dy * dy));
  20. }
  21. // Flatten a path using GDI+ and transform the points before hand so we flatten
  22. // the points that will go in the metafile. We allocate one buffer that will
  23. // contain the points and types. The caller has to free that buffer
  24. extern "C" BOOL GdipFlattenGdiPath(PLOCALDC pLocalDC,
  25. LPVOID *buffer,
  26. INT *count)
  27. {
  28. BOOL b = FALSE;
  29. INT i ;
  30. INT cpt;
  31. PBYTE pb = NULL;
  32. PointF* pptf;
  33. LPPOINT ppt;
  34. PBYTE pjType;
  35. INT flattenCount;
  36. PBYTE flattenpb = NULL;
  37. PointF* flattenPoints;
  38. PBYTE flattenTypes;
  39. PBYTE returnpb = NULL;
  40. ASSERT(buffer != NULL && *buffer == NULL && count != NULL);
  41. // Get the path data.
  42. // First get a count of the number of points.
  43. cpt = GetPath(pLocalDC->hdcHelper, (LPPOINT) NULL, (LPBYTE) NULL, 0);
  44. if (cpt == -1)
  45. {
  46. RIPS("MF3216: DoFlattenPath, GetPath failed\n");
  47. goto exit_DoFlattenPath;
  48. }
  49. // Check for empty path.
  50. if (cpt == 0)
  51. {
  52. b = TRUE;
  53. goto exit_DoFlattenPath;
  54. }
  55. // Allocate memory for the path data.
  56. if (!(pb = (PBYTE) LocalAlloc
  57. (
  58. LMEM_FIXED,
  59. cpt * (sizeof(PointF) + sizeof(POINT) + sizeof(BYTE))
  60. )
  61. )
  62. )
  63. {
  64. RIPS("MF3216: DoFlattenPath, LocalAlloc failed\n");
  65. goto exit_DoFlattenPath;
  66. }
  67. // Order of assignment is important for dword alignment.
  68. pptf = (PointF*) pb;
  69. ppt = (LPPOINT) (pptf + cpt);
  70. pjType = (LPBYTE) (ppt + cpt);
  71. // Finally, get the path data.
  72. if (GetPath(pLocalDC->hdcHelper, ppt, pjType, cpt) != cpt)
  73. {
  74. RIPS("MF3216: DoFlattenPath, GetPath failed\n");
  75. goto exit_DoFlattenPath;
  76. }
  77. if (pfnSetVirtualResolution == NULL)
  78. {
  79. if (!bXformWorkhorse((PPOINTL) ppt, cpt, &pLocalDC->xformRDevToRWorld))
  80. goto exit_DoFlattenPath;
  81. }
  82. BYTE tempType;
  83. for (i = 0; i < cpt; i++)
  84. {
  85. pptf[i] = PointF((REAL) ppt[i].x, (REAL) ppt[i].y);
  86. switch (pjType[i] & ~PT_CLOSEFIGURE)
  87. {
  88. case PT_LINETO:
  89. tempType = PathPointTypeLine;
  90. break;
  91. case PT_MOVETO:
  92. tempType = PathPointTypeStart;
  93. break;
  94. case PT_BEZIERTO:
  95. tempType = PathPointTypeBezier;
  96. break;
  97. default:
  98. WARNING(("MF3216: There's something wrong with this path"));
  99. tempType = PathPointTypeLine;
  100. break;
  101. }
  102. if (pjType[i] & PT_CLOSEFIGURE)
  103. {
  104. tempType |= PathPointTypeCloseSubpath;
  105. }
  106. pjType[i] = tempType;
  107. }
  108. {
  109. XFORM* xform = &(pLocalDC->xformRWorldToPPage);
  110. Matrix matrix((REAL)xform->eM11, (REAL)xform->eM12, (REAL)xform->eM21,
  111. (REAL)xform->eM22, (REAL)xform->eDx, (REAL)xform->eDy);
  112. GraphicsPath gdipPath (pptf,
  113. pjType,
  114. cpt);
  115. // This will transform the flattened point into the resolution of the
  116. // metafile, giving us the best resolution for playtime
  117. gdipPath.Flatten(&matrix, 1.0f/6.0f);
  118. flattenCount = gdipPath.GetPointCount();
  119. if (flattenCount < 0)
  120. {
  121. RIPS("MF3216: GDIP failed in flatting the path\n");
  122. goto exit_DoFlattenPath;
  123. }
  124. if (!(flattenpb = (PBYTE) LocalAlloc
  125. (
  126. LMEM_FIXED,
  127. flattenCount * (sizeof(PointF) + sizeof(BYTE))
  128. )
  129. )
  130. )
  131. {
  132. RIPS("MF3216: DoFlattenPath, LocalAlloc failed\n");
  133. goto exit_DoFlattenPath;
  134. }
  135. flattenPoints = (PointF*) flattenpb;
  136. flattenTypes = (PBYTE) (flattenPoints + flattenCount);
  137. if (!(returnpb = (PBYTE) LocalAlloc
  138. (
  139. LMEM_FIXED,
  140. flattenCount * (sizeof(POINT) + sizeof(BYTE))
  141. )
  142. )
  143. )
  144. {
  145. RIPS("MF3216: DoFlattenPath, LocalAlloc failed\n");
  146. goto exit_DoFlattenPath;
  147. }
  148. ppt = (LPPOINT) returnpb;
  149. pjType = (PBYTE) (ppt + flattenCount);
  150. if (gdipPath.GetPathTypes(flattenTypes, flattenCount) != Ok)
  151. {
  152. RIPS("MF3216: DoFlattenPath, GetPathTypes failed\n");
  153. goto exit_DoFlattenPath;
  154. }
  155. if (gdipPath.GetPathPoints(flattenPoints, flattenCount) != Ok)
  156. {
  157. RIPS("MF3216: DoFlattenPath, GetPathPoints failed\n");
  158. goto exit_DoFlattenPath;
  159. }
  160. for (i = 0; i < flattenCount; i++)
  161. {
  162. ppt[i].x = (INT)(flattenPoints[i].X + 0.5f);
  163. ppt[i].y = (INT)(flattenPoints[i].Y + 0.5f);
  164. switch (flattenTypes[i] & ~PathPointTypeCloseSubpath)
  165. {
  166. case PathPointTypeLine:
  167. tempType = PT_LINETO;
  168. break;
  169. case PathPointTypeStart:
  170. tempType = PT_MOVETO;
  171. break;
  172. break;
  173. default:
  174. WARNING(("MF3216: There's something wrong with this path"));
  175. break;
  176. }
  177. if (flattenTypes[i] & PathPointTypeCloseSubpath)
  178. {
  179. tempType |= PT_CLOSEFIGURE;
  180. }
  181. pjType[i] = tempType;
  182. }
  183. }
  184. *buffer = returnpb;
  185. *count = flattenCount;
  186. returnpb = NULL;
  187. b = TRUE;
  188. exit_DoFlattenPath:
  189. // Cleanup any allocations
  190. if (pb != NULL)
  191. {
  192. LocalFree((HANDLE)pb);
  193. }
  194. if (flattenpb != NULL)
  195. {
  196. LocalFree((HANDLE)flattenpb);
  197. }
  198. // This should only happen if we failed
  199. if (returnpb != NULL)
  200. {
  201. LocalFree((HANDLE)returnpb);
  202. }
  203. return b;
  204. }