Commit c79091e6 authored by jpetsovits@rim.com's avatar jpetsovits@rim.com

2010-01-29 Jakob Petsovits <jpetsovits@rim.com>

        Reviewed by Nikolas Zimmermann.

        [OpenVG] Implement more graphics primitives
        https://bugs.webkit.org/show_bug.cgi?id=34339

        Adds lines, arcs, ellipses, polygons and rounded
        rectangles to PainterOpenVG and GraphicsContext.

        Rounded rects support by Eli Fidler <efidler@rim.com>.

        * platform/graphics/openvg/GraphicsContextOpenVG.cpp:
        (WebCore::GraphicsContext::drawLine):
        (WebCore::GraphicsContext::drawEllipse):
        (WebCore::GraphicsContext::strokeArc):
        (WebCore::GraphicsContext::drawConvexPolygon):
        (WebCore::GraphicsContext::fillRect):
        (WebCore::GraphicsContext::fillRoundedRect):
        (WebCore::GraphicsContext::drawFocusRing):
        (WebCore::GraphicsContext::drawLineForText):
        (WebCore::GraphicsContext::clearRect):
        (WebCore::GraphicsContext::strokeRect):
        * platform/graphics/openvg/PainterOpenVG.cpp:
        (WebCore::PainterOpenVG::drawRect):
        (WebCore::PainterOpenVG::drawRoundedRect):
        (WebCore::PainterOpenVG::drawLine):
        (WebCore::PainterOpenVG::drawArc):
        (WebCore::PainterOpenVG::drawEllipse):
        (WebCore::PainterOpenVG::drawPolygon):
        * platform/graphics/openvg/PainterOpenVG.h:


