4 * Author: Duncan Mak (duncan@ximian.com)
6 * Copyright (C) 2003, Novell Inc.
12 #include "graphics-path.h"
15 array_to_g_array (const GpPointF *pt, int length)
17 GArray *p = g_array_sized_new (FALSE, TRUE, sizeof (GpPointF), length);
18 g_array_append_vals (p, pt, length);
23 g_array_to_array (GArray *p)
26 GpPointF *pts = (GpPointF *) GdipAlloc (sizeof (GpPointF) * length);
28 memcpy (pts, p->data, p->len * sizeof (GpPointF));
34 g_byte_array_to_array (GByteArray *p)
37 byte *types = (byte *) GdipAlloc (sizeof (byte) * length);
39 memcpy (types, p->data, p->len * sizeof (byte));
45 array_to_g_byte_array (const byte *types, int count)
47 GByteArray *p = g_byte_array_sized_new (count);
48 g_byte_array_append (p, types, count);
53 float_to_int (const GpPointF *pts, int count)
55 GpPoint *p = (GpPoint *) GdipAlloc (sizeof (GpPoint) * count);
56 GpPointF *tmp = (GpPointF *) pts;
59 for (i = 0; i < count; i++, p++, tmp++) {
68 int_to_float (const GpPoint *pts, int count)
70 GpPointF *p = (GpPointF *) GdipAlloc (sizeof (GpPointF) * count);
71 GpPoint *tmp = (GpPoint *) pts;
74 for (i = 0; i < count; i++, p++, tmp++) {
75 p->X = (float) tmp->X;
76 p->Y = (float) tmp->Y;
83 append (GpPath *path, float x, float y, GpPathPointType type)
86 GpPointF pt = { x, y };
87 g_array_append_val (path->points, pt);
88 g_byte_array_append (path->types, &t, 1);
92 append_point (GpPath *path, GpPointF pt, GpPathPointType type)
95 g_array_append_val (path->points, pt);
96 g_byte_array_append (path->types, &t, 1);
100 append_bezier (GpPath *path, float x1, float y1, float x2, float y2, float x3, float y3)
102 append (path, x1, y1, PathPointTypeBezier3);
103 append (path, x2, y2, PathPointTypeBezier3);
104 append (path, x3, y3, PathPointTypeBezier3);
108 GdipCreatePath (GpFillMode brushMode, GpPath **path)
110 *path = (GpPath *) GdipAlloc (sizeof (GpPath));
112 (*path)->fill_mode = brushMode;
113 (*path)->points = NULL;
114 (*path)->types = NULL;
121 GdipCreatePath2 (const GpPointF *points, const byte *types,
122 int count, GpFillMode fillMode, GpPath **path)
124 GArray *pts = array_to_g_array (points, count);
125 GByteArray *t = array_to_g_byte_array (types, count);
127 *path = (GpPath *) GdipAlloc (sizeof (GpPath));
128 (*path)->fill_mode = fillMode;
129 (*path)->count = count;
130 (*path)->points = pts;
137 GdipClonePath (GpPath *path, GpPath **clonePath)
139 *clonePath = (GpPath *) GdipAlloc (sizeof (GpPath));
140 (*clonePath)->fill_mode = path->fill_mode;
141 (*clonePath)->count = path->count;
142 (*clonePath)->points = path->points;
143 (*clonePath)->types = path->types;
149 GdipDeletePath (GpPath *path)
151 if (path->count != 0) {
152 if (path->points != NULL)
153 g_array_free (path->points, TRUE);
155 if (path->types != NULL)
156 g_byte_array_free (path->types, TRUE);
164 GdipResetPath (GpPath *path)
174 GdipGetPointCount (GpPath *path, int *count)
176 *count = path->count;
181 GdipGetPathTypes (GpPath *path, byte *types, int *count)
183 *count = path->count;
184 types = g_byte_array_to_array (path->types);
190 GdipGetPathPoints (GpPath *path, GpPointF *points, int *count)
192 *count = path->count;
193 points = g_array_to_array (path->points);
199 GdipGetPathPointsI (GpPath *path, GpPoint *points, int *count)
201 *count = path->count;
202 PointF *tmp = g_array_to_array (path->points);
204 points = float_to_int (tmp, path->count);
212 GdipGetPathFillMode (GpPath *path, GpFillMode *fillmode)
214 *fillmode = path->fill_mode;
220 GdipSetPathFillMode (GpPath *path, GpFillMode fillmode)
222 path->fill_mode = fillmode;
228 GdipGetPathData (GpPath *path, GpPathData *pathData)
230 pathData->Count = path->count;
231 pathData->Points = g_array_to_array (path->points);
232 pathData->Types = g_byte_array_to_array (path->types);
238 GdipStartPathFigure (GpPath *path)
240 return NotImplemented;
244 GdipClosePathFigure (GpPath *path)
246 return NotImplemented;
250 GdipClosePathFigures (GpPath *path)
252 return NotImplemented;
256 GdipSetPathMarker (GpPath *path)
258 return NotImplemented;
262 GdipClearPathMarkers (GpPath *path)
264 return NotImplemented;
268 GdipReversePath (GpPath *path)
270 int length= path->count;
271 GByteArray *types = g_byte_array_sized_new (length);
272 GArray *points = g_array_sized_new (FALSE, TRUE, sizeof (GpPointF), length);
274 for (i = length; i > 0; i--) {
275 byte t = g_array_index (path->types, byte, i);
276 GpPointF pt = g_array_index (path->points, GpPointF, i);
278 g_byte_array_append (types, &t, 1);
279 g_array_append_val (points, pt);
281 path->points = points;
288 GdipGetPathLastPoint (GpPath *path, GpPointF *lastPoint)
290 *lastPoint = g_array_index (path->points, GpPointF, path->count);
295 GdipAddPathLine (GpPath *path, float x1, float y1, float x2, float y2)
297 PointF p1 = { x1, y1 };
298 PointF p2 = { x2, y2 };
299 append_point (path, p1, PathPointTypeStart);
300 append_point (path, p2, PathPointTypeLine);
306 GdipAddPathLine2 (GpPath *path, const GpPointF *points, int count)
309 GpPointF *tmp = (GpPointF *) points;
311 for (i = 0; i < count; i++, tmp++)
312 append_point (path, *tmp, PathPointTypeLine);
318 GdipAddPathArc (GpPath *path, float x, float y,
319 float width, float height, float startAngle, float sweepAngle)
321 float rx = width / 2;
322 float ry = height / 2;
328 /* angles in radians */
329 float alpha = startAngle * PI / 180;
330 float beta = sweepAngle * PI / 180;
332 float delta = beta - alpha;
333 float bcp = 4.0 / 3 * (1 - cos (delta / 2)) / sin (delta /2);
335 float sin_alpha = sin (alpha);
336 float sin_beta = sin (beta);
337 float cos_alpha = cos (alpha);
338 float cos_beta = cos (beta);
346 cx + rx * (cos_alpha - bcp * sin_alpha),
347 cy + ry * (sin_alpha + bcp * cos_alpha),
348 cx + rx * (cos_beta + bcp * sin_beta),
349 cy + ry * (sin_beta - bcp * cos_beta),
357 GdipAddPathBezier (GpPath *path,
358 float x1, float y1, float x2, float y2,
359 float x3, float y3, float x4, float y4)
361 append (path, x1, y1, PathPointTypeStart);
362 append_bezier (path, x2, y2, x3, y3, x4, y4);
368 GdipAddPathBeziers (GpPath *path, const GpPointF *points, int count)
371 GpPointF *tmp = (GpPointF *) points;
373 append_point (path, *tmp, PathPointTypeStart);
376 for (i = 1; i < count; i++, tmp++)
377 append_point (path, *tmp, PathPointTypeBezier3);
383 GdipAddPathCurve (GpPath *path, const GpPointF *points, int count)
385 return NotImplemented;
389 GdipAddPathCurve2 (GpPath *path, const GpPointF *points, int count, float tension)
391 return NotImplemented;
395 GdipAddPathCurve3 (GpPath *path, const GpPointF *points, int count,
396 int offset, int numberOfSegments, float tension)
398 return NotImplemented;
402 GdipAddPathClosedCurve (GpPath *path, const GpPointF *points, int count)
404 return GdipAddPathClosedCurve2 (path, points, count, 0.5);
408 GdipAddPathClosedCurve2 (GpPath *path, const GpPointF *points, int count, float tension)
410 return NotImplemented;
414 GdipAddPathRectangle (GpPath *path, float x, float y, float width, float height)
416 append (path, x, y, PathPointTypeLine);
417 append (path, x + width, y, PathPointTypeLine);
418 append (path, x + width, y + height, PathPointTypeLine);
419 append (path, x, y + height, PathPointTypeLine);
425 GdipAddPathRectangles (GpPath *path, const GpRectF *rects, int count)
428 for (i = 0; i < count; i++, rects++) {
429 float x = rects->left;
430 float y = rects->top;
431 float width = rects->right - rects->left;
432 float height = rects->bottom - rects->top;
433 GdipAddPathRectangle (path, x, y, width, height);
440 GdipAddPathEllipse (GpPath *path, float x, float y, float width, float height)
443 double rx = width / 2;
444 double ry = height / 2;
449 append (path, cx + rx, cy, PathPointTypeStart);
453 cx + rx, cy - C1 * ry,
454 cx + C1 * rx, cy - ry,
459 cx - C1 * rx, cy - ry,
460 cx - rx, cy - C1 * ry,
465 cx - rx, cy + C1 * ry,
466 cx - C1 * rx, cy + ry,
471 cx + C1 * rx, cy + ry,
472 cx + rx, cy + C1 * ry,
479 GdipAddPathPie (GpPath *path, float x, float y, float width, float height, float startAngle, float sweepAngle)
481 float rx = width / 2;
482 float ry = height / 2;
486 /* angles in radians */
487 float alpha = startAngle * PI / 180;
488 float beta = sweepAngle * PI / 180;
490 float delta = beta - alpha;
491 float bcp = 4.0 / 3 * (1 - cos (delta / 2)) / sin (delta /2);
493 float sin_alpha = sin (alpha);
494 float sin_beta = sin (beta);
495 float cos_alpha = cos (alpha);
496 float cos_beta = cos (beta);
499 append (path, cx, cy, PathPointTypeStart);
503 append (path, cx + rx * cos_alpha, cy + ry * sin_alpha,
508 cx + rx * (cos_alpha - bcp * sin_alpha),
509 cy + ry * (sin_alpha + bcp * cos_alpha),
510 cx + rx * (cos_beta + bcp * sin_beta),
511 cy + ry * (sin_beta - bcp * cos_beta),
516 append (path, cx, cy, PathPointTypeLine);
522 GdipAddPathPolygon (GpPath *path, const GpPointF *points, int count)
525 GpPointF *tmp = (GpPointF *) points;
527 append_point (path, *tmp, PathPointTypeStart);
530 for (i = 1; i < count; i++, tmp++)
531 append_point (path, *tmp, PathPointTypeLine);
537 GdipAddPathPath (GpPath *path, GpPath *addingPath, bool connect)
539 /* XXX:need to understand the connect argument */
541 return NotImplemented;
544 /* XXX: This one is really hard. They really translate a string into bezier points and what not */
547 * GdipAddString (GpPath *path, const char *string, int length,
548 * const GpFontFamily *family, int style, float emSize, const GpRectF *layoutRect, const GpStringFormat *format)
550 * return NotImplemented;
556 * GdipAddString (GpPath *path, const char *string, int length,
557 * const GpFontFamily *family, int style, float emSize, const GpRect *layoutRect, const GpStringFormat *format)
559 * return NotImplemented;
564 GdipAddPathLineI (GpPath *path, int x1, int y1, int x2, int y2)
566 append (path, x1, y1, PathPointTypeStart);
567 append (path, x2, y2, PathPointTypeLine);
573 GdipAddPathLine2I (GpPath* path, const GpPoint *points, int count)
576 GpPointF *tmp = int_to_float (points, count);
578 append_point (path, *tmp, PathPointTypeStart);
581 for (i = 1; i < count; i++, tmp++)
582 append_point (path, *tmp, PathPointTypeLine);
590 GdipAddPathArcI (GpPath *path, int x, int y, int width, int height, float startAngle, float sweepAngle)
592 return GdipAddPathArc (path, x, y, width, height, startAngle, sweepAngle);
596 GdipAddPathBezierI (GpPath *path, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
598 return GdipAddPathBezier (path, x1, y1, x2, y2, x3, y3, x4, y4);
602 GdipAddPathBeziersI (GpPath *path, const GpPoint *points, int count)
604 GpPointF *tmp = int_to_float (points, count);
605 Status s = GdipAddPathBeziers (path, tmp, count);
613 GdipAddPathCurveI (GpPath *path, const GpPoint *points, int count)
615 return GdipAddPathCurve2I (path, points, count, 0.5);
619 GdipAddPathCurve2I (GpPath *path, const GpPoint *points, int count, float tension)
621 return NotImplemented;
625 GdipAddPathCurve3I (GpPath *path, const GpPoint *points,
626 int count, int offset, int numberOfSegments, float tension)
628 return NotImplemented;
632 GdipAddPathClosedCurveI (GpPath *path, const GpPoint *points, int count)
634 return GdipAddPathClosedCurve2I (path, points, count, 0.5);
638 GdipAddPathClosedCurve2I (GpPath *path, const GpPoint *points, int count, float tension)
640 return NotImplemented;
644 GdipAddPathRectangleI (GpPath *path, int x, int y, int width, int height)
646 return GdipAddPathRectangle (path, x, y, width, height);
650 GdipAddPathRectanglesI (GpPath *path, const GpRect *rects, int count)
653 for (i = 0; i < count; i++, rects++) {
654 float x = (float) rects->left;
655 float y = (float) rects->top;
656 float width = (float) (rects->right - rects->left);
657 float height = (float) (rects->bottom - rects->top);
658 GdipAddPathRectangle (path, x, y, width, height);
665 GdipAddPathEllipseI (GpPath *path, int x, int y, int width, int height)
667 return GdipAddPathEllipse (path, x, y, width, height);
671 GdipAddPathPieI (GpPath *path, int x, int y, int width, int height, float startAngle, float sweepAngle)
673 return GdipAddPathPie (path, x, y, width, height, startAngle, sweepAngle);
677 GdipAddPathPolygonI (GpPath *path, const GpPoint *points, int count)
679 GpPointF *tmp = int_to_float (points, count);
681 Status s = GdipAddPathPolygon (path, tmp, count);
689 GdipFlattenPath (GpPath *path, GpMatrix *matrix, float flatness)
691 return NotImplemented;
695 GdipWindingModeOutline (GpPath *path, GpMatrix *matrix, float flatness)
697 return NotImplemented;
701 GdipWidenPath (GpPath *nativePath, GpPen *pen, GpMatrix *matrix, float flatness)
703 return NotImplemented;
707 GdipWarpPath (GpPath *nativePath, GpMatrix *matrix, const GpPointF *points, int count,
708 float src, float srcy, float srcwidth, float srcheight, WarpMode warpMode, float flatness)
710 return NotImplemented;
714 GdipTransformPath (GpPath* path, GpMatrix *matrix)
716 PointF *points = g_array_to_array (path->points);
717 Status s = GdipTransformMatrixPoints (matrix, points, path->count);
725 GdipGetPathWorldBounds (GpPath *path, GpRectF *bounds, const GpMatrix *matrix, const GpPen *pen)
727 return NotImplemented;
731 GdipGetPathWorldBoundsI (GpPath *path, GpRect *bounds, const GpMatrix *matrix, const GpPen *pen)
733 return NotImplemented;
737 GdipIsVisiblePathPoint (GpPath *path, float x, float y, GpGraphics *graphics, bool *result)
739 return NotImplemented;
743 GdipIsVisiblePathPointI (GpPath *path, int x, int y, GpGraphics *graphics, bool *result)
745 return NotImplemented;
749 GdipIsOutlineVisiblePathPoint (GpPath *path, float x, float y, GpGraphics *graphics, bool *result)
751 return NotImplemented;
755 GdipIsOutlineVisiblePathPointI (GpPath *path, int x, int y, GpGraphics *graphics, bool *result)
757 return NotImplemented;