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 "GraphicsContextPrivate.h" 24 #include "NotImplemented.h" 25 #include "PainterOpenVG.h" 26 #include "SurfaceOpenVG.h" 27 #include "TransformationMatrix.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 GraphicsContext::GraphicsContext(SurfaceOpenVG* surface) 52 : m_common(createGraphicsContextPrivate()) 53 , m_data(surface ? new GraphicsContextPlatformPrivate(surface) : 0) 54 { 55 setPaintingDisabled(!surface); 56 } 57 58 GraphicsContext::~GraphicsContext() 59 { 60 destroyGraphicsContextPrivate(m_common); 61 delete m_data; 62 } 63 64 PlatformGraphicsContext* GraphicsContext::platformContext() const 65 { 66 if (paintingDisabled()) 67 return 0; 68 69 return m_data->baseSurface(); 70 } 71 72 TransformationMatrix GraphicsContext::getCTM() const 73 { 74 if (paintingDisabled()) 75 return TransformationMatrix(); 76 77 return m_data->transformationMatrix(); 78 } 79 80 void GraphicsContext::savePlatformState() 81 { 82 if (paintingDisabled()) 83 return; 84 85 m_data->save(); 86 } 87 88 void GraphicsContext::restorePlatformState() 89 { 90 if (paintingDisabled()) 91 return; 92 93 m_data->restore(); 94 } 95 96 void GraphicsContext::drawRect(const IntRect& rect) 97 { 98 if (paintingDisabled()) 99 return; 100 101 m_data->drawRect(rect); 102 } 103 104 void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to) 105 { 106 if (paintingDisabled()) 107 return; 108 109 m_data->drawLine(from, to); 110 } 111 112 /** 113 * Draw the largest ellipse that fits into the given rectangle. 114 */ 115 void GraphicsContext::drawEllipse(const IntRect& rect) 116 { 117 if (paintingDisabled()) 118 return; 119 120 m_data->drawEllipse(rect); 121 } 122 123 void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan) 124 { 125 if (paintingDisabled()) 126 return; 127 128 m_data->drawArc(rect, startAngle, angleSpan, VG_STROKE_PATH); 129 } 130 131 void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias) 132 { 133 if (paintingDisabled()) 134 return; 135 136 m_data->drawPolygon(numPoints, points); 137 138 UNUSED_PARAM(shouldAntialias); // FIXME 139 } 140 141 void GraphicsContext::fillPath() 142 { 143 if (paintingDisabled()) 144 return; 145 146 notImplemented(); 147 } 148 149 void GraphicsContext::strokePath() 150 { 151 if (paintingDisabled()) 152 return; 153 154 notImplemented(); 155 } 156 157 void GraphicsContext::fillRect(const FloatRect& rect) 158 { 159 if (paintingDisabled()) 160 return; 161 162 m_data->drawRect(rect, VG_FILL_PATH); 163 } 164 165 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) 166 { 167 if (paintingDisabled()) 168 return; 169 170 Color oldColor = m_data->fillColor(); 171 m_data->setFillColor(color); 172 m_data->drawRect(rect, VG_FILL_PATH); 173 m_data->setFillColor(oldColor); 174 175 UNUSED_PARAM(colorSpace); // FIXME 176 } 177 178 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace) 179 { 180 if (paintingDisabled()) 181 return; 182 183 Color oldColor = m_data->fillColor(); 184 m_data->setFillColor(color); 185 m_data->drawRoundedRect(rect, topLeft, topRight, bottomLeft, bottomRight, VG_FILL_PATH); 186 m_data->setFillColor(oldColor); 187 188 UNUSED_PARAM(colorSpace); // FIXME 189 } 190 191 void GraphicsContext::beginPath() 192 { 193 if (paintingDisabled()) 194 return; 195 196 notImplemented(); 197 } 198 199 void GraphicsContext::addPath(const Path& path) 200 { 201 if (paintingDisabled()) 202 return; 203 204 notImplemented(); 205 } 206 207 void GraphicsContext::clip(const FloatRect& rect) 208 { 209 if (paintingDisabled()) 210 return; 211 212 m_data->intersectClipRect(rect); 213 } 214 215 void GraphicsContext::clipPath(WindRule clipRule) 216 { 217 if (paintingDisabled()) 218 return; 219 220 notImplemented(); 221 UNUSED_PARAM(clipRule); 222 } 223 224 void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color) 225 { 226 if (paintingDisabled()) 227 return; 228 229 if (rects.isEmpty()) 230 return; 231 232 // FIXME: We just unite all focus ring rects into one for now. 233 // We should outline the edge of the full region. 234 offset += (width - 1) / 2; 235 IntRect finalFocusRect; 236 237 for (unsigned i = 0; i < rects.size(); i++) { 238 IntRect focusRect = rects[i]; 239 focusRect.inflate(offset); 240 finalFocusRect.unite(focusRect); 241 } 242 243 StrokeStyle oldStyle = m_data->strokeStyle(); 244 Color oldStrokeColor = m_data->strokeColor(); 245 m_data->setStrokeStyle(DashedStroke); 246 m_data->setStrokeColor(color); 247 strokeRect(FloatRect(finalFocusRect), 1.f); 248 m_data->setStrokeStyle(oldStyle); 249 m_data->setStrokeColor(oldStrokeColor); 250 } 251 252 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) 253 { 254 if (paintingDisabled()) 255 return; 256 257 if (width <= 0) 258 return; 259 260 StrokeStyle oldStyle = m_data->strokeStyle(); 261 m_data->setStrokeStyle(SolidStroke); 262 drawLine(origin, origin + IntSize(width, 0)); 263 m_data->setStrokeStyle(oldStyle); 264 265 UNUSED_PARAM(printing); 266 } 267 268 void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar) 269 { 270 if (paintingDisabled()) 271 return; 272 273 notImplemented(); 274 UNUSED_PARAM(origin); 275 UNUSED_PARAM(width); 276 UNUSED_PARAM(grammar); 277 } 278 279 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) 280 { 281 if (paintingDisabled()) 282 return FloatRect(); 283 284 return FloatRect(enclosingIntRect(m_data->transformationMatrix().mapRect(rect))); 285 } 286 287 void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color, ColorSpace colorSpace) 288 { 289 if (paintingDisabled()) 290 return; 291 292 notImplemented(); 293 UNUSED_PARAM(size); 294 UNUSED_PARAM(blur); 295 UNUSED_PARAM(color); 296 UNUSED_PARAM(colorSpace); 297 } 298 299 void GraphicsContext::clearPlatformShadow() 300 { 301 if (paintingDisabled()) 302 return; 303 304 notImplemented(); 305 } 306 307 void GraphicsContext::beginTransparencyLayer(float opacity) 308 { 309 if (paintingDisabled()) 310 return; 311 312 notImplemented(); 313 UNUSED_PARAM(opacity); 314 } 315 316 void GraphicsContext::endTransparencyLayer() 317 { 318 if (paintingDisabled()) 319 return; 320 321 notImplemented(); 322 } 323 324 void GraphicsContext::clearRect(const FloatRect& rect) 325 { 326 if (paintingDisabled()) 327 return; 328 329 CompositeOperator op = m_data->compositeOperation(); 330 m_data->setCompositeOperation(CompositeClear); 331 m_data->drawRect(rect, VG_FILL_PATH); 332 m_data->setCompositeOperation(op); 333 } 334 335 void GraphicsContext::strokeRect(const FloatRect& rect) 336 { 337 if (paintingDisabled()) 338 return; 339 340 m_data->drawRect(rect, VG_STROKE_PATH); 341 } 342 343 void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) 344 { 345 if (paintingDisabled()) 346 return; 347 348 float oldThickness = m_data->strokeThickness(); 349 m_data->setStrokeThickness(lineWidth); 350 m_data->drawRect(rect, VG_STROKE_PATH); 351 m_data->setStrokeThickness(oldThickness); 352 } 353 354 void GraphicsContext::setLineCap(LineCap lc) 355 { 356 if (paintingDisabled()) 357 return; 358 359 m_data->setLineCap(lc); 360 } 361 362 void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) 363 { 364 if (paintingDisabled()) 365 return; 366 367 m_data->setLineDash(dashes, dashOffset); 368 } 369 370 void GraphicsContext::setLineJoin(LineJoin lj) 371 { 372 if (paintingDisabled()) 373 return; 374 375 m_data->setLineJoin(lj); 376 } 377 378 void GraphicsContext::setMiterLimit(float limit) 379 { 380 if (paintingDisabled()) 381 return; 382 383 m_data->setMiterLimit(limit); 384 } 385 386 void GraphicsContext::setAlpha(float opacity) 387 { 388 if (paintingDisabled()) 389 return; 390 391 m_data->setOpacity(opacity); 392 } 393 394 void GraphicsContext::setCompositeOperation(CompositeOperator op) 395 { 396 if (paintingDisabled()) 397 return; 398 399 m_data->setCompositeOperation(op); 400 } 401 402 void GraphicsContext::clip(const Path& path) 403 { 404 if (paintingDisabled()) 405 return; 406 407 notImplemented(); 408 UNUSED_PARAM(path); 409 } 410 411 void GraphicsContext::canvasClip(const Path& path) 412 { 413 clip(path); 414 } 415 416 void GraphicsContext::clipOut(const Path& path) 417 { 418 if (paintingDisabled()) 419 return; 420 421 notImplemented(); 422 UNUSED_PARAM(path); 423 } 424 425 void GraphicsContext::scale(const FloatSize& scaleFactors) 426 { 427 if (paintingDisabled()) 428 return; 429 430 m_data->scale(scaleFactors); 431 } 432 433 void GraphicsContext::rotate(float radians) 434 { 435 if (paintingDisabled()) 436 return; 437 438 m_data->rotate(radians); 439 } 440 441 void GraphicsContext::translate(float dx, float dy) 442 { 443 if (paintingDisabled()) 444 return; 445 446 m_data->translate(dx, dy); 447 } 448 449 IntPoint GraphicsContext::origin() 450 { 451 if (paintingDisabled()) 452 return IntPoint(); 453 454 TransformationMatrix matrix = m_data->transformationMatrix(); 455 return IntPoint(roundf(matrix.m41()), roundf(matrix.m42())); 456 } 457 458 void GraphicsContext::clipOut(const IntRect& rect) 459 { 460 if (paintingDisabled()) 461 return; 462 463 notImplemented(); 464 UNUSED_PARAM(rect); 465 } 466 467 void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) 468 { 469 if (paintingDisabled()) 470 return; 471 472 notImplemented(); 473 UNUSED_PARAM(rect); 474 } 475 476 void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer) 477 { 478 if (paintingDisabled()) 479 return; 480 481 notImplemented(); 482 UNUSED_PARAM(rect); 483 UNUSED_PARAM(imageBuffer); 484 } 485 486 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) 487 { 488 if (paintingDisabled()) 489 return; 490 491 notImplemented(); 492 UNUSED_PARAM(rect); 493 UNUSED_PARAM(thickness); 494 } 495 496 void GraphicsContext::concatCTM(const TransformationMatrix& transform) 497 { 498 if (paintingDisabled()) 499 return; 500 501 m_data->concatTransformationMatrix(transform); 502 } 503 504 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) 505 { 506 notImplemented(); 507 UNUSED_PARAM(link); 508 UNUSED_PARAM(destRect); 509 } 510 511 void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace) 512 { 513 if (paintingDisabled()) 514 return; 515 516 m_data->setStrokeColor(color); 517 518 UNUSED_PARAM(colorSpace); // FIXME 519 } 520 521 void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle) 522 { 523 if (paintingDisabled()) 524 return; 525 526 m_data->setStrokeStyle(strokeStyle); 527 } 528 529 void GraphicsContext::setPlatformStrokeThickness(float thickness) 530 { 531 if (paintingDisabled()) 532 return; 533 534 m_data->setStrokeThickness(thickness); 535 } 536 537 void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace) 538 { 539 if (paintingDisabled()) 540 return; 541 542 m_data->setFillColor(color); 543 544 UNUSED_PARAM(colorSpace); // FIXME 545 } 546 547 void GraphicsContext::setPlatformShouldAntialias(bool enable) 548 { 549 if (paintingDisabled()) 550 return; 551 552 m_data->setAntialiasingEnabled(enable); 553 } 554 555 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) 556 { 557 notImplemented(); 558 } 559 560 InterpolationQuality GraphicsContext::imageInterpolationQuality() const 561 { 562 notImplemented(); 563 return InterpolationDefault; 564 } 565 566 } 567