Home | History | Annotate | Download | only in openvg
      1 /*
      2  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 #include "GraphicsContext.h"
     22 
     23 #include "AffineTransform.h"
     24 #include "KURL.h"
     25 #include "NotImplemented.h"
     26 #include "PainterOpenVG.h"
     27 #include "SurfaceOpenVG.h"
     28 
     29 #include <wtf/Assertions.h>
     30 #include <wtf/MathExtras.h>
     31 #include <wtf/UnusedParam.h>
     32 #include <wtf/Vector.h>
     33 
     34 #if PLATFORM(EGL)
     35 #include "EGLDisplayOpenVG.h"
     36 #include "EGLUtils.h"
     37 #include <egl.h>
     38 #endif
     39 
     40 namespace WebCore {
     41 
     42 // typedef'ing doesn't work, let's inherit from PainterOpenVG instead
     43 class GraphicsContextPlatformPrivate : public PainterOpenVG {
     44 public:
     45     GraphicsContextPlatformPrivate(SurfaceOpenVG* surface)
     46         : PainterOpenVG(surface)
     47     {
     48     }
     49 };
     50 
     51 void GraphicsContext::platformInit(SurfaceOpenVG* surface)
     52 {
     53     m_data = surface ? new GraphicsContextPlatformPrivate(surface) : 0;
     54     setPaintingDisabled(!surface);
     55 }
     56 
     57 void GraphicsContext::platformDestroy()
     58 {
     59     delete m_data;
     60 }
     61 
     62 PlatformGraphicsContext* GraphicsContext::platformContext() const
     63 {
     64     if (paintingDisabled())
     65         return 0;
     66 
     67     return m_data->baseSurface();
     68 }
     69 
     70 AffineTransform GraphicsContext::getCTM() const
     71 {
     72     if (paintingDisabled())
     73         return AffineTransform();
     74 
     75     return m_data->transformation();
     76 }
     77 
     78 void GraphicsContext::savePlatformState()
     79 {
     80     if (paintingDisabled())
     81         return;
     82 
     83     m_data->save();
     84 }
     85 
     86 void GraphicsContext::restorePlatformState()
     87 {
     88     if (paintingDisabled())
     89         return;
     90 
     91     m_data->restore();
     92 }
     93 
     94 void GraphicsContext::drawRect(const IntRect& rect)
     95 {
     96     if (paintingDisabled())
     97         return;
     98 
     99     m_data->drawRect(rect);
    100 }
    101 
    102 void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to)
    103 {
    104     if (paintingDisabled())
    105         return;
    106 
    107     m_data->drawLine(from, to);
    108 }
    109 
    110 /**
    111  * Draw the largest ellipse that fits into the given rectangle.
    112  */
    113 void GraphicsContext::drawEllipse(const IntRect& rect)
    114 {
    115     if (paintingDisabled())
    116         return;
    117 
    118     m_data->drawEllipse(rect);
    119 }
    120 
    121 void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
    122 {
    123     if (paintingDisabled())
    124         return;
    125 
    126     m_data->drawArc(rect, startAngle, angleSpan, VG_STROKE_PATH);
    127 }
    128 
    129 void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
    130 {
    131     if (paintingDisabled())
    132         return;
    133 
    134     m_data->drawPolygon(numPoints, points);
    135 
    136     UNUSED_PARAM(shouldAntialias); // FIXME
    137 }
    138 
    139 void GraphicsContext::fillPath(const Path& path)
    140 {
    141     if (paintingDisabled())
    142         return;
    143 
    144     m_data->drawPath(path, VG_FILL_PATH, m_state.fillRule);
    145 }
    146 
    147 void GraphicsContext::strokePath(const Path& path)
    148 {
    149     if (paintingDisabled())
    150         return;
    151 
    152     m_data->drawPath(path, VG_STROKE_PATH, m_state.fillRule);
    153 }
    154 
    155 void GraphicsContext::fillRect(const FloatRect& rect)
    156 {
    157     if (paintingDisabled())
    158         return;
    159 
    160     m_data->drawRect(rect, VG_FILL_PATH);
    161 }
    162 
    163 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
    164 {
    165     if (paintingDisabled())
    166         return;
    167 
    168     Color oldColor = m_data->fillColor();
    169     m_data->setFillColor(color);
    170     m_data->drawRect(rect, VG_FILL_PATH);
    171     m_data->setFillColor(oldColor);
    172 
    173     UNUSED_PARAM(colorSpace); // FIXME
    174 }
    175 
    176 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
    177 {
    178     if (paintingDisabled())
    179         return;
    180 
    181     Color oldColor = m_data->fillColor();
    182     m_data->setFillColor(color);
    183     m_data->drawRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, VG_FILL_PATH);
    184     m_data->setFillColor(oldColor);
    185 
    186     UNUSED_PARAM(colorSpace); // FIXME
    187 }
    188 
    189 void GraphicsContext::clip(const FloatRect& rect)
    190 {
    191     if (paintingDisabled())
    192         return;
    193 
    194     m_data->intersectClipRect(rect);
    195 }
    196 
    197 void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
    198 {
    199     if (paintingDisabled())
    200         return;
    201 
    202     m_data->clipPath(path, PainterOpenVG::IntersectClip, clipRule);
    203 }
    204 
    205 void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
    206 {
    207     if (paintingDisabled())
    208         return;
    209 
    210     if (rects.isEmpty())
    211         return;
    212 
    213     // FIXME: We just unite all focus ring rects into one for now.
    214     // We should outline the edge of the full region.
    215     offset += (width - 1) / 2;
    216     IntRect finalFocusRect;
    217 
    218     for (unsigned i = 0; i < rects.size(); i++) {
    219         IntRect focusRect = rects[i];
    220         focusRect.inflate(offset);
    221         finalFocusRect.unite(focusRect);
    222     }
    223 
    224     StrokeStyle oldStyle = m_data->strokeStyle();
    225     Color oldStrokeColor = m_data->strokeColor();
    226     m_data->setStrokeStyle(DashedStroke);
    227     m_data->setStrokeColor(color);
    228     strokeRect(FloatRect(finalFocusRect), 1.f);
    229     m_data->setStrokeStyle(oldStyle);
    230     m_data->setStrokeColor(oldStrokeColor);
    231 }
    232 
    233 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
    234 {
    235     if (paintingDisabled())
    236         return;
    237 
    238     if (width <= 0)
    239         return;
    240 
    241     StrokeStyle oldStyle = m_data->strokeStyle();
    242     m_data->setStrokeStyle(SolidStroke);
    243     drawLine(origin, origin + IntSize(width, 0));
    244     m_data->setStrokeStyle(oldStyle);
    245 
    246     UNUSED_PARAM(printing);
    247 }
    248 
    249 void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style)
    250 {
    251     if (paintingDisabled())
    252         return;
    253 
    254     notImplemented();
    255     UNUSED_PARAM(origin);
    256     UNUSED_PARAM(width);
    257     UNUSED_PARAM(style);
    258 }
    259 
    260 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect, RoundingMode)
    261 {
    262     if (paintingDisabled())
    263         return FloatRect();
    264 
    265     return FloatRect(enclosingIntRect(m_data->transformation().mapRect(rect)));
    266 }
    267 
    268 void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace colorSpace)
    269 {
    270     if (paintingDisabled())
    271         return;
    272 
    273     notImplemented();
    274     UNUSED_PARAM(size);
    275     UNUSED_PARAM(blur);
    276     UNUSED_PARAM(color);
    277     UNUSED_PARAM(colorSpace);
    278 }
    279 
    280 void GraphicsContext::clearPlatformShadow()
    281 {
    282     if (paintingDisabled())
    283         return;
    284 
    285     notImplemented();
    286 }
    287 
    288 void GraphicsContext::beginTransparencyLayer(float opacity)
    289 {
    290     if (paintingDisabled())
    291         return;
    292 
    293     notImplemented();
    294     UNUSED_PARAM(opacity);
    295 }
    296 
    297 void GraphicsContext::endTransparencyLayer()
    298 {
    299     if (paintingDisabled())
    300         return;
    301 
    302     notImplemented();
    303 }
    304 
    305 void GraphicsContext::clearRect(const FloatRect& rect)
    306 {
    307     if (paintingDisabled())
    308         return;
    309 
    310     CompositeOperator op = m_data->compositeOperation();
    311     m_data->setCompositeOperation(CompositeClear);
    312     m_data->drawRect(rect, VG_FILL_PATH);
    313     m_data->setCompositeOperation(op);
    314 }
    315 
    316 void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
    317 {
    318     if (paintingDisabled())
    319         return;
    320 
    321     float oldThickness = m_data->strokeThickness();
    322     m_data->setStrokeThickness(lineWidth);
    323     m_data->drawRect(rect, VG_STROKE_PATH);
    324     m_data->setStrokeThickness(oldThickness);
    325 }
    326 
    327 void GraphicsContext::setLineCap(LineCap lc)
    328 {
    329     if (paintingDisabled())
    330         return;
    331 
    332     m_data->setLineCap(lc);
    333 }
    334 
    335 void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
    336 {
    337     if (paintingDisabled())
    338         return;
    339 
    340     m_data->setLineDash(dashes, dashOffset);
    341 }
    342 
    343 void GraphicsContext::setLineJoin(LineJoin lj)
    344 {
    345     if (paintingDisabled())
    346         return;
    347 
    348     m_data->setLineJoin(lj);
    349 }
    350 
    351 void GraphicsContext::setMiterLimit(float limit)
    352 {
    353     if (paintingDisabled())
    354         return;
    355 
    356     m_data->setMiterLimit(limit);
    357 }
    358 
    359 void GraphicsContext::setAlpha(float opacity)
    360 {
    361     if (paintingDisabled())
    362         return;
    363 
    364     m_data->setOpacity(opacity);
    365 }
    366 
    367 void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
    368 {
    369     if (paintingDisabled())
    370         return;
    371 
    372     m_data->setCompositeOperation(op);
    373 }
    374 
    375 void GraphicsContext::clip(const Path& path)
    376 {
    377     if (paintingDisabled())
    378         return;
    379 
    380     m_data->clipPath(path, PainterOpenVG::IntersectClip, m_state.fillRule);
    381 }
    382 
    383 void GraphicsContext::canvasClip(const Path& path)
    384 {
    385     clip(path);
    386 }
    387 
    388 void GraphicsContext::clipOut(const Path& path)
    389 {
    390     if (paintingDisabled())
    391         return;
    392 
    393     m_data->clipPath(path, PainterOpenVG::SubtractClip, m_state.fillRule);
    394 }
    395 
    396 void GraphicsContext::scale(const FloatSize& scaleFactors)
    397 {
    398     if (paintingDisabled())
    399         return;
    400 
    401     m_data->scale(scaleFactors);
    402 }
    403 
    404 void GraphicsContext::rotate(float radians)
    405 {
    406     if (paintingDisabled())
    407         return;
    408 
    409     m_data->rotate(radians);
    410 }
    411 
    412 void GraphicsContext::translate(float dx, float dy)
    413 {
    414     if (paintingDisabled())
    415         return;
    416 
    417     m_data->translate(dx, dy);
    418 }
    419 
    420 void GraphicsContext::clipOut(const IntRect& rect)
    421 {
    422     if (paintingDisabled())
    423         return;
    424 
    425     Path path;
    426     path.addRect(rect);
    427     m_data->clipPath(path, PainterOpenVG::SubtractClip, m_state.fillRule);
    428 }
    429 
    430 void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
    431 {
    432     if (paintingDisabled())
    433         return;
    434 
    435     notImplemented();
    436     UNUSED_PARAM(rect);
    437     UNUSED_PARAM(imageBuffer);
    438 }
    439 
    440 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
    441 {
    442     if (paintingDisabled())
    443         return;
    444 
    445     Path path;
    446     path.addEllipse(rect);
    447     path.addEllipse(FloatRect(rect.x() + thickness, rect.y() + thickness,
    448         rect.width() - (thickness * 2), rect.height() - (thickness * 2)));
    449 
    450     m_data->clipPath(path, PainterOpenVG::IntersectClip, m_state.fillRule);
    451 }
    452 
    453 void GraphicsContext::concatCTM(const AffineTransform& transformation)
    454 {
    455     if (paintingDisabled())
    456         return;
    457 
    458     m_data->concatTransformation(transformation);
    459 }
    460 
    461 void GraphicsContext::setCTM(const AffineTransform& transformation)
    462 {
    463     if (paintingDisabled())
    464         return;
    465 
    466     m_data->setTransformation(transformation);
    467 }
    468 
    469 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
    470 {
    471     notImplemented();
    472     UNUSED_PARAM(link);
    473     UNUSED_PARAM(destRect);
    474 }
    475 
    476 void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
    477 {
    478     if (paintingDisabled())
    479         return;
    480 
    481     m_data->setStrokeColor(color);
    482 
    483     UNUSED_PARAM(colorSpace); // FIXME
    484 }
    485 
    486 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
    487 {
    488     if (paintingDisabled())
    489         return;
    490 
    491     m_data->setStrokeStyle(strokeStyle);
    492 }
    493 
    494 void GraphicsContext::setPlatformStrokeThickness(float thickness)
    495 {
    496     if (paintingDisabled())
    497         return;
    498 
    499     m_data->setStrokeThickness(thickness);
    500 }
    501 
    502 void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
    503 {
    504     if (paintingDisabled())
    505         return;
    506 
    507     m_data->setFillColor(color);
    508 
    509     UNUSED_PARAM(colorSpace); // FIXME
    510 }
    511 
    512 void GraphicsContext::setPlatformShouldAntialias(bool enable)
    513 {
    514     if (paintingDisabled())
    515         return;
    516 
    517     m_data->setAntialiasingEnabled(enable);
    518 }
    519 
    520 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
    521 {
    522     notImplemented();
    523 }
    524 
    525 InterpolationQuality GraphicsContext::imageInterpolationQuality() const
    526 {
    527     notImplemented();
    528     return InterpolationDefault;
    529 }
    530 
    531 }
    532