void createRadial() { VGfloat stops[] = { 0.0, 1.0, 0.0, 0.0, 1, 0.5, 0.0, 1.0, 0.0, 1, 1.0, 0.0, 0.0, 1.0, 1}; VGint numstops = sizeof(stops) / sizeof(VGfloat); VGfloat radial[5]; radial[0] = cx; radial[1] = cy; radial[2] = fx; radial[3] = fy; radial[4] = r; vgSetParameteri(radialFill, VG_PAINT_COLOR_RAMP_SPREAD_MODE, spread[sindex]); vgSetParameteri(radialFill, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT); vgSetParameterfv(radialFill, VG_PAINT_RADIAL_GRADIENT, 5, radial); vgSetParameterfv(radialFill, VG_PAINT_COLOR_RAMP_STOPS, numstops, stops); vgClearPath(center, VG_PATH_CAPABILITY_ALL); createCross(center, cx, cy); vgClearPath(focus, VG_PATH_CAPABILITY_ALL); vguEllipse(focus, fx, fy, 8,8); vgClearPath(radius, VG_PATH_CAPABILITY_ALL); vguEllipse(radius, cx, cy, r*2, r*2); }
void PainterOpenVG::drawEllipse(const IntRect& rect, VGbitfield specifiedPaintModes) { ASSERT(m_state); VGbitfield paintModes = 0; if (!m_state->strokeDisabled()) paintModes |= VG_STROKE_PATH; if (!m_state->fillDisabled()) paintModes |= VG_FILL_PATH; paintModes &= specifiedPaintModes; if (!paintModes) return; m_surface->makeCurrent(); VGPath path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0 /* scale */, 0.0 /* bias */, 4 /* expected number of segments */, 12 /* expected number of total coordinates */, VG_PATH_CAPABILITY_APPEND_TO); ASSERT_VG_NO_ERROR(); if (vguEllipse(path, rect.x() + rect.width() / 2.0, rect.y() + rect.height() / 2.0, rect.width(), rect.height()) == VGU_NO_ERROR) { vgDrawPath(path, paintModes); ASSERT_VG_NO_ERROR(); } vgDestroyPath(path); ASSERT_VG_NO_ERROR(); }
void createPrimitives() { VGfloat points[] = {-30,-30, 30,-30, 0,30}; line = testCreatePath(); vguLine(line, -30,-30,30,30); primitives[0] = line; polyOpen = testCreatePath(); vguPolygon(polyOpen, points, 3, VG_FALSE); primitives[1] = polyOpen; polyClosed = testCreatePath(); vguPolygon(polyClosed, points, 3, VG_TRUE); primitives[2] = polyClosed; rect = testCreatePath(); vguRect(rect, -50,-30, 100,60); primitives[3] = rect; rectRound = testCreatePath(); vguRoundRect(rectRound, -50,-30, 100,60, 30,30); primitives[4] = rectRound; ellipse = testCreatePath(); vguEllipse(ellipse, 0,0, 100, 100); primitives[5] = ellipse; arcOpen = testCreatePath(); vguArc(arcOpen, 0,0, 100,60, 0, 270, VGU_ARC_OPEN); primitives[6] = arcOpen; arcChord = testCreatePath(); vguArc(arcChord, 0,0, 100,60, 0, 270, VGU_ARC_CHORD); primitives[7] = arcChord; arcPie = testCreatePath(); vguArc(arcPie, 0,0, 100,60, 0, 270, VGU_ARC_PIE); primitives[8] = arcPie; }
void Path::addEllipse(const FloatRect& rect) { if (rect.isEmpty()) { moveTo(rect.location()); if (rect.width() > FLT_EPSILON) { addLineTo(FloatPoint(rect.x() + rect.width(), rect.y())); closeSubpath(); } else if (rect.height() > FLT_EPSILON) { addLineTo(FloatPoint(rect.x(), rect.y() + rect.height())); closeSubpath(); } return; } m_path->makeCompatibleContextCurrent(); VGUErrorCode error = vguEllipse(m_path->vgPath(), rect.x() + rect.width() / 2.0, rect.y() + rect.height() / 2.0, rect.width(), rect.height()); ASSERT(error == VGU_NO_ERROR); }
// EllipseOutline makes an ellipse at the specified location and dimensions, outlined void EllipseOutline(VGfloat x, VGfloat y, VGfloat w, VGfloat h) { VGPath path = newpath(); vguEllipse(path, x, y, w, h); vgDrawPath(path, VG_STROKE_PATH); vgDestroyPath(path); }
void simpleVGPath::ellipse(float x, float y, float w, float h) { vguEllipse(_path, x, y, w, h); }
void Path::addArc(const FloatPoint& center, float radius, float startAngle, float endAngle, bool anticlockwise) { // The OpenVG spec says nothing about inf as radius or start/end angle. // WebKit seems to pass those (e.g. https://bugs.webkit.org/show_bug.cgi?id=16449), // so abort instead of risking undefined behavior. if (!isfinite(radius) || !isfinite(startAngle) || !isfinite(endAngle)) return; // For some reason, the HTML 5 spec defines the angle as going clockwise // from the positive X axis instead of going standard anticlockwise. // So let's make it a proper angle in order to keep sanity. startAngle = fmod((2.0 * piDouble) - startAngle, 2.0 * piDouble); endAngle = fmod((2.0 * piDouble) - endAngle, 2.0 * piDouble); // Make it so that endAngle > startAngle. fmod() above takes care of // keeping the difference below 360 degrees. if (endAngle <= startAngle) endAngle += 2.0 * piDouble; m_path->makeCompatibleContextCurrent(); const VGfloat angleDelta = anticlockwise ? (endAngle - startAngle) : (startAngle - endAngle + (2.0 * piDouble)); // OpenVG uses endpoint parameterization while this method receives its // values in center parameterization. It lacks an ellipse rotation // parameter so we use 0 for that, and also the radius is only a single // value which makes for rh == rv. In order to convert from endpoint to // center parameterization, we use the formulas from the OpenVG/SVG specs: // (x,y) = (cos rot, -sin rot; sin rot, -cos rot) * (rh * cos angle, rv * sin angle) + (center.x, center.y) // rot is 0, which simplifies this a bit: // (x,y) = (1, 0; 0, -1) * (rh * cos angle, rv * sin angle) + (center.x, center.y) // = (1 * rh * cos angle + 0 * rv * sin angle, 0 * rh * cos angle + -1 * rv * sin angle) + (center.x, center.y) // = (rh * cos angle, -rv * sin angle) + (center.x, center.y) // (Set angle = {startAngle, endAngle} to retrieve the respective endpoints.) const VGfloat startX = radius * cos(startAngle) + center.x(); const VGfloat startY = -radius * sin(startAngle) + center.y(); const VGfloat endX = radius * cos(endAngle) + center.x(); const VGfloat endY = -radius * sin(endAngle) + center.y(); if (angleDelta > 2.0 * piDouble - 0.05) { VGUErrorCode error = vguEllipse(m_path->vgPath(), center.x(), center.y(), radius * 2, radius * 2); ASSERT(error == VGU_NO_ERROR); } else { // Fa: large arc flag, makes the difference between SCWARC_TO and // LCWARC_TO, respectively SCCWARC_TO and LCCWARC_TO arcs. const bool largeArc = (angleDelta > piDouble); // Fs: sweep flag, specifying whether the arc is drawn in increasing // (true) or decreasing (0) direction. No need to calculate this // value, as it we already get it passed as a parameter // (Fs == !anticlockwise). // Translate the large arc and sweep flags into an OpenVG segment // command. As OpenVG thinks of everything upside down, we need to // reverse the anticlockwise parameter in order to get the specified // rotation. const VGubyte segmentCommand = !anticlockwise ? (largeArc ? VG_LCCWARC_TO_ABS : VG_SCCWARC_TO_ABS) : (largeArc ? VG_LCWARC_TO_ABS : VG_SCWARC_TO_ABS); // So now, we've got all the parameters in endpoint parameterization // format as OpenVG requires it. Which means we can just pass it // like this. const VGubyte pathSegments[] = { hasCurrentPoint() ? VG_LINE_TO_ABS : VG_MOVE_TO_ABS, segmentCommand }; const VGfloat pathData[] = { startX, startY, radius, radius, 0, endX, endY }; m_path->appendPathData(2, pathSegments, pathData); } m_path->m_currentPoint.setX(endX); m_path->m_currentPoint.setY(endY); }
VGPath SurfaceOpenVG::cachedPath(CachedPathDescriptor which) { Vector<VGPath>& paths = cachedPaths(); if (paths.isEmpty()) { paths.resize(CachedPathCount); paths.fill(VG_INVALID_HANDLE); } if (paths.at(which) == VG_INVALID_HANDLE) { sharedSurface()->makeCurrent(); VGPath path = VG_INVALID_HANDLE; VGUErrorCode errorCode; switch (which) { case CachedLinePath: path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0 /* scale */, 0.0 /* bias */, 2 /* expected number of segments */, 4 /* expected number of total coordinates */, VG_PATH_CAPABILITY_APPEND_TO); ASSERT_VG_NO_ERROR(); errorCode = vguLine(path, 0, 0, 1, 0); ASSERT(errorCode == VGU_NO_ERROR); break; case CachedRectPath: path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0 /* scale */, 0.0 /* bias */, 5 /* expected number of segments */, 5 /* expected number of total coordinates */, VG_PATH_CAPABILITY_APPEND_TO); ASSERT_VG_NO_ERROR(); errorCode = vguRect(path, 0, 0, 1, 1); ASSERT(errorCode == VGU_NO_ERROR); break; case CachedCirclePath: path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0 /* scale */, 0.0 /* bias */, 4 /* expected number of segments */, 10 /* expected number of total coordinates */, VG_PATH_CAPABILITY_APPEND_TO); ASSERT_VG_NO_ERROR(); errorCode = vguEllipse(path, 0.5, 0.5, 1, 1); ASSERT(errorCode == VGU_NO_ERROR); break; case EmptyTemporaryPath: path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0 /* scale */, 0.0 /* bias */, 0 /* expected number of segments */, 0 /* expected number of total coordinates */, VG_PATH_CAPABILITY_ALL); ASSERT_VG_NO_ERROR(); break; default: ASSERT_NOT_REACHED(); } paths.at(which) = path; makeCurrent(); } if (which == EmptyTemporaryPath) { VGPath path = paths.at(EmptyTemporaryPath); vgClearPath(path, VG_PATH_CAPABILITY_ALL); ASSERT_VG_NO_ERROR(); return path; } return paths.at(which); }
void createOrigin(VGPath p) { vguEllipse(p, 0,0,10,10); }