static void test_rect(void) { GpStatus status; GpPath *path; GpRectF rects[2]; GdipCreatePath(FillModeAlternate, &path); status = GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0); expect(Ok, status); status = GdipAddPathRectangle(path, 100.0, 50.0, 120.0, 30.0); expect(Ok, status); ok_path(path, rect_path, sizeof(rect_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); GdipCreatePath(FillModeAlternate, &path); rects[0].X = 5.0; rects[0].Y = 5.0; rects[0].Width = 100.0; rects[0].Height = 50.0; rects[1].X = 100.0; rects[1].Y = 50.0; rects[1].Width = 120.0; rects[1].Height = 30.0; status = GdipAddPathRectangles(path, (GDIPCONST GpRectF*)&rects, 2); expect(Ok, status); ok_path(path, rect_path, sizeof(rect_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_arc(void) { GpStatus status; GpPath* path; GdipCreatePath(FillModeAlternate, &path); /* Exactly 90 degrees */ status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0); expect(Ok, status); /* Over 90 degrees */ status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0); expect(Ok, status); /* Negative start angle */ status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0); expect(Ok, status); /* Negative sweep angle */ status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 80.0, -100.0); expect(Ok, status); /* More than a full revolution */ status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 50.0, -400.0); expect(Ok, status); /* 0 sweep angle */ status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 50.0, 0.0); expect(Ok, status); ok_path(path, arc_path, sizeof(arc_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_pathgradientpath(void) { GpStatus status; GpPath *path=NULL; GpPathGradient *grad=NULL; status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad); expect(Ok, status); status = GdipGetPathGradientPath(grad, NULL); expect(NotImplemented, status); status = GdipCreatePath(FillModeWinding, &path); expect(Ok, status); status = GdipGetPathGradientPath(NULL, path); expect(NotImplemented, status); status = GdipGetPathGradientPath(grad, path); expect(NotImplemented, status); status = GdipDeletePath(path); expect(Ok, status); status = GdipDeleteBrush((GpBrush*)grad); expect(Ok, status); }
static M4Err gdip_get_text_size(FontRaster *dr, const unsigned short *string, Float *width, Float *height) { GpPath *path_tmp; GpStringFormat *fmt; FontPriv *ctx = (FontPriv *)dr->priv; *width = *height = 0.0; if (!ctx->font) return M4BadParam; GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &fmt); GdipCreatePath(FillModeAlternate, &path_tmp); RectF rc; rc.X = rc.Y = 0; rc.Width = rc.Height = 0; GdipAddPathString(path_tmp, string, -1, ctx->font, ctx->font_style, ctx->font_size, &rc, fmt); GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL); *width = rc.Width; *height = rc.Height; adjust_white_space(string, width, ctx->whitespace_width ); GdipDeleteStringFormat(fmt); GdipDeletePath(path_tmp); return M4OK; }
static void test_line2(void) { GpStatus status; GpPath* path; int i; GpPointF line2_points[9]; for(i = 0; i < 9; i ++){ line2_points[i].X = i * 5.0 * (REAL)(i % 2); line2_points[i].Y = 50.0 - i * 5.0; } GdipCreatePath(FillModeAlternate, &path); status = GdipAddPathLine2(path, line2_points, 3); expect(Ok, status); status = GdipAddPathLine2(path, &(line2_points[3]), 3); expect(Ok, status); status = GdipClosePathFigure(path); expect(Ok, status); status = GdipAddPathLine2(path, &(line2_points[6]), 3); expect(Ok, status); ok_path(path, line2_path, sizeof(line2_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_empty_rect(void) { GpPath *path; GpStatus status; BOOL result; status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); status = GdipAddPathRectangle(path, 0.0, 0.0, -5.0, 5.0); expect(Ok, status); status = GdipIsVisiblePathPoint(path, -2.0, 2.0, NULL, &result); expect(Ok, status); expect(FALSE, status); status = GdipAddPathRectangle(path, 0.0, 0.0, 5.0, -5.0); expect(Ok, status); status = GdipAddPathRectangle(path, 0.0, 0.0, 0.0, 5.0); expect(Ok, status); status = GdipAddPathRectangle(path, 0.0, 0.0, 5.0, 0.0); expect(Ok, status); GdipDeletePath(path); }
static void test_getpathdata(void) { GpPath *path; GpPathData data; GpStatus status; INT count; status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); status = GdipAddPathLine(path, 5.0, 5.0, 100.0, 50.0); expect(Ok, status); status = GdipGetPointCount(path, &count); expect(Ok, status); expect(2, count); data.Count = count; data.Types = GdipAlloc(sizeof(BYTE) * count); data.Points = GdipAlloc(sizeof(PointF) * count); status = GdipGetPathData(path, &data); expect(Ok, status); expect((data.Points[0].X == 5.0) && (data.Points[0].Y == 5.0) && (data.Points[1].X == 100.0) && (data.Points[1].Y == 50.0), TRUE); expect((data.Types[0] == PathPointTypeStart) && (data.Types[1] == PathPointTypeLine), TRUE); GdipFree(data.Points); GdipFree(data.Types); GdipDeletePath(path); }
static void test_reverse(void) { GpStatus status; GpPath *path; GpPointF pts[7]; INT i; for(i = 0; i < 7; i++){ pts[i].X = i * 5.0 * (REAL)(i % 2); pts[i].Y = 50.0 - i * 5.0; } GdipCreatePath(FillModeAlternate, &path); /* NULL argument */ status = GdipReversePath(NULL); expect(InvalidParameter, status); /* empty path */ status = GdipReversePath(path); expect(Ok, status); GdipAddPathLine2(path, pts, 4); GdipClosePathFigure(path); GdipAddPathLine2(path, &(pts[4]), 3); status = GdipReversePath(path); expect(Ok, status); ok_path(path, reverse_path, sizeof(reverse_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_addclosedcurve(void) { GpStatus status; GpPath *path; GpPointF points[4]; points[0].X = 0.0; points[0].Y = 0.0; points[1].X = 10.0; points[1].Y = 10.0; points[2].X = 10.0; points[2].Y = 20.0; points[3].X = 30.0; points[3].Y = 10.0; GdipCreatePath(FillModeAlternate, &path); /* NULL args */ status = GdipAddPathClosedCurve2(NULL, NULL, 0, 0.0); expect(InvalidParameter, status); status = GdipAddPathClosedCurve2(path, NULL, 0, 0.0); expect(InvalidParameter, status); status = GdipAddPathClosedCurve2(path, points, -1, 0.0); expect(InvalidParameter, status); status = GdipAddPathClosedCurve2(path, points, 1, 1.0); expect(InvalidParameter, status); /* add to empty path */ status = GdipAddPathClosedCurve2(path, points, 4, 1.0); expect(Ok, status); ok_path(path, addclosedcurve_path, sizeof(addclosedcurve_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_addpie(void) { GpStatus status; GpPath *path; GdipCreatePath(FillModeAlternate, &path); /* NULL argument */ status = GdipAddPathPie(NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); expect(InvalidParameter, status); status = GdipAddPathPie(path, 0.0, 0.0, 100.0, 50.0, 10.0, 50.0); expect(Ok, status); ok_path(path, addpie_path, sizeof(addpie_path)/sizeof(path_test_t), FALSE); status = GdipResetPath(path); expect(Ok, status); /* zero width base ellipse */ status = GdipAddPathPie(path, 0.0, 0.0, 0.0, 60.0, -90.0, 24.0); expect(InvalidParameter, status); ok_path(path, addpie_path2, sizeof(addpie_path2)/sizeof(path_test_t), FALSE); status = GdipResetPath(path); expect(Ok, status); /* zero height base ellipse */ status = GdipAddPathPie(path, 0.0, 0.0, 60.0, 0.0 , -90.0, 24.0); expect(InvalidParameter, status); ok_path(path, addpie_path3, sizeof(addpie_path3)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static GF_Err gdip_get_text_size(GF_FontReader *dr, const unsigned short *string, Fixed *width, Fixed *height) { GpPath *path_tmp; GpStringFormat *fmt; FontPriv *ctx = (FontPriv *)dr->udta; *width = *height = 0; if (!ctx->font) return GF_BAD_PARAM; GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &fmt); GdipCreatePath(FillModeAlternate, &path_tmp); RectF rc; rc.X = rc.Y = 0; rc.Width = rc.Height = 0; GdipAddPathString(path_tmp, (const WCHAR *)string, -1, ctx->font, ctx->font_style, ctx->em_size, &rc, fmt); GdipGetPathWorldBounds(path_tmp, &rc, NULL, NULL); adjust_white_space(string, &rc.Width, ctx->whitespace_width); *width = FLT2FIX(rc.Width); *height = FLT2FIX(rc.Height); GdipDeleteStringFormat(fmt); GdipDeletePath(path_tmp); return GF_OK; }
static void test_scale(void) { GpCustomLineCap *custom; GpPath *path; REAL scale; GpStatus stat; stat = GdipCreatePath(FillModeAlternate, &path); expect(Ok, stat); stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0); expect(Ok, stat); stat = GdipCreateCustomLineCap(NULL, path, LineCapFlat, 0.0, &custom); expect(Ok, stat); /* NULL args */ stat = GdipGetCustomLineCapWidthScale(NULL, NULL); expect(InvalidParameter, stat); stat = GdipGetCustomLineCapWidthScale(NULL, &scale); expect(InvalidParameter, stat); stat = GdipGetCustomLineCapWidthScale(custom, NULL); expect(InvalidParameter, stat); /* valid args */ scale = (REAL)0xdeadbeef; stat = GdipGetCustomLineCapWidthScale(custom, &scale); expect(Ok, stat); expectf(1.0, scale); GdipDeleteCustomLineCap(custom); GdipDeletePath(path); }
static void test_inset(void) { GpCustomLineCap *custom; GpPath *path; REAL inset; GpStatus stat; stat = GdipCreatePath(FillModeAlternate, &path); expect(Ok, stat); stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0); expect(Ok, stat); stat = GdipCreateCustomLineCap(NULL, path, LineCapFlat, 0.0, &custom); expect(Ok, stat); /* NULL args */ stat = GdipGetCustomLineCapBaseInset(NULL, NULL); expect(InvalidParameter, stat); stat = GdipGetCustomLineCapBaseInset(NULL, &inset); expect(InvalidParameter, stat); stat = GdipGetCustomLineCapBaseInset(custom, NULL); expect(InvalidParameter, stat); /* valid args */ inset = (REAL)0xdeadbeef; stat = GdipGetCustomLineCapBaseInset(custom, &inset); expect(Ok, stat); expectf(0.0, inset); GdipDeleteCustomLineCap(custom); GdipDeletePath(path); }
static void test_ellipse(void) { GpStatus status; GpPath *path; GpPointF points[2]; points[0].X = 7.0; points[0].Y = 11.0; points[1].X = 13.0; points[1].Y = 17.0; GdipCreatePath(FillModeAlternate, &path); status = GdipAddPathEllipse(path, 10.0, 100.0, 20.0, 50.5); expect(Ok, status); GdipAddPathLine2(path, points, 2); status = GdipAddPathEllipse(path, 10.0, 200.0, -5.0, -10.0); expect(Ok, status); GdipClosePathFigure(path); status = GdipAddPathEllipse(path, 10.0, 300.0, 0.0, 1.0); expect(Ok, status); ok_path(path, ellipse_path, sizeof(ellipse_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_flatten(void) { GpStatus status; GpPath *path; GpMatrix *m; status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); status = GdipCreateMatrix(&m); expect(Ok, status); /* NULL arguments */ status = GdipFlattenPath(NULL, NULL, 0.0); expect(InvalidParameter, status); status = GdipFlattenPath(NULL, m, 0.0); expect(InvalidParameter, status); /* flatten empty path */ status = GdipFlattenPath(path, NULL, 1.0); expect(Ok, status); status = GdipTransformPath(path, 0); expect(Ok, status); status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 50.0); expect(Ok, status); status = GdipFlattenPath(path, NULL, 1.0); expect(Ok, status); ok_path(path, flattenellipse_path, sizeof(flattenellipse_path)/sizeof(path_test_t), TRUE); status = GdipResetPath(path); expect(Ok, status); status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 100.0); expect(Ok, status); status = GdipFlattenPath(path, NULL, 1.0); expect(Ok, status); ok_path(path, flattenline_path, sizeof(flattenline_path)/sizeof(path_test_t), FALSE); status = GdipResetPath(path); expect(Ok, status); status = GdipAddPathArc(path, 0.0, 0.0, 100.0, 50.0, 0.0, 90.0); expect(Ok, status); status = GdipFlattenPath(path, NULL, 1.0); expect(Ok, status); ok_path(path, flattenarc_path, sizeof(flattenarc_path)/sizeof(path_test_t), TRUE); /* easy case - quater of a full circle */ status = GdipResetPath(path); expect(Ok, status); status = GdipAddPathArc(path, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0); expect(Ok, status); status = GdipFlattenPath(path, NULL, 1.0); expect(Ok, status); ok_path(path, flattenquater_path, sizeof(flattenquater_path)/sizeof(path_test_t), FALSE); GdipDeleteMatrix(m); GdipDeletePath(path); }
GpPath *gdip_create_path(GF_Path *_this) { GpPath *p; u32 j, i, nb_pts, cur; if (!_this || !_this->n_points) return NULL; GdipCreatePath(FillModeAlternate, &p); GdipSetPathFillMode(p, (_this->flags & GF_PATH_FILL_ZERO_NONZERO) ? FillModeWinding : FillModeAlternate); cur = 0; for (i=0; i<_this->n_contours; i++) { nb_pts = 1+_this->contours[i] - cur; GdipStartPathFigure(p); for (j=cur+1; j<cur+nb_pts; ) { switch (_this->tags[j]) { case GF_PATH_CURVE_ON: GdipAddPathLine(p, FIX2FLT(_this->points[j-1].x), FIX2FLT(_this->points[j-1].y), FIX2FLT(_this->points[j].x), FIX2FLT(_this->points[j].y)); j++; break; case GF_PATH_CLOSE: GdipAddPathLine(p, FIX2FLT(_this->points[j].x), FIX2FLT(_this->points[j].y), FIX2FLT(_this->points[cur].x), FIX2FLT(_this->points[cur].y)); j++; break; case GF_PATH_CURVE_CUBIC: GdipAddPathBezier(p, FIX2FLT(_this->points[j-1].x), FIX2FLT(_this->points[j-1].y), FIX2FLT(_this->points[j].x), FIX2FLT(_this->points[j].y), FIX2FLT(_this->points[j+1].x), FIX2FLT(_this->points[j+1].y), FIX2FLT(_this->points[j+2].x), FIX2FLT(_this->points[j+2].y) ); j+=3; break; case GF_PATH_CURVE_CONIC: { GF_Point2D ctl, end, c1, c2, start; start = _this->points[j-1]; ctl = _this->points[j]; end = _this->points[j+1]; c1.x = start.x + 2*(ctl.x - start.x) / 3; c1.y = start.y + 2*(ctl.y - start.y) / 3; c2.x = c1.x + (end.x - start.x) / 3; c2.y = c1.y + (end.y - start.y) / 3; GdipAddPathBezier(p, FIX2FLT(start.x), FIX2FLT(start.y), FIX2FLT(c1.x), FIX2FLT(c1.y), FIX2FLT(c2.x), FIX2FLT(c2.y), FIX2FLT(end.x), FIX2FLT(end.y) ); j+=2; } break; } } GdipClosePathFigure(p); cur += nb_pts; } return p; }
static GF_Err gdip_surface_set_clipper(GF_SURFACE _this, GF_IRect *rc) { GPGRAPH(); if (_graph->clip) GdipDeletePath(_graph->clip); _graph->clip = 0L; if (!rc) return GF_OK; GdipCreatePath(FillModeAlternate, &_graph->clip); GdipAddPathRectangleI(_graph->clip, rc->x, rc->y - rc->height, rc->width, rc->height); return GF_OK; }
static void test_pathpath(void) { GpStatus status; GpPath* path1, *path2; GdipCreatePath(FillModeAlternate, &path2); GdipAddPathArc(path2, 100.0, 100.0, 500.0, 700.0, 95.0, 100.0); GdipCreatePath(FillModeAlternate, &path1); GdipAddPathArc(path1, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0); status = GdipAddPathPath(path1, path2, FALSE); expect(Ok, status); GdipAddPathArc(path1, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0); status = GdipAddPathPath(path1, path2, TRUE); expect(Ok, status); ok_path(path1, pathpath_path, sizeof(pathpath_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path1); GdipDeletePath(path2); }
/* Transforms GpRegion elements with given matrix */ static GpStatus transform_region_element(region_element* element, GpMatrix *matrix) { GpStatus stat; switch(element->type) { case RegionDataEmptyRect: case RegionDataInfiniteRect: return Ok; case RegionDataRect: { /* We can't transform a rectangle, so convert it to a path. */ GpRegion *new_region; GpPath *path; stat = GdipCreatePath(FillModeAlternate, &path); if (stat == Ok) { stat = GdipAddPathRectangle(path, element->elementdata.rect.X, element->elementdata.rect.Y, element->elementdata.rect.Width, element->elementdata.rect.Height); if (stat == Ok) stat = GdipCreateRegionPath(path, &new_region); GdipDeletePath(path); } if (stat == Ok) { /* Steal the element from the created region. */ memcpy(element, &new_region->node, sizeof(region_element)); heap_free(new_region); } else return stat; } /* Fall-through to do the actual conversion. */ case RegionDataPath: if (!element->elementdata.path->pathdata.Count) return Ok; stat = GdipTransformMatrixPoints(matrix, element->elementdata.path->pathdata.Points, element->elementdata.path->pathdata.Count); return stat; default: stat = transform_region_element(element->elementdata.combine.left, matrix); if (stat == Ok) stat = transform_region_element(element->elementdata.combine.right, matrix); return stat; } }
static void test_constructor_destructor(void) { GpCustomLineCap *custom; GpPath *path, *path2; GpStatus stat; stat = GdipCreatePath(FillModeAlternate, &path); expect(Ok, stat); stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0); expect(Ok, stat); stat = GdipCreatePath(FillModeAlternate, &path2); expect(Ok, stat); stat = GdipAddPathRectangle(path2, 5.0, 5.0, 10.0, 10.0); expect(Ok, stat); /* NULL args */ stat = GdipCreateCustomLineCap(NULL, NULL, LineCapFlat, 0.0, NULL); expect(InvalidParameter, stat); stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 0.0, NULL); expect(InvalidParameter, stat); stat = GdipCreateCustomLineCap(NULL, path, LineCapFlat, 0.0, NULL); expect(InvalidParameter, stat); stat = GdipCreateCustomLineCap(NULL, NULL, LineCapFlat, 0.0, &custom); expect(InvalidParameter, stat); stat = GdipDeleteCustomLineCap(NULL); expect(InvalidParameter, stat); /* valid args */ stat = GdipCreateCustomLineCap(NULL, path2, LineCapFlat, 0.0, &custom); expect(Ok, stat); stat = GdipDeleteCustomLineCap(custom); expect(Ok, stat); /* it's strange but native returns NotImplemented on stroke == NULL */ stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 10.0, &custom); todo_wine expect(NotImplemented, stat); GdipDeletePath(path2); GdipDeletePath(path); }
static void test_isvisible(void) { GpPath *path; GpGraphics *graphics = NULL; HDC hdc = GetDC(0); BOOL result; GpStatus status; status = GdipCreateFromHDC(hdc, &graphics); expect(Ok, status); status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); /* NULL */ status = GdipIsVisiblePathPoint(NULL, 0.0, 0.0, NULL, NULL); expect(InvalidParameter, status); status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, NULL); expect(InvalidParameter, status); status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, NULL); expect(InvalidParameter, status); status = GdipIsVisiblePathPoint(path, 0.0, 0.0, graphics, NULL); expect(InvalidParameter, status); /* empty path */ result = TRUE; status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, &result); expect(Ok, status); expect(FALSE, result); /* rect */ status = GdipAddPathRectangle(path, 0.0, 0.0, 10.0, 10.0); expect(Ok, status); result = FALSE; status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, &result); expect(Ok, status); expect(TRUE, result); result = TRUE; status = GdipIsVisiblePathPoint(path, 11.0, 11.0, NULL, &result); expect(Ok, status); expect(FALSE, result); /* not affected by clipping */ status = GdipSetClipRect(graphics, 5.0, 5.0, 5.0, 5.0, CombineModeReplace); expect(Ok, status); result = FALSE; status = GdipIsVisiblePathPoint(path, 0.0, 0.0, graphics, &result); expect(Ok, status); expect(TRUE, result); GdipDeletePath(path); GdipDeleteGraphics(graphics); ReleaseDC(0, hdc); }
static void test_linejoin(void) { GpCustomLineCap *custom; GpPath *path; GpLineJoin join; GpStatus stat; stat = GdipCreatePath(FillModeAlternate, &path); expect(Ok, stat); stat = GdipAddPathRectangle(path, 5.0, 5.0, 10.0, 10.0); expect(Ok, stat); stat = GdipCreateCustomLineCap(NULL, path, LineCapFlat, 0.0, &custom); expect(Ok, stat); /* NULL args */ stat = GdipGetCustomLineCapStrokeJoin(NULL, NULL); expect(InvalidParameter, stat); stat = GdipGetCustomLineCapStrokeJoin(custom, NULL); expect(InvalidParameter, stat); stat = GdipGetCustomLineCapStrokeJoin(NULL, &join); expect(InvalidParameter, stat); stat = GdipSetCustomLineCapStrokeJoin(NULL, LineJoinBevel); expect(InvalidParameter, stat); /* LineJoinMiter is default */ stat = GdipGetCustomLineCapStrokeJoin(custom, &join); expect(Ok, stat); expect(LineJoinMiter, join); /* set/get */ stat = GdipSetCustomLineCapStrokeJoin(custom, LineJoinBevel); expect(Ok, stat); stat = GdipGetCustomLineCapStrokeJoin(custom, &join); expect(Ok, stat); expect(LineJoinBevel, join); stat = GdipSetCustomLineCapStrokeJoin(custom, LineJoinRound); expect(Ok, stat); stat = GdipGetCustomLineCapStrokeJoin(custom, &join); expect(Ok, stat); expect(LineJoinRound, join); stat = GdipSetCustomLineCapStrokeJoin(custom, LineJoinMiterClipped); expect(Ok, stat); stat = GdipGetCustomLineCapStrokeJoin(custom, &join); expect(Ok, stat); expect(LineJoinMiterClipped, join); GdipDeleteCustomLineCap(custom); GdipDeletePath(path); }
static void test_constructor_destructor(void) { GpStatus status; GpPath* path = NULL; status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); ok(path != NULL, "Expected path to be initialized\n"); status = GdipDeletePath(NULL); expect(InvalidParameter, status); status = GdipDeletePath(path); expect(Ok, status); }
static void test_linei(void) { GpStatus status; GpPath *path; GdipCreatePath(FillModeAlternate, &path); status = GdipAddPathLineI(path, 5.0, 5.0, 6.0, 8.0); expect(Ok, status); GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0); status = GdipAddPathLineI(path, 15.0, 15.0, 26.0, 28.0); expect(Ok, status); GdipClosePathFigure(path); status = GdipAddPathLineI(path, 35.0, 35.0, 36.0, 38.0); expect(Ok, status); ok_path(path, linei_path, sizeof(linei_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static void test_polygon(void) { GpStatus status; GpPath *path; GpPointF points[5]; points[0].X = 0.0; points[0].Y = 0.0; points[1].X = 10.0; points[1].Y = 10.0; points[2].X = 10.0; points[2].Y = 20.0; points[3].X = 30.0; points[3].Y = 10.0; points[4].X = 20.0; points[4].Y = 0.0; GdipCreatePath(FillModeAlternate, &path); /* NULL args */ status = GdipAddPathPolygon(NULL, points, 5); expect(InvalidParameter, status); status = GdipAddPathPolygon(path, NULL, 5); expect(InvalidParameter, status); /* Polygon should have 3 points at least */ status = GdipAddPathPolygon(path, points, 2); expect(InvalidParameter, status); /* to test how it prolongs not empty path */ status = GdipAddPathLine(path, 5.0, 5.0, 6.0, 8.0); expect(Ok, status); status = GdipAddPathPolygon(path, points, 5); expect(Ok, status); /* check resulting path */ ok_path(path, poly_path, sizeof(poly_path)/sizeof(path_test_t), FALSE); GdipDeletePath(path); }
static GF_Err gdip_surface_clear(GF_SURFACE _this, GF_IRect *rc, u32 color) { GpPath *path; GPGRAPH(); GdipCreatePath(FillModeAlternate, &path); if (rc) { /*luckily enough this maps well for both flipped and unflipped coords*/ GdipAddPathRectangleI(path, rc->x, rc->y - rc->height, rc->width, rc->height); } else { /* if (_graph->center_coords) { GdipAddPathRectangleI(path, -1 * (s32)_graph->w / 2, -1 * (s32)_graph->h / 2, _graph->w, _graph->h); } else { */ GdipAddPathRectangleI(path, 0, 0, _graph->w, _graph->h); // } } /*we MUST use clear otherwise ARGB surfaces are not cleared correctly*/ GdipSetClipPath(_graph->graph, path, CombineModeReplace); GdipGraphicsClear(_graph->graph, color); GdipDeletePath(path); return GF_OK; }
static void test_lastpoint(void) { GpStatus status; GpPath *path; GpPointF ptf; GdipCreatePath(FillModeAlternate, &path); status = GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0); expect(Ok, status); /* invalid args */ status = GdipGetPathLastPoint(NULL, &ptf); expect(InvalidParameter, status); status = GdipGetPathLastPoint(path, NULL); expect(InvalidParameter, status); status = GdipGetPathLastPoint(NULL, NULL); expect(InvalidParameter, status); status = GdipGetPathLastPoint(path, &ptf); expect(Ok, status); expect(TRUE, (ptf.X == 5.0) && (ptf.Y == 55.0)); GdipDeletePath(path); }
static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element *node, INT *count) { GpStatus status; const DWORD *type; type = buffer_read(mbuf, sizeof(*type)); if (!type) return Ok; TRACE("type %#x\n", *type); node->type = *type; switch (node->type) { case CombineModeReplace: case CombineModeIntersect: case CombineModeUnion: case CombineModeXor: case CombineModeExclude: case CombineModeComplement: { region_element *left, *right; left = heap_alloc_zero(sizeof(region_element)); if (!left) return OutOfMemory; right = heap_alloc_zero(sizeof(region_element)); if (!right) { heap_free(left); return OutOfMemory; } status = read_element(mbuf, region, left, count); if (status == Ok) { status = read_element(mbuf, region, right, count); if (status == Ok) { node->elementdata.combine.left = left; node->elementdata.combine.right = right; region->num_children += 2; return Ok; } } heap_free(left); heap_free(right); return status; } case RegionDataRect: { const GpRectF *rc; rc = buffer_read(mbuf, sizeof(*rc)); if (!rc) { ERR("failed to read rect data\n"); return InvalidParameter; } node->elementdata.rect = *rc; *count += 1; return Ok; } case RegionDataPath: { GpPath *path; const struct path_header *path_header; const BYTE *types; path_header = buffer_read(mbuf, sizeof(*path_header)); if (!path_header) { ERR("failed to read path header\n"); return InvalidParameter; } if (!VALID_MAGIC(path_header->magic)) { ERR("invalid path header magic %#x\n", path_header->magic); return InvalidParameter; } /* Windows always fails to create an empty path in a region */ if (!path_header->count) { TRACE("refusing to create an empty path in a region\n"); return GenericError; } status = GdipCreatePath(FillModeAlternate, &path); if (status) return status; node->elementdata.path = path; if (!lengthen_path(path, path_header->count)) return OutOfMemory; path->pathdata.Count = path_header->count; if (path_header->flags & ~FLAGS_INTPATH) FIXME("unhandled path flags %#x\n", path_header->flags); if (path_header->flags & FLAGS_INTPATH) { const packed_point *pt; DWORD i; pt = buffer_read(mbuf, sizeof(*pt) * path_header->count); if (!pt) { ERR("failed to read packed %u path points\n", path_header->count); return InvalidParameter; } for (i = 0; i < path_header->count; i++) { path->pathdata.Points[i].X = (REAL)pt[i].X; path->pathdata.Points[i].Y = (REAL)pt[i].Y; } } else { const GpPointF *ptf; ptf = buffer_read(mbuf, sizeof(*ptf) * path_header->count); if (!ptf) { ERR("failed to read %u path points\n", path_header->count); return InvalidParameter; } memcpy(path->pathdata.Points, ptf, sizeof(*ptf) * path_header->count); } types = buffer_read(mbuf, path_header->count); if (!types) { ERR("failed to read %u path types\n", path_header->count); return InvalidParameter; } memcpy(path->pathdata.Types, types, path_header->count); if (path_header->count & 3) { if (!buffer_read(mbuf, 4 - (path_header->count & 3))) { ERR("failed to read rounding %u bytes\n", 4 - (path_header->count & 3)); return InvalidParameter; } } *count += 1; return Ok; } case RegionDataEmptyRect: case RegionDataInfiniteRect: *count += 1; return Ok; default: FIXME("element type %#x is not supported\n", *type); break; } return InvalidParameter; }
/****************************************************************************** * GdipCreateRegionHrgn [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region) { DWORD size; LPRGNDATA buf; LPRECT rect; GpStatus stat; GpPath* path; GpRegion* local; DWORD i; TRACE("(%p, %p)\n", hrgn, region); if(!region || !(size = GetRegionData(hrgn, 0, NULL))) return InvalidParameter; buf = heap_alloc_zero(size); if(!buf) return OutOfMemory; if(!GetRegionData(hrgn, size, buf)){ heap_free(buf); return GenericError; } if(buf->rdh.nCount == 0){ if((stat = GdipCreateRegion(&local)) != Ok){ heap_free(buf); return stat; } if((stat = GdipSetEmpty(local)) != Ok){ heap_free(buf); GdipDeleteRegion(local); return stat; } *region = local; heap_free(buf); return Ok; } if((stat = GdipCreatePath(FillModeAlternate, &path)) != Ok){ heap_free(buf); return stat; } rect = (LPRECT)buf->Buffer; for(i = 0; i < buf->rdh.nCount; i++){ if((stat = GdipAddPathRectangle(path, (REAL)rect->left, (REAL)rect->top, (REAL)(rect->right - rect->left), (REAL)(rect->bottom - rect->top))) != Ok){ heap_free(buf); GdipDeletePath(path); return stat; } rect++; } stat = GdipCreateRegionPath(path, region); heap_free(buf); GdipDeletePath(path); return stat; }
static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn) { switch (element->type) { case RegionDataInfiniteRect: *hrgn = NULL; return Ok; case RegionDataEmptyRect: *hrgn = CreateRectRgn(0, 0, 0, 0); return *hrgn ? Ok : OutOfMemory; case RegionDataPath: return get_path_hrgn(element->elementdata.path, graphics, hrgn); case RegionDataRect: { GpPath* path; GpStatus stat; GpRectF* rc = &element->elementdata.rect; stat = GdipCreatePath(FillModeAlternate, &path); if (stat != Ok) return stat; stat = GdipAddPathRectangle(path, rc->X, rc->Y, rc->Width, rc->Height); if (stat == Ok) stat = get_path_hrgn(path, graphics, hrgn); GdipDeletePath(path); return stat; } case CombineModeIntersect: case CombineModeUnion: case CombineModeXor: case CombineModeExclude: case CombineModeComplement: { HRGN left, right; GpStatus stat; int ret; stat = get_region_hrgn(element->elementdata.combine.left, graphics, &left); if (stat != Ok) { *hrgn = NULL; return stat; } if (left == NULL) { /* existing region is infinite */ switch (element->type) { case CombineModeIntersect: return get_region_hrgn(element->elementdata.combine.right, graphics, hrgn); case CombineModeXor: case CombineModeExclude: left = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22); break; case CombineModeUnion: case CombineModeComplement: *hrgn = NULL; return Ok; } } stat = get_region_hrgn(element->elementdata.combine.right, graphics, &right); if (stat != Ok) { DeleteObject(left); *hrgn = NULL; return stat; } if (right == NULL) { /* new region is infinite */ switch (element->type) { case CombineModeIntersect: *hrgn = left; return Ok; case CombineModeXor: case CombineModeComplement: right = CreateRectRgn(-(1 << 22), -(1 << 22), 1 << 22, 1 << 22); break; case CombineModeUnion: case CombineModeExclude: DeleteObject(left); *hrgn = NULL; return Ok; } } switch (element->type) { case CombineModeIntersect: ret = CombineRgn(left, left, right, RGN_AND); break; case CombineModeUnion: ret = CombineRgn(left, left, right, RGN_OR); break; case CombineModeXor: ret = CombineRgn(left, left, right, RGN_XOR); break; case CombineModeExclude: ret = CombineRgn(left, left, right, RGN_DIFF); break; case CombineModeComplement: ret = CombineRgn(left, right, left, RGN_DIFF); break; default: ret = ERROR; } DeleteObject(right); if (ret == ERROR) { DeleteObject(left); *hrgn = NULL; return GenericError; } *hrgn = left; return Ok; } default: FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type); *hrgn = NULL; return NotImplemented; } }