Changeset 35966 in webkit
- Timestamp:
- Aug 28, 2008 5:04:40 AM (16 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r35964 r35966 1 2008-08-27 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Oliver Hunt. 4 5 Add stroke/fill Gradient and Pattern support to GraphicsContext and update <canvas> to use it. 6 https://bugs.webkit.org/show_bug.cgi?id=20373 7 8 Changed pattern() to canvasPattern() on CanvasStyle to match canvasGradient() 9 10 Made Generator (aka Gradient) RefCounted so that GraphicsContext didn't 11 have to store large Gradient objects in the GraphicsContextState 12 13 Made Pattern RefCounted for the same reason. 14 15 Many updates to GraphicsContext to support easier drawing with 16 Patterns and Gradients. 17 18 * WebCore.xcodeproj/project.pbxproj: Add pre-existing GraphicsContextPrivate.h 19 * bindings/js/JSCanvasRenderingContext2DCustom.cpp: 20 (WebCore::toJS): 21 * css/CSSGradientValue.cpp: 22 (WebCore::CSSGradientValue::createGradient): 23 * css/CSSGradientValue.h: 24 * html/CanvasGradient.cpp: 25 (WebCore::CanvasGradient::CanvasGradient): 26 * html/CanvasGradient.h: 27 (WebCore::CanvasGradient::gradient): 28 (WebCore::CanvasGradient::addColorStop): 29 (WebCore::CanvasGradient::getColor): 30 * html/CanvasPattern.cpp: 31 * html/CanvasPattern.h: 32 (WebCore::CanvasPattern::pattern): 33 (WebCore::CanvasPattern::originClean): 34 * html/CanvasRenderingContext2D.cpp: 35 (WebCore::CanvasRenderingContext2D::State::State): 36 (WebCore::CanvasRenderingContext2D::setStrokeStyle): 37 (WebCore::CanvasRenderingContext2D::setFillStyle): 38 (WebCore::CanvasRenderingContext2D::fill): 39 (WebCore::CanvasRenderingContext2D::stroke): 40 (WebCore::CanvasRenderingContext2D::fillRect): 41 (WebCore::CanvasRenderingContext2D::strokeRect): 42 * html/CanvasRenderingContext2D.h: 43 * html/CanvasStyle.cpp: 44 (WebCore::CanvasStyle::applyStrokeColor): 45 (WebCore::CanvasStyle::applyFillColor): 46 * html/CanvasStyle.h: 47 * platform/graphics/GeneratedImage.h: 48 (WebCore::GeneratedImage::GeneratedImage): 49 * platform/graphics/Generator.h: 50 * platform/graphics/Gradient.h: 51 (WebCore::Gradient::create): 52 * platform/graphics/GraphicsContext.cpp: 53 (WebCore::GraphicsContext::fillRule): 54 (WebCore::GraphicsContext::setFillRule): 55 (WebCore::GraphicsContext::setStrokePattern): 56 (WebCore::GraphicsContext::setFillPattern): 57 (WebCore::GraphicsContext::setStrokeGradient): 58 (WebCore::GraphicsContext::setFillGradient): 59 * platform/graphics/GraphicsContext.h: 60 * platform/graphics/GraphicsContextPrivate.h: 61 (WebCore::): 62 (WebCore::GraphicsContextState::GraphicsContextState): 63 * platform/graphics/GraphicsTypes.h: 64 * platform/graphics/Path.h: 65 * platform/graphics/Pattern.h: 66 (WebCore::Pattern::create): 67 (WebCore::Pattern::tileImage): 68 * platform/graphics/cg/GraphicsContextCG.cpp: 69 (WebCore::GraphicsContext::drawRect): 70 (WebCore::GraphicsContext::drawEllipse): 71 (WebCore::GraphicsContext::drawConvexPolygon): 72 (WebCore::calculateDrawingMode): 73 (WebCore::GraphicsContext::drawPath): 74 (WebCore::fillPathWithFillRule): 75 (WebCore::GraphicsContext::fillPath): 76 (WebCore::GraphicsContext::strokePath): 77 (WebCore::GraphicsContext::fillRect): 78 (WebCore::GraphicsContext::fillRoundedRect): 79 (WebCore::GraphicsContext::setPlatformStrokePattern): 80 (WebCore::GraphicsContext::setPlatformFillPattern): 81 (WebCore::GraphicsContext::setPlatformStrokeGradient): 82 (WebCore::GraphicsContext::setPlatformFillGradient): 83 1 84 2008-08-20 Eric Seidel <eric@webkit.org> 2 85 -
trunk/WebCore/WebCore.xcodeproj/project.pbxproj
r35939 r35966 2294 2294 A88DD4870B4629A300C02990 /* PathTraversalState.h in Headers */ = {isa = PBXBuildFile; fileRef = A88DD4860B4629A300C02990 /* PathTraversalState.h */; }; 2295 2295 A88DD4890B4629B000C02990 /* PathTraversalState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A88DD4880B4629B000C02990 /* PathTraversalState.cpp */; }; 2296 A88FE3340E5EEE87008D8C0F /* GraphicsContextPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A88FE3330E5EEE87008D8C0F /* GraphicsContextPrivate.h */; }; 2296 2297 A89943280B42338800D7C802 /* BitmapImage.h in Headers */ = {isa = PBXBuildFile; fileRef = A89943260B42338700D7C802 /* BitmapImage.h */; }; 2297 2298 A89943290B42338800D7C802 /* BitmapImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A89943270B42338700D7C802 /* BitmapImage.cpp */; }; … … 6664 6665 A88DD4860B4629A300C02990 /* PathTraversalState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathTraversalState.h; sourceTree = "<group>"; }; 6665 6666 A88DD4880B4629B000C02990 /* PathTraversalState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathTraversalState.cpp; sourceTree = "<group>"; }; 6667 A88FE3330E5EEE87008D8C0F /* GraphicsContextPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsContextPrivate.h; sourceTree = "<group>"; }; 6666 6668 A89943260B42338700D7C802 /* BitmapImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitmapImage.h; sourceTree = "<group>"; }; 6667 6669 A89943270B42338700D7C802 /* BitmapImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitmapImage.cpp; sourceTree = "<group>"; }; … … 12224 12226 BC53C6070DA56C570021EB5D /* Gradient.cpp */, 12225 12227 BC53C5F40DA56B920021EB5D /* Gradient.h */, 12228 A88FE3330E5EEE87008D8C0F /* GraphicsContextPrivate.h */, 12226 12229 B2A015920AF6CD53006BCE0E /* GraphicsContext.cpp */, 12227 12230 B2A015930AF6CD53006BCE0E /* GraphicsContext.h */, … … 15441 15444 08A484780E5272C500C3FE76 /* ScriptElement.h in Headers */, 15442 15445 A8FA6E5D0E4CFDED00D5CF49 /* Pattern.h in Headers */, 15446 A88FE3340E5EEE87008D8C0F /* GraphicsContextPrivate.h in Headers */, 15443 15447 ); 15444 15448 runOnlyForDeploymentPostprocessing = 0; -
trunk/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
r35291 r35966 45 45 if (style->canvasGradient()) 46 46 return toJS(exec, style->canvasGradient()); 47 if (style-> pattern())48 return toJS(exec, style-> pattern());47 if (style->canvasPattern()) 48 return toJS(exec, style->canvasPattern()); 49 49 return jsString(exec, style->color()); 50 50 } -
trunk/WebCore/css/CSSGradientValue.cpp
r32263 r35966 72 72 } 73 73 74 Gradient*CSSGradientValue::createGradient(RenderObject* renderer, const IntSize& size)74 PassRefPtr<Gradient> CSSGradientValue::createGradient(RenderObject* renderer, const IntSize& size) 75 75 { 76 76 ASSERT(!size.isEmpty()); … … 81 81 FloatPoint secondPoint = resolvePoint(m_secondX.get(), m_secondY.get(), size, zoomFactor); 82 82 83 Gradient* gradient = 0;83 RefPtr<Gradient> gradient; 84 84 if (m_type == CSSLinearGradient) 85 gradient = new Gradient(firstPoint, secondPoint);85 gradient = Gradient::create(firstPoint, secondPoint); 86 86 else { 87 87 float firstRadius = resolveRadius(m_firstRadius.get(), zoomFactor); 88 88 float secondRadius = resolveRadius(m_secondRadius.get(), zoomFactor); 89 gradient = new Gradient(firstPoint, firstRadius, secondPoint, secondRadius);89 gradient = Gradient::create(firstPoint, firstRadius, secondPoint, secondRadius); 90 90 } 91 91 … … 102 102 gradient->setStopsSorted(true); 103 103 104 return gradient ;104 return gradient.release(); 105 105 } 106 106 -
trunk/WebCore/css/CSSGradientValue.h
r34627 r35966 83 83 84 84 // Create the gradient for a given size. 85 Gradient*createGradient(RenderObject*, const IntSize&);85 PassRefPtr<Gradient> createGradient(RenderObject*, const IntSize&); 86 86 87 87 // Resolve points/radii to front end values. -
trunk/WebCore/html/CanvasGradient.cpp
r34366 r35966 33 33 34 34 CanvasGradient::CanvasGradient(const FloatPoint& p0, const FloatPoint& p1) 35 : m_gradient( p0, p1)35 : m_gradient(Gradient::create(p0, p1)) 36 36 { 37 37 } 38 38 39 39 CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1) 40 : m_gradient( p0, r0, p1, r1)40 : m_gradient(Gradient::create(p0, r0, p1, r1)) 41 41 { 42 42 } -
trunk/WebCore/html/CanvasGradient.h
r34432 r35966 47 47 } 48 48 49 Gradient & gradient() { return m_gradient; }49 Gradient* gradient() const { return m_gradient.get(); } 50 50 51 void addColorStop(float value, const String& color) { m_gradient .addColorStop(value, color); }51 void addColorStop(float value, const String& color) { m_gradient->addColorStop(value, color); } 52 52 53 void getColor(float value, float* r, float* g, float* b, float* a) const { m_gradient .getColor(value, r, g, b, a); }53 void getColor(float value, float* r, float* g, float* b, float* a) const { m_gradient->getColor(value, r, g, b, a); } 54 54 55 55 private: … … 57 57 CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1); 58 58 59 Gradientm_gradient;59 RefPtr<Gradient> m_gradient; 60 60 }; 61 61 -
trunk/WebCore/html/CanvasPattern.cpp
r35732 r35966 59 59 60 60 CanvasPattern::CanvasPattern(Image* image, bool repeatX, bool repeatY, bool originClean) 61 : m_pattern( image, repeatX, repeatY)61 : m_pattern(Pattern::create(image, repeatX, repeatY)) 62 62 , m_originClean(originClean) 63 63 { -
trunk/WebCore/html/CanvasPattern.h
r35732 r35966 46 46 return adoptRef(new CanvasPattern(image, repeatX, repeatY, originClean)); 47 47 } 48 49 const Pattern& pattern() { return m_pattern; }48 49 Pattern* pattern() const { return m_pattern.get(); } 50 50 51 51 bool originClean() const { return m_originClean; } … … 54 54 CanvasPattern(Image*, bool repeatX, bool repeatY, bool originClean); 55 55 56 Patternm_pattern;56 RefPtr<Pattern> m_pattern; 57 57 bool m_originClean; 58 58 }; -
trunk/WebCore/html/CanvasRenderingContext2D.cpp
r35955 r35966 3 3 * Copyright (C) 2007 Trolltech ASA 4 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 5 6 * 6 7 * Redistribution and use in source and binary forms, with or without … … 102 103 , m_globalAlpha(1) 103 104 , m_globalComposite(CompositeSourceOver) 104 , m_appliedStrokePattern(false)105 , m_appliedFillPattern(false)106 105 { 107 106 } … … 142 141 143 142 if (m_canvas->originClean()) { 144 if (CanvasPattern* pattern = style-> pattern()) {143 if (CanvasPattern* pattern = style->canvasPattern()) { 145 144 if (!pattern->originClean()) 146 145 m_canvas->setOriginTainted(); … … 153 152 return; 154 153 state().m_strokeStyle->applyStrokeColor(c); 155 state().m_appliedStrokePattern = false;156 154 } 157 155 … … 167 165 168 166 if (m_canvas->originClean()) { 169 if (CanvasPattern* pattern = style-> pattern()) {167 if (CanvasPattern* pattern = style->canvasPattern()) { 170 168 if (!pattern->originClean()) 171 169 m_canvas->setOriginTainted(); … … 178 176 return; 179 177 state().m_fillStyle->applyFillColor(c); 180 state().m_appliedFillPattern = false;181 178 } 182 179 … … 543 540 willDraw(m_path.boundingRect()); 544 541 545 #if PLATFORM(CG) 546 if (state().m_fillStyle->canvasGradient()) { 547 // Shading works on the entire clip region, so convert the current path to a clip. 548 c->save(); 549 CGContextClip(c->platformContext()); 550 CGContextDrawShading(c->platformContext(), state().m_fillStyle->canvasGradient()->gradient().platformGradient()); 551 c->restore(); 552 } else { 553 if (state().m_fillStyle->pattern()) 554 applyFillPattern(); 555 CGContextFillPath(c->platformContext()); 556 } 557 #elif PLATFORM(QT) 558 QPainterPath* path = m_path.platformPath(); 559 QPainter* p = static_cast<QPainter*>(c->platformContext()); 560 if (state().m_fillStyle->canvasGradient()) { 561 p->fillPath(*path, QBrush(*(state().m_fillStyle->canvasGradient()->gradient().platformGradient()))); 562 } else { 563 if (state().m_fillStyle->pattern()) 564 applyFillPattern(); 565 p->fillPath(*path, p->brush()); 566 } 567 #elif PLATFORM(CAIRO) 568 cairo_t* cr = c->platformContext(); 569 cairo_save(cr); 570 571 if (state().m_fillStyle->canvasGradient()) { 572 cairo_set_source(cr, state().m_fillStyle->canvasGradient()->gradient().platformGradient()); 573 cairo_fill(cr); 574 } else { 575 if (state().m_fillStyle->pattern()) 576 applyFillPattern(); 577 else { 578 float red, green, blue, alpha; 579 c->fillColor().getRGBA(red, green, blue, alpha); 580 cairo_set_source_rgba(cr, red, green, blue, alpha); 581 } 582 cairo_fill(cr); 583 } 584 cairo_restore(cr); 585 #endif 542 c->fillPath(); 586 543 587 544 #if ENABLE(DASHBOARD_SUPPORT) … … 606 563 willDraw(boundingRect); 607 564 } 608 609 // FIXME: Do this through platform-independent GraphicsContext API. 610 #if PLATFORM(CG) 611 if (state().m_strokeStyle->canvasGradient()) { 612 // Shading works on the entire clip region, so convert the current path to a clip. 613 c->save(); 614 CGContextReplacePathWithStrokedPath(c->platformContext()); 615 CGContextClip(c->platformContext()); 616 CGContextDrawShading(c->platformContext(), state().m_strokeStyle->canvasGradient()->gradient().platformGradient()); 617 c->restore(); 618 } else { 619 if (state().m_strokeStyle->pattern()) 620 applyStrokePattern(); 621 CGContextStrokePath(c->platformContext()); 622 } 623 #elif PLATFORM(QT) 624 QPainterPath* path = m_path.platformPath(); 625 QPainter* p = static_cast<QPainter*>(c->platformContext()); 626 if (state().m_strokeStyle->canvasGradient()) { 627 p->save(); 628 p->setBrush(*(state().m_strokeStyle->canvasGradient()->gradient().platformGradient())); 629 p->strokePath(*path, p->pen()); 630 p->restore(); 631 } else { 632 if (state().m_strokeStyle->pattern()) 633 applyStrokePattern(); 634 p->strokePath(*path, p->pen()); 635 } 636 #elif PLATFORM(CAIRO) 637 cairo_t* cr = c->platformContext(); 638 cairo_save(cr); 639 if (state().m_strokeStyle->canvasGradient()) { 640 cairo_set_source(cr, state().m_strokeStyle->canvasGradient()->gradient().platformGradient()); 641 c->addPath(m_path); 642 cairo_stroke(cr); 643 } else { 644 if (state().m_strokeStyle->pattern()) 645 applyStrokePattern(); 646 else { 647 float red, green, blue, alpha; 648 c->strokeColor().getRGBA(red, green, blue, alpha); 649 cairo_set_source_rgba(cr, red, green, blue, alpha); 650 } 651 c->addPath(m_path); 652 cairo_stroke(cr); 653 } 654 cairo_restore(cr); 655 #endif 565 566 c->strokePath(); 656 567 657 568 #if ENABLE(DASHBOARD_SUPPORT) … … 710 621 willDraw(rect); 711 622 712 // FIXME: Do this through platform-independent GraphicsContext API. 713 #if PLATFORM(CG) 714 if (state().m_fillStyle->canvasGradient()) { 715 c->save(); 716 state().m_fillStyle->canvasGradient()->gradient().fill(c, rect); 717 c->restore(); 718 } else { 719 if (state().m_fillStyle->pattern()) 720 applyFillPattern(); 721 CGContextFillRect(c->platformContext(), rect); 722 } 723 #elif PLATFORM(QT) 724 QPainter* p = static_cast<QPainter*>(c->platformContext()); 725 if (state().m_fillStyle->canvasGradient()) { 726 p->fillRect(rect, QBrush(*(state().m_fillStyle->canvasGradient()->gradient().platformGradient()))); 727 } else { 728 if (state().m_fillStyle->pattern()) 729 applyFillPattern(); 730 p->fillRect(rect, p->brush()); 731 } 732 #elif PLATFORM(CAIRO) 733 cairo_t* cr = c->platformContext(); 734 cairo_save(cr); 735 if (state().m_fillStyle->canvasGradient()) { 736 state().m_fillStyle->canvasGradient()->gradient().fill(c, rect); 737 } else { 738 if (state().m_fillStyle->pattern()) { 739 applyFillPattern(); 740 cairo_rectangle(cr, x, y, width, height); 741 cairo_fill(cr); 742 } else 743 c->fillRect(rect, c->fillColor()); 744 } 745 746 cairo_restore(cr); 747 #endif 623 c->save(); 624 c->fillRect(rect); 625 c->restore(); 748 626 } 749 627 … … 772 650 boundingRect.inflate(lineWidth / 2); 773 651 willDraw(boundingRect); 774 775 // FIXME: No support for gradients!776 if (state().m_strokeStyle->pattern())777 applyStrokePattern();778 652 779 653 c->strokeRect(rect, lineWidth); … … 1175 1049 } 1176 1050 1177 void CanvasRenderingContext2D::applyStrokePattern()1178 {1179 GraphicsContext* c = drawingContext();1180 if (!c)1181 return;1182 1183 // FIXME: Can this check be moved into GraphicsContext? or removed?1184 #if PLATFORM(CG)1185 // Check for case where the pattern is already set.1186 AffineTransform ctm = c->getCTM();1187 if (state().m_appliedStrokePattern && ctm == state().m_strokeStylePatternTransform)1188 return;1189 #endif1190 1191 CanvasPattern* pattern = state().m_strokeStyle->pattern();1192 if (!pattern)1193 return;1194 1195 c->applyStrokePattern(pattern->pattern());1196 1197 #if PLATFORM(CG)1198 state().m_strokeStylePatternTransform = ctm;1199 #endif1200 state().m_appliedStrokePattern = true;1201 }1202 1203 void CanvasRenderingContext2D::applyFillPattern()1204 {1205 GraphicsContext* c = drawingContext();1206 if (!c)1207 return;1208 1209 // FIXME: Can this check be moved into GraphicsContext? or removed?1210 #if PLATFORM(CG)1211 // Check for case where the pattern is already set.1212 AffineTransform ctm = c->getCTM();1213 if (state().m_appliedFillPattern && ctm == state().m_fillStylePatternTransform)1214 return;1215 #endif1216 1217 CanvasPattern* pattern = state().m_fillStyle->pattern();1218 if (!pattern)1219 return;1220 1221 c->applyFillPattern(pattern->pattern());1222 1223 #if PLATFORM(CG)1224 state().m_fillStylePatternTransform = ctm;1225 #endif1226 state().m_appliedFillPattern = true;1227 }1228 1229 1051 static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size) 1230 1052 { -
trunk/WebCore/html/CanvasRenderingContext2D.h
r35732 r35966 192 192 float m_globalAlpha; 193 193 CompositeOperator m_globalComposite; 194 bool m_appliedStrokePattern;195 bool m_appliedFillPattern;196 194 AffineTransform m_transform; 197 #if PLATFORM(CG)198 AffineTransform m_strokeStylePatternTransform;199 AffineTransform m_fillStylePatternTransform;200 #endif201 195 }; 202 196 Path m_path; -
trunk/WebCore/html/CanvasStyle.cpp
r35766 r35966 3 3 * Copyright (C) 2007 Trolltech ASA 4 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 5 6 * 6 7 * Redistribution and use in source and binary forms, with or without … … 142 143 } 143 144 case Gradient: 145 context->setStrokeGradient(canvasGradient()->gradient()); 146 break; 144 147 case ImagePattern: 148 context->setStrokePattern(canvasPattern()->pattern()); 145 149 break; 146 150 } … … 188 192 } 189 193 case Gradient: 194 context->setFillGradient(canvasGradient()->gradient()); 195 break; 190 196 case ImagePattern: 197 context->setFillPattern(canvasPattern()->pattern()); 191 198 break; 192 199 } -
trunk/WebCore/html/CanvasStyle.h
r35730 r35966 48 48 String color() const { return m_color; } 49 49 CanvasGradient* canvasGradient() const { return m_gradient.get(); } 50 CanvasPattern* pattern() const { return m_pattern.get(); }50 CanvasPattern* canvasPattern() const { return m_pattern.get(); } 51 51 52 // These do nothing for gradients or patterns.53 52 void applyFillColor(GraphicsContext*); 54 53 void applyStrokeColor(GraphicsContext*); -
trunk/WebCore/platform/graphics/GeneratedImage.h
r35934 r35966 31 31 #include "Generator.h" 32 32 #include "IntSize.h" 33 #include <wtf/ OwnPtr.h>33 #include <wtf/RefPtr.h> 34 34 35 35 namespace WebCore { … … 37 37 class GeneratedImage : public Image { 38 38 public: 39 GeneratedImage(Generator* generator, const IntSize& size) 40 : m_size(size) 39 GeneratedImage(PassRefPtr<Generator> generator, const IntSize& size) 40 : m_generator(generator) 41 , m_size(size) 41 42 { 42 m_generator.set(generator);43 43 } 44 44 virtual ~GeneratedImage() {} … … 64 64 65 65 protected: 66 OwnPtr<Generator> m_generator;66 RefPtr<Generator> m_generator; 67 67 IntSize m_size; 68 68 }; -
trunk/WebCore/platform/graphics/Generator.h
r31830 r35966 27 27 #define Generator_h 28 28 29 #include <wtf/ Noncopyable.h>29 #include <wtf/RefCounted.h> 30 30 31 31 namespace WebCore { … … 34 34 class GraphicsContext; 35 35 36 class Generator : Noncopyable{36 class Generator : public RefCounted<Generator> { 37 37 public: 38 38 virtual ~Generator() {}; -
trunk/WebCore/platform/graphics/Gradient.h
r35852 r35966 31 31 32 32 #include "FloatPoint.h" 33 #include <wtf/PassRefPtr.h> 33 34 #include <wtf/Vector.h> 34 35 … … 59 60 class Gradient : public Generator { 60 61 public: 61 Gradient(const FloatPoint& p0, const FloatPoint& p1); 62 Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1); 62 static PassRefPtr<Gradient> create(const FloatPoint& p0, const FloatPoint& p1) 63 { 64 return adoptRef(new Gradient(p0, p1)); 65 } 66 static PassRefPtr<Gradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1) 67 { 68 return adoptRef(new Gradient(p0, r0, p1, r1)); 69 } 63 70 virtual ~Gradient(); 64 71 … … 76 83 float blue; 77 84 float alpha; 78 85 79 86 ColorStop() : stop(0), red(0), green(0), blue(0), alpha(0) { } 80 87 ColorStop(float s, float r, float g, float b, float a) : stop(s), red(r), green(g), blue(b), alpha(a) { } … … 86 93 87 94 private: 95 Gradient(const FloatPoint& p0, const FloatPoint& p1); 96 Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1); 97 88 98 void platformInit() { m_gradient = 0; } 89 99 void platformDestroy(); -
trunk/WebCore/platform/graphics/GraphicsContext.cpp
r35301 r35966 135 135 void GraphicsContext::setStrokeColor(const Color& color) 136 136 { 137 m_common->state.strokeColorSpace = SolidColorSpace; 137 138 m_common->state.strokeColor = color; 138 139 setPlatformStrokeColor(color); … … 179 180 } 180 181 182 WindRule GraphicsContext::fillRule() const 183 { 184 return m_common->state.fillRule; 185 } 186 187 void GraphicsContext::setFillRule(WindRule fillRule) 188 { 189 m_common->state.fillRule = fillRule; 190 } 191 181 192 void GraphicsContext::setFillColor(const Color& color) 182 193 { 194 m_common->state.fillColorSpace = SolidColorSpace; 183 195 m_common->state.fillColor = color; 184 196 setPlatformFillColor(color); … … 188 200 { 189 201 return m_common->state.fillColor; 202 } 203 204 void GraphicsContext::setStrokePattern(PassRefPtr<Pattern> pattern) 205 { 206 ASSERT(pattern); 207 if (!pattern) { 208 setStrokeColor(Color::black); 209 return; 210 } 211 m_common->state.strokeColorSpace = PatternColorSpace; 212 m_common->state.strokePattern = pattern; 213 setPlatformStrokePattern(m_common->state.strokePattern.get()); 214 } 215 216 void GraphicsContext::setFillPattern(PassRefPtr<Pattern> pattern) 217 { 218 ASSERT(pattern); 219 if (!pattern) { 220 setFillColor(Color::black); 221 return; 222 } 223 m_common->state.fillColorSpace = PatternColorSpace; 224 m_common->state.fillPattern = pattern; 225 setPlatformFillPattern(m_common->state.fillPattern.get()); 226 } 227 228 void GraphicsContext::setStrokeGradient(PassRefPtr<Gradient> gradient) 229 { 230 ASSERT(gradient); 231 if (!gradient) { 232 setStrokeColor(Color::black); 233 return; 234 } 235 m_common->state.strokeColorSpace = GradientColorSpace; 236 m_common->state.strokeGradient = gradient; 237 setPlatformStrokeGradient(m_common->state.strokeGradient.get()); 238 } 239 240 void GraphicsContext::setFillGradient(PassRefPtr<Gradient> gradient) 241 { 242 ASSERT(gradient); 243 if (!gradient) { 244 setFillColor(Color::black); 245 return; 246 } 247 m_common->state.fillColorSpace = GradientColorSpace; 248 m_common->state.fillGradient = gradient; 249 setPlatformFillGradient(m_common->state.fillGradient.get()); 190 250 } 191 251 … … 427 487 #endif 428 488 429 #if !PLATFORM(CG) && !PLATFORM(CAIRO)430 // Other platforms need to implement this.431 void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)432 {433 notImplemented();434 }435 #endif436 437 489 #if !PLATFORM(QT) && !PLATFORM(CAIRO) 438 490 void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle&) -
trunk/WebCore/platform/graphics/GraphicsContext.h
r35897 r35966 95 95 class Font; 96 96 class Generator; 97 class Gradient; 97 98 class GraphicsContextPrivate; 98 99 class GraphicsContextPlatformPrivate; … … 140 141 Color strokeColor() const; 141 142 void setStrokeColor(const Color&); 142 143 void setStrokePattern(PassRefPtr<Pattern>); 144 void setStrokeGradient(PassRefPtr<Gradient>); 145 146 WindRule fillRule() const; 147 void setFillRule(WindRule); 143 148 Color fillColor() const; 144 149 void setFillColor(const Color&); 145 146 void applyStrokePattern(const Pattern&); 147 void applyFillPattern(const Pattern&); 150 void setFillPattern(PassRefPtr<Pattern>); 151 void setFillGradient(PassRefPtr<Gradient>); 148 152 149 153 void save(); 150 154 void restore(); 151 155 152 156 // These draw methods will do both stroking and filling. 153 157 void drawRect(const IntRect&); … … 156 160 void drawConvexPolygon(size_t numPoints, const FloatPoint*, bool shouldAntialias = false); 157 161 162 void drawPath(); 163 void fillPath(); 164 void strokePath(); 165 158 166 // Arc drawing (used by border-radius in CSS) just supports stroking at the moment. 159 167 void strokeArc(const IntRect&, int startAngle, int angleSpan); 160 161 void fillRect(const IntRect&, const Color&);168 169 void fillRect(const FloatRect&); 162 170 void fillRect(const FloatRect&, const Color&); 163 171 void fillRect(const FloatRect&, Generator&); 164 172 void fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&); 173 165 174 void clearRect(const FloatRect&); 175 176 void strokeRect(const FloatRect&); 166 177 void strokeRect(const FloatRect&, float lineWidth); 167 178 … … 178 189 CompositeOperator = CompositeSourceOver); 179 190 180 #if PLATFORM(CG)181 191 void setImageInterpolationQuality(InterpolationQuality); 182 192 InterpolationQuality imageInterpolationQuality() const; 183 #else184 void setImageInterpolationQuality(InterpolationQuality) {}185 InterpolationQuality imageInterpolationQuality() const { return InterpolationDefault; }186 #endif187 193 188 194 void clip(const FloatRect&); … … 289 295 #if PLATFORM(QT) 290 296 bool inTransparencyLayer() const; 291 void setFillRule(WindRule);292 297 PlatformPath* currentPath(); 293 298 #endif … … 302 307 void savePlatformState(); 303 308 void restorePlatformState(); 309 304 310 void setPlatformTextDrawingMode(int); 311 void setPlatformFont(const Font& font); 312 305 313 void setPlatformStrokeColor(const Color&); 314 void setPlatformStrokePattern(Pattern*); 315 void setPlatformStrokeGradient(Gradient*); 306 316 void setPlatformStrokeStyle(const StrokeStyle&); 307 317 void setPlatformStrokeThickness(float); 318 308 319 void setPlatformFillColor(const Color&); 309 void setPlatformFont(const Font& font); 320 void setPlatformFillPattern(Pattern*); 321 void setPlatformFillGradient(Gradient*); 322 310 323 void setPlatformShadow(const IntSize&, int blur, const Color&); 311 324 void clearPlatformShadow(); -
trunk/WebCore/platform/graphics/GraphicsContextPrivate.h
r31246 r35966 28 28 29 29 #include "Font.h" 30 #include "Gradient.h" 31 #include "Pattern.h" 30 32 31 33 namespace WebCore { 32 34 35 // FIXME: This is a place-holder until we decide to add 36 // real color space support to WebCore. At that time, ColorSpace will be a 37 // class and instances will be held off of Colors. There will be 38 // special singleton Gradient and Pattern color spaces to mark when 39 // a fill or stroke is using a gradient or pattern instead of a solid color. 40 // https://bugs.webkit.org/show_bug.cgi?id=20558 41 enum ColorSpace { 42 SolidColorSpace, 43 PatternColorSpace, 44 GradientColorSpace 45 }; 46 33 47 struct GraphicsContextState { 34 48 GraphicsContextState() 35 : strokeStyle(SolidStroke) 49 : textDrawingMode(cTextFill) 50 , strokeStyle(SolidStroke) 36 51 , strokeThickness(0) 52 , strokeColorSpace(SolidColorSpace) 37 53 , strokeColor(Color::black) 54 , fillRule(RULE_NONZERO) 55 , fillColorSpace(SolidColorSpace) 38 56 , fillColor(Color::black) 39 , textDrawingMode(cTextFill)40 57 , paintingDisabled(false) 41 58 , shadowBlur(0) … … 44 61 45 62 Font font; 63 int textDrawingMode; 64 46 65 StrokeStyle strokeStyle; 47 66 float strokeThickness; 67 ColorSpace strokeColorSpace; 48 68 Color strokeColor; 69 RefPtr<Gradient> strokeGradient; 70 RefPtr<Pattern> strokePattern; 71 72 WindRule fillRule; 73 ColorSpace fillColorSpace; 49 74 Color fillColor; 50 int textDrawingMode; 75 RefPtr<Gradient> fillGradient; 76 RefPtr<Pattern> fillPattern; 77 51 78 bool paintingDisabled; 79 52 80 IntSize shadowSize; 53 81 unsigned shadowBlur; -
trunk/WebCore/platform/graphics/GraphicsTypes.h
r28877 r35966 66 66 bool parseLineJoin(const String&, LineJoin&); 67 67 68 } 68 } // namespace WebCore 69 69 70 70 #endif -
trunk/WebCore/platform/graphics/Path.h
r35852 r35966 99 99 void moveTo(const FloatPoint&); 100 100 void addLineTo(const FloatPoint&); 101 void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& point);102 void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& );101 void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint); 102 void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint); 103 103 void addArcTo(const FloatPoint&, const FloatPoint&, float radius); 104 104 void closeSubpath(); … … 109 109 110 110 void translate(const FloatSize&); 111 112 void setWindingRule(WindRule rule) { m_rule = rule; }113 WindRule windingRule() const { return m_rule; }114 111 115 112 String debugString() const; … … 129 126 private: 130 127 PlatformPath* m_path; 131 WindRule m_rule;132 128 }; 133 129 -
trunk/WebCore/platform/graphics/Pattern.h
r35852 r35966 28 28 #define Pattern_h 29 29 30 #include <wtf/Noncopyable.h> 30 #include <wtf/PassRefPtr.h> 31 #include <wtf/RefCounted.h> 31 32 #include <wtf/RefPtr.h> 32 33 … … 57 58 class Image; 58 59 59 class Pattern : Noncopyable{60 class Pattern : public RefCounted<Pattern> { 60 61 public: 61 Pattern(Image*, bool repeatX, bool repeatY); 62 static PassRefPtr<Pattern> create(Image* tileImage, bool repeatX, bool repeatY) 63 { 64 return adoptRef(new Pattern(tileImage, repeatX, repeatY)); 65 } 66 virtual ~Pattern(); 62 67 63 virtual ~Pattern();64 65 68 Image* tileImage() const { return m_tileImage.get(); } 66 69 … … 68 71 69 72 private: 73 Pattern(Image*, bool repeatX, bool repeatY); 74 70 75 RefPtr<Image> m_tileImage; 71 76 bool m_repeatX; -
trunk/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r35869 r35966 1 1 /* 2 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 30 31 #include "AffineTransform.h" 31 32 #include "FloatConversion.h" 33 #include "GraphicsContextPrivate.h" 32 34 #include "GraphicsContextPlatformPrivateCG.h" 33 35 #include "ImageBuffer.h" … … 108 110 void GraphicsContext::drawRect(const IntRect& rect) 109 111 { 112 // FIXME: this function does not handle patterns and gradients 113 // like drawPath does, it probably should. 110 114 if (paintingDisabled()) 111 115 return; … … 262 266 CGContextClosePath(context); 263 267 264 if (fillColor().alpha()) { 265 if (strokeStyle() != NoStroke) 266 // stroke and fill 267 CGContextDrawPath(context, kCGPathFillStroke); 268 else 269 CGContextFillPath(context); 270 } else if (strokeStyle() != NoStroke) 271 CGContextStrokePath(context); 268 drawPath(); 272 269 } 273 270 … … 382 379 CGContextClosePath(context); 383 380 384 if (fillColor().alpha()) { 385 if (strokeStyle() != NoStroke) 386 CGContextDrawPath(context, kCGPathEOFillStroke); 381 drawPath(); 382 383 CGContextRestoreGState(context); 384 } 385 386 static inline bool calculateDrawingMode(const GraphicsContextState& state, CGPathDrawingMode& mode) 387 { 388 bool shouldFill = state.fillColorSpace == PatternColorSpace || state.fillColor.alpha(); 389 bool shouldStroke = state.strokeColorSpace == PatternColorSpace || (state.strokeStyle != NoStroke && state.strokeColor.alpha()); 390 bool useEOFill = state.fillRule == RULE_EVENODD; 391 392 if (shouldFill) { 393 if (shouldStroke) { 394 if (useEOFill) 395 mode = kCGPathEOFillStroke; 396 else 397 mode = kCGPathFillStroke; 398 } else { // fill, no stroke 399 if (useEOFill) 400 mode = kCGPathEOFill; 401 else 402 mode = kCGPathFill; 403 } 404 } else if (shouldStroke) // no fill, just stroke 405 mode = kCGPathStroke; 406 407 return shouldFill || shouldStroke; 408 } 409 410 void GraphicsContext::drawPath() 411 { 412 if (paintingDisabled()) 413 return; 414 415 CGContextRef context = platformContext(); 416 const GraphicsContextState& state = m_common->state; 417 418 if (state.fillColorSpace == GradientColorSpace || state.strokeColorSpace == GradientColorSpace) { 419 // We don't have any optimized way to fill & stroke a path using gradients 420 fillPath(); 421 strokePath(); 422 return; 423 } 424 425 CGPathDrawingMode drawingMode; 426 if (calculateDrawingMode(state, drawingMode)) 427 CGContextDrawPath(context, drawingMode); 428 } 429 430 static inline void fillPathWithFillRule(CGContextRef context, WindRule fillRule) 431 { 432 if (fillRule == RULE_EVENODD) 433 CGContextEOFillPath(context); 434 else 435 CGContextFillPath(context); 436 } 437 438 void GraphicsContext::fillPath() 439 { 440 if (paintingDisabled()) 441 return; 442 443 CGContextRef context = platformContext(); 444 switch (m_common->state.fillColorSpace) { 445 case SolidColorSpace: 446 if (!fillColor().alpha()) 447 return; 448 // fall through 449 case PatternColorSpace: 450 fillPathWithFillRule(context, fillRule()); 451 break; 452 case GradientColorSpace: 453 if (fillRule() == RULE_EVENODD) 454 CGContextEOClip(context); 387 455 else 388 CGContextEOFillPath(context); 389 } else 456 CGContextClip(context); 457 CGContextDrawShading(context, m_common->state.fillGradient->platformGradient()); 458 break; 459 } 460 } 461 462 void GraphicsContext::strokePath() 463 { 464 if (paintingDisabled()) 465 return; 466 467 CGContextRef context = platformContext(); 468 switch (m_common->state.strokeColorSpace) { 469 case SolidColorSpace: 470 if (!fillColor().alpha()) 471 return; 472 // fall through 473 case PatternColorSpace: 390 474 CGContextStrokePath(context); 391 392 CGContextRestoreGState(context); 393 } 394 395 void GraphicsContext::fillRect(const IntRect& rect, const Color& color) 475 break; 476 case GradientColorSpace: 477 CGContextReplacePathWithStrokedPath(context); 478 CGContextClip(context); 479 CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient()); 480 break; 481 } 482 } 483 484 void GraphicsContext::fillRect(const FloatRect& rect) 485 { 486 if (paintingDisabled()) 487 return; 488 switch (m_common->state.fillColorSpace) { 489 case SolidColorSpace: 490 if (fillColor().alpha()) 491 CGContextFillRect(platformContext(), rect); 492 break; 493 case PatternColorSpace: 494 CGContextFillRect(platformContext(), rect); 495 break; 496 case GradientColorSpace: 497 clip(rect); 498 CGContextDrawShading(platformContext(), m_common->state.fillGradient->platformGradient()); 499 break; 500 } 501 } 502 503 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) 396 504 { 397 505 if (paintingDisabled()) … … 408 516 } 409 517 410 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)411 {412 if (paintingDisabled())413 return;414 if (color.alpha()) {415 CGContextRef context = platformContext();416 Color oldFillColor = fillColor();417 if (oldFillColor != color)418 setCGFillColor(context, color);419 CGContextFillRect(context, rect);420 if (oldFillColor != color)421 setCGFillColor(context, oldFillColor);422 }423 }424 425 518 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color) 426 519 { … … 434 527 435 528 addPath(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); 436 CGContextFillPath(context);529 fillPath(); 437 530 438 531 if (oldFillColor != color) 439 532 setCGFillColor(context, oldFillColor); 440 533 } 441 442 534 443 535 void GraphicsContext::clip(const FloatRect& rect) … … 911 1003 } 912 1004 913 void GraphicsContext::applyStrokePattern(const Pattern& pattern) 914 { 915 CGPatternRef platformPattern = pattern.createPlatformPattern(getCTM()); 1005 // FIXME: It is unclear if setting patterns on the CGContext at 1006 // setStrokePattern/setFillPattern time is safe. Our Pattern object currently 1007 // depends on the CTM for CGShading creation, thus setting a pattern and then 1008 // transforming the GraphicsContext may cause the pattern to draw incorrectly. 1009 // I believe we can fix our Pattern object to not depend on the CTM. 1010 void GraphicsContext::setPlatformStrokePattern(Pattern* pattern) 1011 { 1012 if (paintingDisabled()) 1013 return; 1014 CGPatternRef platformPattern = pattern->createPlatformPattern(getCTM()); 916 1015 if (!platformPattern) 917 1016 return; … … 926 1025 } 927 1026 928 void GraphicsContext::applyFillPattern(const Pattern& pattern) 929 { 930 CGPatternRef platformPattern = pattern.createPlatformPattern(getCTM()); 1027 void GraphicsContext::setPlatformFillPattern(Pattern* pattern) 1028 { 1029 if (paintingDisabled()) 1030 return; 1031 CGPatternRef platformPattern = pattern->createPlatformPattern(getCTM()); 931 1032 if (!platformPattern) 932 1033 return; … … 939 1040 CGContextSetFillPattern(platformContext(), platformPattern, &patternAlpha); 940 1041 CGPatternRelease(platformPattern); 1042 } 1043 1044 void GraphicsContext::setPlatformStrokeGradient(Gradient*) 1045 { 1046 // CoreGraphics does not support setting a "stroke gradient", only 1047 // filling a clip region with a gradient, which we do at draw time 1048 } 1049 1050 void GraphicsContext::setPlatformFillGradient(Gradient*) 1051 { 1052 // CoreGraphics does not support setting a "fill gradient", only 1053 // filling a clip region with a gradient, which we do at draw time 941 1054 } 942 1055
Note: See TracChangeset
for help on using the changeset viewer.