git-svn-id: svn://svn.chromium.org/blink/trunk@54089 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent fc2bca7f
2010-01-29 Jakob Petsovits <jpetsovits@rim.com>
Reviewed by Nikolas Zimmermann.
[OpenVG] Implement more graphics primitives
https://bugs.webkit.org/show_bug.cgi?id=34339
Adds lines, arcs, ellipses, polygons and rounded
rectangles to PainterOpenVG and GraphicsContext.
Rounded rects support by Eli Fidler <efidler@rim.com>.
* platform/graphics/openvg/GraphicsContextOpenVG.cpp:
(WebCore::GraphicsContext::drawLine):
(WebCore::GraphicsContext::drawEllipse):
(WebCore::GraphicsContext::strokeArc):
(WebCore::GraphicsContext::drawConvexPolygon):
(WebCore::GraphicsContext::fillRect):
(WebCore::GraphicsContext::fillRoundedRect):
(WebCore::GraphicsContext::drawFocusRing):
(WebCore::GraphicsContext::drawLineForText):
(WebCore::GraphicsContext::clearRect):
(WebCore::GraphicsContext::strokeRect):
* platform/graphics/openvg/PainterOpenVG.cpp:
(WebCore::PainterOpenVG::drawRect):
(WebCore::PainterOpenVG::drawRoundedRect):
(WebCore::PainterOpenVG::drawLine):
(WebCore::PainterOpenVG::drawArc):
(WebCore::PainterOpenVG::drawEllipse):
(WebCore::PainterOpenVG::drawPolygon):
* platform/graphics/openvg/PainterOpenVG.h:
2010-01-29 Jeremy Orlow <jorlow@chromium.org> 2010-01-29 Jeremy Orlow <jorlow@chromium.org>
Reviewed by Dimitri Glazkov. Reviewed by Dimitri Glazkov.
...@@ -106,9 +106,7 @@ void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to) ...@@ -106,9 +106,7 @@ void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to)
if (paintingDisabled()) if (paintingDisabled())
return; return;
notImplemented(); m_data->drawLine(from, to);
UNUSED_PARAM(from);
UNUSED_PARAM(to);
} }
/** /**
...@@ -119,8 +117,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect) ...@@ -119,8 +117,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
if (paintingDisabled()) if (paintingDisabled())
return; return;
notImplemented(); m_data->drawEllipse(rect);
UNUSED_PARAM(rect);
} }
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
...@@ -128,10 +125,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp ...@@ -128,10 +125,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (paintingDisabled()) if (paintingDisabled())
return; return;
notImplemented(); m_data->drawArc(rect, startAngle, angleSpan, VG_STROKE_PATH);
UNUSED_PARAM(rect);
UNUSED_PARAM(startAngle);
UNUSED_PARAM(angleSpan);
} }
void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias) void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
...@@ -139,10 +133,9 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin ...@@ -139,10 +133,9 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin
if (paintingDisabled()) if (paintingDisabled())
return; return;
notImplemented(); m_data->drawPolygon(numPoints, points);
UNUSED_PARAM(numPoints);
UNUSED_PARAM(points); UNUSED_PARAM(shouldAntialias); // FIXME
UNUSED_PARAM(shouldAntialias);
} }
void GraphicsContext::fillPath() void GraphicsContext::fillPath()
...@@ -174,11 +167,10 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS ...@@ -174,11 +167,10 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (paintingDisabled()) if (paintingDisabled())
return; return;
PainterOpenVG* painter = m_data; Color oldColor = m_data->fillColor();
Color oldColor = painter->fillColor(); m_data->setFillColor(color);
painter->setFillColor(color); m_data->drawRect(rect, VG_FILL_PATH);
painter->drawRect(rect, VG_FILL_PATH); m_data->setFillColor(oldColor);
painter->setFillColor(oldColor);
UNUSED_PARAM(colorSpace); // FIXME UNUSED_PARAM(colorSpace); // FIXME
} }
...@@ -188,14 +180,12 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef ...@@ -188,14 +180,12 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
if (paintingDisabled()) if (paintingDisabled())
return; return;
notImplemented(); Color oldColor = m_data->fillColor();
UNUSED_PARAM(rect); m_data->setFillColor(color);
UNUSED_PARAM(topLeft); m_data->drawRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, VG_FILL_PATH);
UNUSED_PARAM(topRight); m_data->setFillColor(oldColor);
UNUSED_PARAM(bottomLeft);
UNUSED_PARAM(bottomRight); UNUSED_PARAM(colorSpace); // FIXME
UNUSED_PARAM(color);
UNUSED_PARAM(colorSpace);
} }
void GraphicsContext::beginPath() void GraphicsContext::beginPath()
...@@ -250,14 +240,13 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int ...@@ -250,14 +240,13 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
finalFocusRect.unite(focusRect); finalFocusRect.unite(focusRect);
} }
PainterOpenVG* painter = m_data; StrokeStyle oldStyle = m_data->strokeStyle();
StrokeStyle oldStyle = painter->strokeStyle(); Color oldStrokeColor = m_data->strokeColor();
Color oldStrokeColor = painter->strokeColor(); m_data->setStrokeStyle(DashedStroke);
painter->setStrokeStyle(DashedStroke); m_data->setStrokeColor(color);
painter->setStrokeColor(color);
strokeRect(FloatRect(finalFocusRect), 1.f); strokeRect(FloatRect(finalFocusRect), 1.f);
painter->setStrokeStyle(oldStyle); m_data->setStrokeStyle(oldStyle);
painter->setStrokeColor(oldStrokeColor); m_data->setStrokeColor(oldStrokeColor);
} }
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
...@@ -268,9 +257,11 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr ...@@ -268,9 +257,11 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
if (width <= 0) if (width <= 0)
return; return;
notImplemented(); StrokeStyle oldStyle = m_data->strokeStyle();
UNUSED_PARAM(origin); m_data->setStrokeStyle(SolidStroke);
UNUSED_PARAM(width); drawLine(origin, origin + IntSize(width, 0));
m_data->setStrokeStyle(oldStyle);
UNUSED_PARAM(printing); UNUSED_PARAM(printing);
} }
...@@ -335,12 +326,10 @@ void GraphicsContext::clearRect(const FloatRect& rect) ...@@ -335,12 +326,10 @@ void GraphicsContext::clearRect(const FloatRect& rect)
if (paintingDisabled()) if (paintingDisabled())
return; return;
PainterOpenVG* painter = m_data; CompositeOperator op = m_data->compositeOperation();
m_data->setCompositeOperation(CompositeClear);
CompositeOperator op = painter->compositeOperation(); m_data->drawRect(rect, VG_FILL_PATH);
painter->setCompositeOperation(CompositeClear); m_data->setCompositeOperation(op);
painter->drawRect(rect, VG_FILL_PATH);
painter->setCompositeOperation(op);
} }
void GraphicsContext::strokeRect(const FloatRect& rect) void GraphicsContext::strokeRect(const FloatRect& rect)
...@@ -356,12 +345,10 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) ...@@ -356,12 +345,10 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
if (paintingDisabled()) if (paintingDisabled())
return; return;
PainterOpenVG* painter = m_data; float oldThickness = m_data->strokeThickness();
m_data->setStrokeThickness(lineWidth);
float oldThickness = painter->strokeThickness(); m_data->drawRect(rect, VG_STROKE_PATH);
painter->setStrokeThickness(lineWidth); m_data->setStrokeThickness(oldThickness);
painter->drawRect(rect, VG_STROKE_PATH);
painter->setStrokeThickness(oldThickness);
} }
void GraphicsContext::setLineCap(LineCap lc) void GraphicsContext::setLineCap(LineCap lc)
......
...@@ -694,8 +694,7 @@ void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintMod ...@@ -694,8 +694,7 @@ void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintMod
1.0 /* scale */, 0.0 /* bias */, 1.0 /* scale */, 0.0 /* bias */,
5 /* expected number of segments */, 5 /* expected number of segments */,
5 /* expected number of total coordinates */, 5 /* expected number of total coordinates */,
VG_PATH_CAPABILITY_APPEND_TO VG_PATH_CAPABILITY_APPEND_TO);
);
ASSERT_VG_NO_ERROR(); ASSERT_VG_NO_ERROR();
if (vguRect(path, rect.x(), rect.y(), rect.width(), rect.height()) == VGU_NO_ERROR) { if (vguRect(path, rect.x(), rect.y(), rect.width(), rect.height()) == VGU_NO_ERROR) {
...@@ -707,6 +706,219 @@ void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintMod ...@@ -707,6 +706,219 @@ void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintMod
ASSERT_VG_NO_ERROR(); ASSERT_VG_NO_ERROR();
} }
void PainterOpenVG::drawRoundedRect(const FloatRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, 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 */,
10 /* expected number of segments */,
25 /* expected number of total coordinates */,
VG_PATH_CAPABILITY_APPEND_TO);
ASSERT_VG_NO_ERROR();
// clamp corner arc sizes
FloatSize clampedTopLeft = FloatSize(topLeft).shrunkTo(rect.size()).expandedTo(FloatSize());
FloatSize clampedTopRight = FloatSize(topRight).shrunkTo(rect.size()).expandedTo(FloatSize());
FloatSize clampedBottomLeft = FloatSize(bottomLeft).shrunkTo(rect.size()).expandedTo(FloatSize());
FloatSize clampedBottomRight = FloatSize(bottomRight).shrunkTo(rect.size()).expandedTo(FloatSize());
// As OpenVG's coordinate system is flipped in comparison to WebKit's,
// we have to specify the opposite value for the "clockwise" value.
static const VGubyte pathSegments[] = {
VG_MOVE_TO_ABS,
VG_HLINE_TO_REL,
VG_SCCWARC_TO_REL,
VG_VLINE_TO_REL,
VG_SCCWARC_TO_REL,
VG_HLINE_TO_REL,
VG_SCCWARC_TO_REL,
VG_VLINE_TO_REL,
VG_SCCWARC_TO_REL,
VG_CLOSE_PATH
};
// Also, the rounded rectangle path proceeds from the top to the bottom,
// requiring height distances and clamped radius sizes to be flipped.
const VGfloat pathData[] = {
rect.x() + clampedTopLeft.width(), rect.y(),
rect.width() - clampedTopLeft.width() - clampedTopRight.width(),
clampedTopRight.width(), clampedTopRight.height(), 0, clampedTopRight.width(), clampedTopRight.height(),
rect.height() - clampedTopRight.height() - clampedBottomRight.height(),
clampedBottomRight.width(), clampedBottomRight.height(), 0, -clampedBottomRight.width(), clampedBottomRight.height(),
-(rect.width() - clampedBottomLeft.width() - clampedBottomRight.width()),
clampedBottomLeft.width(), clampedBottomLeft.height(), 0, -clampedBottomLeft.width(), -clampedBottomLeft.height(),
-(rect.height() - clampedTopLeft.height() - clampedBottomLeft.height()),
clampedTopLeft.width(), clampedTopLeft.height(), 0, clampedTopLeft.width(), -clampedTopLeft.height(),
};
vgAppendPathData(path, 10, pathSegments, pathData);
vgDrawPath(path, paintModes);
vgDestroyPath(path);
ASSERT_VG_NO_ERROR();
}
void PainterOpenVG::drawLine(const IntPoint& from, const IntPoint& to)
{
ASSERT(m_state);
if (m_state->strokeDisabled())
return;
m_surface->makeCurrent();
VGPath 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();
VGUErrorCode errorCode;
// Try to align lines to pixels, centering them between pixels for odd thickness values.
if (fmod(m_state->strokeThickness + 0.5, 2.0) < 1.0)
errorCode = vguLine(path, from.x(), from.y(), to.x(), to.y());
else if ((to.y() - from.y()) > (to.x() - from.x())) // more vertical than horizontal
errorCode = vguLine(path, from.x() + 0.5, from.y(), to.x() + 0.5, to.y());
else
errorCode = vguLine(path, from.x(), from.y() + 0.5, to.x(), to.y() + 0.5);
if (errorCode == VGU_NO_ERROR) {
vgDrawPath(path, VG_STROKE_PATH);
ASSERT_VG_NO_ERROR();
}
vgDestroyPath(path);
ASSERT_VG_NO_ERROR();
}
void PainterOpenVG::drawArc(const IntRect& rect, int startAngle, int angleSpan, 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 */,
2 /* expected number of segments */,
4 /* expected number of total coordinates */,
VG_PATH_CAPABILITY_APPEND_TO);
ASSERT_VG_NO_ERROR();
if (vguArc(path, rect.x() + rect.width() / 2.0, rect.y() + rect.height() / 2.0, rect.width(), rect.height(), -startAngle, -angleSpan, VGU_ARC_OPEN) == VGU_NO_ERROR) {
vgDrawPath(path, VG_STROKE_PATH);
ASSERT_VG_NO_ERROR();
}
vgDestroyPath(path);
ASSERT_VG_NO_ERROR();
}
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 PainterOpenVG::drawPolygon(size_t numPoints, const FloatPoint* points, 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();
// Path segments: all points + "close path".
const VGint numSegments = numPoints + 1;
const VGint numCoordinates = numPoints * 2;
VGPath path = vgCreatePath(
VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
1.0 /* scale */, 0.0 /* bias */,
numSegments /* expected number of segments */,
numCoordinates /* expected number of total coordinates */,
VG_PATH_CAPABILITY_APPEND_TO);
ASSERT_VG_NO_ERROR();
Vector<VGfloat> vgPoints(numCoordinates);
for (int i = 0; i < numPoints; ++i) {
vgPoints[i*2] = points[i].x();
vgPoints[i*2 + 1] = points[i].y();
}
if (vguPolygon(path, vgPoints.data(), numPoints, VG_TRUE /* closed */) == VGU_NO_ERROR) {
vgDrawPath(path, paintModes);
ASSERT_VG_NO_ERROR();
}
vgDestroyPath(path);
ASSERT_VG_NO_ERROR();
}
void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode) void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode)
{ {
ASSERT(m_state); ASSERT(m_state);
......
...@@ -86,6 +86,11 @@ public: ...@@ -86,6 +86,11 @@ public:
void setAntialiasingEnabled(bool); void setAntialiasingEnabled(bool);
void drawRect(const FloatRect&, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH)); void drawRect(const FloatRect&, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void drawRoundedRect(const FloatRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void drawLine(const IntPoint& from, const IntPoint& to);
void drawArc(const IntRect& ellipseBounds, int startAngle, int angleSpan, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void drawEllipse(const IntRect& bounds, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void drawPolygon(size_t numPoints, const FloatPoint* points, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
void scale(const FloatSize& scaleFactors); void scale(const FloatSize& scaleFactors);
void rotate(float radians); void rotate(float radians);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment