GraphicsContextOpenVG.cpp revision 81bc750723a18f21cd17d1b173cd2a4dda9cea6e
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 40namespace WebCore { 41 42// typedef'ing doesn't work, let's inherit from PainterOpenVG instead 43class GraphicsContextPlatformPrivate : public PainterOpenVG { 44public: 45 GraphicsContextPlatformPrivate(SurfaceOpenVG* surface) 46 : PainterOpenVG(surface) 47 { 48 } 49}; 50 51void GraphicsContext::platformInit(SurfaceOpenVG* surface) 52{ 53 m_data = surface ? new GraphicsContextPlatformPrivate(surface) : 0; 54 setPaintingDisabled(!surface); 55} 56 57void GraphicsContext::platformDestroy() 58{ 59 delete m_data; 60} 61 62PlatformGraphicsContext* GraphicsContext::platformContext() const 63{ 64 if (paintingDisabled()) 65 return 0; 66 67 return m_data->baseSurface(); 68} 69 70AffineTransform GraphicsContext::getCTM() const 71{ 72 if (paintingDisabled()) 73 return AffineTransform(); 74 75 return m_data->transformation(); 76} 77 78void GraphicsContext::savePlatformState() 79{ 80 if (paintingDisabled()) 81 return; 82 83 m_data->save(); 84} 85 86void GraphicsContext::restorePlatformState() 87{ 88 if (paintingDisabled()) 89 return; 90 91 m_data->restore(); 92} 93 94void GraphicsContext::drawRect(const IntRect& rect) 95{ 96 if (paintingDisabled()) 97 return; 98 99 m_data->drawRect(rect); 100} 101 102void 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 */ 113void GraphicsContext::drawEllipse(const IntRect& rect) 114{ 115 if (paintingDisabled()) 116 return; 117 118 m_data->drawEllipse(rect); 119} 120 121void 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 129void 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 139void 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 147void 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 155void GraphicsContext::fillRect(const FloatRect& rect) 156{ 157 if (paintingDisabled()) 158 return; 159 160 m_data->drawRect(rect, VG_FILL_PATH); 161} 162 163void 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 176void 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 189void GraphicsContext::clip(const FloatRect& rect) 190{ 191 if (paintingDisabled()) 192 return; 193 194 m_data->intersectClipRect(rect); 195} 196 197void GraphicsContext::clipPath(const Path& path, WindRule clipRule) 198{ 199 if (paintingDisabled()) 200 return; 201 202 m_data->clipPath(path, PainterOpenVG::IntersectClip, clipRule); 203} 204 205void 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 233void 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 249void 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 260FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) 261{ 262 if (paintingDisabled()) 263 return FloatRect(); 264 265 return FloatRect(enclosingIntRect(m_data->transformation().mapRect(rect))); 266} 267 268void 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 280void GraphicsContext::clearPlatformShadow() 281{ 282 if (paintingDisabled()) 283 return; 284 285 notImplemented(); 286} 287 288void GraphicsContext::beginTransparencyLayer(float opacity) 289{ 290 if (paintingDisabled()) 291 return; 292 293 notImplemented(); 294 UNUSED_PARAM(opacity); 295} 296 297void GraphicsContext::endTransparencyLayer() 298{ 299 if (paintingDisabled()) 300 return; 301 302 notImplemented(); 303} 304 305void 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 316void 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 327void GraphicsContext::setLineCap(LineCap lc) 328{ 329 if (paintingDisabled()) 330 return; 331 332 m_data->setLineCap(lc); 333} 334 335void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) 336{ 337 if (paintingDisabled()) 338 return; 339 340 m_data->setLineDash(dashes, dashOffset); 341} 342 343void GraphicsContext::setLineJoin(LineJoin lj) 344{ 345 if (paintingDisabled()) 346 return; 347 348 m_data->setLineJoin(lj); 349} 350 351void GraphicsContext::setMiterLimit(float limit) 352{ 353 if (paintingDisabled()) 354 return; 355 356 m_data->setMiterLimit(limit); 357} 358 359void GraphicsContext::setAlpha(float opacity) 360{ 361 if (paintingDisabled()) 362 return; 363 364 m_data->setOpacity(opacity); 365} 366 367void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op) 368{ 369 if (paintingDisabled()) 370 return; 371 372 m_data->setCompositeOperation(op); 373} 374 375void GraphicsContext::clip(const Path& path) 376{ 377 if (paintingDisabled()) 378 return; 379 380 m_data->clipPath(path, PainterOpenVG::IntersectClip, m_state.fillRule); 381} 382 383void GraphicsContext::canvasClip(const Path& path) 384{ 385 clip(path); 386} 387 388void GraphicsContext::clipOut(const Path& path) 389{ 390 if (paintingDisabled()) 391 return; 392 393 m_data->clipPath(path, PainterOpenVG::SubtractClip, m_state.fillRule); 394} 395 396void GraphicsContext::scale(const FloatSize& scaleFactors) 397{ 398 if (paintingDisabled()) 399 return; 400 401 m_data->scale(scaleFactors); 402} 403 404void GraphicsContext::rotate(float radians) 405{ 406 if (paintingDisabled()) 407 return; 408 409 m_data->rotate(radians); 410} 411 412void GraphicsContext::translate(float dx, float dy) 413{ 414 if (paintingDisabled()) 415 return; 416 417 m_data->translate(dx, dy); 418} 419 420void 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 430void 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 440void 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 453void GraphicsContext::concatCTM(const AffineTransform& transformation) 454{ 455 if (paintingDisabled()) 456 return; 457 458 m_data->concatTransformation(transformation); 459} 460 461void GraphicsContext::setCTM(const AffineTransform& transformation) 462{ 463 if (paintingDisabled()) 464 return; 465 466 m_data->setTransformation(transformation); 467} 468 469void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) 470{ 471 notImplemented(); 472 UNUSED_PARAM(link); 473 UNUSED_PARAM(destRect); 474} 475 476void 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 486void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle) 487{ 488 if (paintingDisabled()) 489 return; 490 491 m_data->setStrokeStyle(strokeStyle); 492} 493 494void GraphicsContext::setPlatformStrokeThickness(float thickness) 495{ 496 if (paintingDisabled()) 497 return; 498 499 m_data->setStrokeThickness(thickness); 500} 501 502void 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 512void GraphicsContext::setPlatformShouldAntialias(bool enable) 513{ 514 if (paintingDisabled()) 515 return; 516 517 m_data->setAntialiasingEnabled(enable); 518} 519 520void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) 521{ 522 notImplemented(); 523} 524 525InterpolationQuality GraphicsContext::imageInterpolationQuality() const 526{ 527 notImplemented(); 528 return InterpolationDefault; 529} 530 531} 532