Bug #: 5969
authoreseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Jan 2006 09:10:04 +0000 (09:10 +0000)
committereseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Jan 2006 09:10:04 +0000 (09:10 +0000)
Submitted by: Alexander Kellett  <lypanov@kde.org>
Reviewed by: eseidel
        Basic support for <mask> tag.
        http://bugzilla.opendarwin.org/show_bug.cgi?id=5969
        Still missing attribute support for: maskUnits, maskContentUnits.

        Mask pixel tests do not work in DumpRenderTree due to:
        http://bugzilla.opendarwin.org/show_bug.cgi?id=6327
        Added test cases anyway.

        This also tickles a (known) gradient update issue:
        http://bugzilla.opendarwin.org/show_bug.cgi?id=6052

        * WebCore.xcodeproj/project.pbxproj: added Mask files
        * kcanvas/KCanvasResources.cpp:
        (KCanvasMasker::KCanvasMasker): added.
        (KCanvasMasker::~KCanvasMasker): added.
        (KCanvasMasker::setMask): added.
        (KCanvasMasker::externalRepresentation): added.
        (getMaskerById): added.
        * kcanvas/KCanvasResources.h:
        (KCanvasResource::isMasker): added.
        (KCanvasMasker::isMasker): added.
        (KCanvasMasker::mask): added.
        * kcanvas/device/quartz/KCanvasItemQuartz.mm:
        (KCanvasItemQuartz::paint): added mask support
        * kcanvas/device/quartz/KCanvasMaskerQuartz.h: Added.
        (KCanvasMaskerQuartz::KCanvasMaskerQuartz): added.
        * kcanvas/device/quartz/KCanvasMaskerQuartz.mm: Added.
        (applyLuminanceToAlphaFilter): added.
        (applyExpandAlphatoGrayscaleFilter): added.
        (transformImageIntoGrayscaleMask): added.
        (KCanvasMaskerQuartz::applyMask): added.
        * kcanvas/device/quartz/KCanvasResourcesQuartz.mm:
        (KCanvasContainerQuartz::paint): added mask support.
        * kcanvas/device/quartz/KRenderingDeviceQuartz.mm:
        (KRenderingDeviceQuartz::createResource): added mask support.
        * kcanvas/device/quartz/KRenderingPaintServerGradientQuartz.mm:
        (KRenderingPaintServerRadialGradientQuartz::draw):
        * kcanvas/device/quartz/QuartzSupport.h:
        * kcanvas/device/quartz/QuartzSupport.mm:
        (debugDumpCGImageToFile): added, debug only.
        (debugDumpCGLayerToFile): added, debug only.
        (debugDumpCIImageToFile): added, debug only.
        * ksvg2/css/SVGCSSStyleSelector.cpp:
        (KDOM::CSSStyleSelector::applySVGProperty): added mask support.
        * ksvg2/css/SVGRenderStyle.cpp:
        (SVGRenderStyle::SVGRenderStyle): added mask support.
        (SVGRenderStyle::operator==): added mask support.
        * ksvg2/css/SVGRenderStyle.h:
        * ksvg2/css/SVGRenderStyleDefs.cpp:
        (StyleMaskData::StyleMaskData): added mask support.
        (StyleMaskData::operator==): added mask support.
        * ksvg2/css/SVGRenderStyleDefs.h:
        (KSVG::StyleMaskData::operator!=): added mask support.
        * ksvg2/ecma/Ecma.cpp:
        (Ecma::inheritedGetDOMNode): added mask support.
        * ksvg2/svg/SVGMaskElementImpl.cpp: Added.
        (KSVG::SVGMaskElementImpl::SVGMaskElementImpl): added.
        (KSVG::SVGMaskElementImpl::~SVGMaskElementImpl): added.
        (KSVG::SVGMaskElementImpl::x): added.
        (KSVG::SVGMaskElementImpl::y): added.
        (KSVG::SVGMaskElementImpl::width): added.
        (KSVG::SVGMaskElementImpl::height): added.
        (KSVG::SVGMaskElementImpl::attributeChanged): added.
        (KSVG::SVGMaskElementImpl::childrenChanged): added.
        (KSVG::SVGMaskElementImpl::parseMappedAttribute): added.
        (KSVG::SVGMaskElementImpl::drawMaskerContent): added.
        (KSVG::SVGMaskElementImpl::createRenderer): added.
        (KSVG::SVGMaskElementImpl::canvasResource): added.
        * ksvg2/svg/SVGMaskElementImpl.h: Added.
        (KSVG::SVGMaskElementImpl::isValid): added.
        (KSVG::SVGMaskElementImpl::rendererIsNeeded): added.
        * ksvg2/svg/svgtags.in: added <mask> support.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@11904 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/kcanvas/KCanvasResources.cpp
WebCore/kcanvas/KCanvasResources.h
WebCore/kcanvas/device/quartz/KCanvasItemQuartz.mm
WebCore/kcanvas/device/quartz/KCanvasMaskerQuartz.h [new file with mode: 0644]
WebCore/kcanvas/device/quartz/KCanvasMaskerQuartz.mm [new file with mode: 0644]
WebCore/kcanvas/device/quartz/KCanvasResourcesQuartz.mm
WebCore/kcanvas/device/quartz/KRenderingDeviceQuartz.mm
WebCore/kcanvas/device/quartz/KRenderingPaintServerGradientQuartz.mm
WebCore/kcanvas/device/quartz/QuartzSupport.h
WebCore/kcanvas/device/quartz/QuartzSupport.mm
WebCore/ksvg2/css/SVGCSSStyleSelector.cpp
WebCore/ksvg2/css/SVGRenderStyle.cpp
WebCore/ksvg2/css/SVGRenderStyle.h
WebCore/ksvg2/css/SVGRenderStyleDefs.cpp
WebCore/ksvg2/css/SVGRenderStyleDefs.h
WebCore/ksvg2/ecma/Ecma.cpp
WebCore/ksvg2/svg/SVGMaskElementImpl.cpp [new file with mode: 0644]
WebCore/ksvg2/svg/SVGMaskElementImpl.h [new file with mode: 0644]
WebCore/ksvg2/svg/svgtags.in

index 47e51b26356230736e63cf8707e22825d024f33b..8535ad23f2c2730559357b09ea0f14ec529f85d6 100644 (file)
@@ -1,3 +1,80 @@
+2006-01-06  Alexander Kellett  <lypanov@kde.org>
+
+        Reviewed by eseidel.
+
+        Basic support for <mask> tag.
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=5969
+        Still missing attribute support for: maskUnits, maskContentUnits.
+        
+        Mask pixel tests do not work in DumpRenderTree due to:
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=6327
+        Added test cases anyway.
+
+        This also tickles a (known) gradient update issue:
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=6052
+
+        * WebCore.xcodeproj/project.pbxproj: added Mask files
+        * kcanvas/KCanvasResources.cpp:
+        (KCanvasMasker::KCanvasMasker): added.
+        (KCanvasMasker::~KCanvasMasker): added.
+        (KCanvasMasker::setMask): added.
+        (KCanvasMasker::externalRepresentation): added.
+        (getMaskerById): added.
+        * kcanvas/KCanvasResources.h:
+        (KCanvasResource::isMasker): added.
+        (KCanvasMasker::isMasker): added.
+        (KCanvasMasker::mask): added.
+        * kcanvas/device/quartz/KCanvasItemQuartz.mm:
+        (KCanvasItemQuartz::paint): added mask support
+        * kcanvas/device/quartz/KCanvasMaskerQuartz.h: Added.
+        (KCanvasMaskerQuartz::KCanvasMaskerQuartz): added.
+        * kcanvas/device/quartz/KCanvasMaskerQuartz.mm: Added.
+        (applyLuminanceToAlphaFilter): added.
+        (applyExpandAlphatoGrayscaleFilter): added.
+        (transformImageIntoGrayscaleMask): added.
+        (KCanvasMaskerQuartz::applyMask): added.
+        * kcanvas/device/quartz/KCanvasResourcesQuartz.mm:
+        (KCanvasContainerQuartz::paint): added mask support.
+        * kcanvas/device/quartz/KRenderingDeviceQuartz.mm:
+        (KRenderingDeviceQuartz::createResource): added mask support.
+        * kcanvas/device/quartz/KRenderingPaintServerGradientQuartz.mm:
+        (KRenderingPaintServerRadialGradientQuartz::draw):
+        * kcanvas/device/quartz/QuartzSupport.h:
+        * kcanvas/device/quartz/QuartzSupport.mm:
+        (debugDumpCGImageToFile): added, debug only.
+        (debugDumpCGLayerToFile): added, debug only.
+        (debugDumpCIImageToFile): added, debug only.
+        * ksvg2/css/SVGCSSStyleSelector.cpp:
+        (KDOM::CSSStyleSelector::applySVGProperty): added mask support.
+        * ksvg2/css/SVGRenderStyle.cpp:
+        (SVGRenderStyle::SVGRenderStyle): added mask support.
+        (SVGRenderStyle::operator==): added mask support.
+        * ksvg2/css/SVGRenderStyle.h:
+        * ksvg2/css/SVGRenderStyleDefs.cpp:
+        (StyleMaskData::StyleMaskData): added mask support.
+        (StyleMaskData::operator==): added mask support.
+        * ksvg2/css/SVGRenderStyleDefs.h:
+        (KSVG::StyleMaskData::operator!=): added mask support.
+        * ksvg2/ecma/Ecma.cpp:
+        (Ecma::inheritedGetDOMNode): added mask support.
+        * ksvg2/svg/SVGMaskElementImpl.cpp: Added.
+        (KSVG::SVGMaskElementImpl::SVGMaskElementImpl): added.
+        (KSVG::SVGMaskElementImpl::~SVGMaskElementImpl): added.
+        (KSVG::SVGMaskElementImpl::x): added.
+        (KSVG::SVGMaskElementImpl::y): added.
+        (KSVG::SVGMaskElementImpl::width): added.
+        (KSVG::SVGMaskElementImpl::height): added.
+        (KSVG::SVGMaskElementImpl::attributeChanged): added.
+        (KSVG::SVGMaskElementImpl::childrenChanged): added.
+        (KSVG::SVGMaskElementImpl::parseMappedAttribute): added.
+        (KSVG::SVGMaskElementImpl::drawMaskerContent): added.
+        (KSVG::SVGMaskElementImpl::createRenderer): added.
+        (KSVG::SVGMaskElementImpl::canvasResource): added.
+        * ksvg2/svg/SVGMaskElementImpl.h: Added.
+        (KSVG::SVGMaskElementImpl::isValid): added.
+        (KSVG::SVGMaskElementImpl::rendererIsNeeded): added.
+        * ksvg2/svg/svgtags.in: added <mask> support.
+
 2006-01-04  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Darin.
index ec305cb5240cf84db1b81774d6b992cd705f89c9..51fc8eb7919565f169a38dbb6d49b77061a4fc4e 100644 (file)
@@ -15,7 +15,6 @@
                4756536809652C5D00BD9F29 /* KWQRectF.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4756536209652C5D00BD9F29 /* KWQRectF.mm */; };
                4756536909652C5D00BD9F29 /* KWQSizeF.h in Headers */ = {isa = PBXBuildFile; fileRef = 4756536309652C5D00BD9F29 /* KWQSizeF.h */; };
                4756536A09652C5D00BD9F29 /* KWQSizeF.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4756536409652C5D00BD9F29 /* KWQSizeF.mm */; };
-               475658CB096A728100BD9F29 /* KCanvasHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 475658CA096A728100BD9F29 /* KCanvasHelper.h */; };
                550A0BC9085F6039007353D6 /* dom_qname.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* dom_qname.cpp */; };
                550A0BCA085F6039007353D6 /* dom_qname.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* dom_qname.h */; };
                550A0BCD085F604D007353D6 /* htmlnames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BCB085F604D007353D6 /* htmlnames.cpp */; };
                93F19B1608245E59001E9ABC /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8216299029F4FB501000131 /* JavaScriptCore.framework */; };
                93F19B1708245E59001E9ABC /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 93F1D31A0558CC5C00821BC0 /* libicucore.dylib */; };
                93F19B1808245E59001E9ABC /* libxslt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 840633070731A77200DB1FD1 /* libxslt.dylib */; };
+               A81655D4096BBEAC00601058 /* KCanvasMaskerQuartz.h in Headers */ = {isa = PBXBuildFile; fileRef = A81655D2096BBEAC00601058 /* KCanvasMaskerQuartz.h */; };
+               A81655D5096BBEAC00601058 /* KCanvasMaskerQuartz.mm in Sources */ = {isa = PBXBuildFile; fileRef = A81655D3096BBEAC00601058 /* KCanvasMaskerQuartz.mm */; };
+               A81655E4096BC13900601058 /* SVGMaskElementImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81655E2096BC13900601058 /* SVGMaskElementImpl.cpp */; };
+               A81655E5096BC13900601058 /* SVGMaskElementImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A81655E3096BC13900601058 /* SVGMaskElementImpl.h */; };
                A83C81A3091189B9009BF4A7 /* XSLTProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = A83C819F091189B9009BF4A7 /* XSLTProcessor.h */; };
                A83C81A4091189B9009BF4A7 /* XSLTProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A83C81A0091189B9009BF4A7 /* XSLTProcessor.cpp */; };
                A88AD1190952480A001DD196 /* css_base.h in Headers */ = {isa = PBXBuildFile; fileRef = BC8F618B040594BA00A80004 /* css_base.h */; };
                4756536209652C5D00BD9F29 /* KWQRectF.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = KWQRectF.mm; sourceTree = "<group>"; };
                4756536309652C5D00BD9F29 /* KWQSizeF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = KWQSizeF.h; sourceTree = "<group>"; };
                4756536409652C5D00BD9F29 /* KWQSizeF.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = KWQSizeF.mm; sourceTree = "<group>"; };
-               475658CA096A728100BD9F29 /* KCanvasHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KCanvasHelper.h; sourceTree = "<group>"; };
                4758C44308C5F217009BAF05 /* KCanvasPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KCanvasPath.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                51111AC007BD812C00B7162C /* DOMUtility.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMUtility.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                5150C2A10702629000AF642C /* WebDashboardRegion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebDashboardRegion.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                A8122CF208D564B100844FA3 /* SVGViewElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = SVGViewElement.idl; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                A8122CF308D564B100844FA3 /* SVGZoomAndPan.idl */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = SVGZoomAndPan.idl; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                A8122CF408D564B100844FA3 /* SVGZoomEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = SVGZoomEvent.idl; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+               A81655D2096BBEAC00601058 /* KCanvasMaskerQuartz.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = KCanvasMaskerQuartz.h; sourceTree = "<group>"; };
+               A81655D3096BBEAC00601058 /* KCanvasMaskerQuartz.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = KCanvasMaskerQuartz.mm; sourceTree = "<group>"; };
+               A81655E2096BC13900601058 /* SVGMaskElementImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGMaskElementImpl.cpp; sourceTree = "<group>"; };
+               A81655E3096BC13900601058 /* SVGMaskElementImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGMaskElementImpl.h; sourceTree = "<group>"; };
                A82336B1094C23BE0085A296 /* DataRef.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = DataRef.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                A82FC33B08CBB07C00EFEE23 /* SVGCursorElementImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = SVGCursorElementImpl.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                A82FC33C08CBB07C00EFEE23 /* SVGCursorElementImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGCursorElementImpl.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                                A8C0F881089701F300BA5114 /* SVGLocatableImpl.h */,
                                A8C0F882089701F300BA5114 /* SVGMarkerElementImpl.cpp */,
                                A8C0F883089701F300BA5114 /* SVGMarkerElementImpl.h */,
+                               A81655E2096BC13900601058 /* SVGMaskElementImpl.cpp */,
+                               A81655E3096BC13900601058 /* SVGMaskElementImpl.h */,
                                A8C0F884089701F300BA5114 /* SVGMatrixImpl.cpp */,
                                A8C0F885089701F300BA5114 /* SVGMatrixImpl.h */,
                                A8C0F886089701F300BA5114 /* SVGNumberImpl.cpp */,
                                A8C0FB8A089701F800BA5114 /* KCanvasResources.cpp */,
                                A8C0FB8B089701F800BA5114 /* KCanvasResources.h */,
                                A8C0FB8C089701F800BA5114 /* KCanvasTypes.h */,
-                               475658CA096A728100BD9F29 /* KCanvasHelper.h */,
                                A810E39308A4160F00333D98 /* KCanvasTreeDebug.h */,
                                A810E39408A4160F00333D98 /* KCanvasTreeDebug.cpp */,
                        );
                                A8C0FB75089701F800BA5114 /* KRenderingPaintServerQuartz.mm */,
                                A8C0FB76089701F800BA5114 /* QuartzSupport.h */,
                                A8C0FB77089701F800BA5114 /* QuartzSupport.mm */,
+                               A81655D2096BBEAC00601058 /* KCanvasMaskerQuartz.h */,
+                               A81655D3096BBEAC00601058 /* KCanvasMaskerQuartz.mm */,
                                A8ABC99909445EC00013945F /* KCanvasPathQuartz.h */,
                                A8ABC99A09445EC00013945F /* KCanvasPathQuartz.mm */,
                        );
                                4756536509652C5D00BD9F29 /* KWQPointF.h in Headers */,
                                4756536709652C5D00BD9F29 /* KWQRectF.h in Headers */,
                                4756536909652C5D00BD9F29 /* KWQSizeF.h in Headers */,
-                               475658CB096A728100BD9F29 /* KCanvasHelper.h in Headers */,
+                               A81655D4096BBEAC00601058 /* KCanvasMaskerQuartz.h in Headers */,
+                               A81655E5096BC13900601058 /* SVGMaskElementImpl.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                4756536609652C5D00BD9F29 /* KWQPointF.mm in Sources */,
                                4756536809652C5D00BD9F29 /* KWQRectF.mm in Sources */,
                                4756536A09652C5D00BD9F29 /* KWQSizeF.mm in Sources */,
+                               A81655D5096BBEAC00601058 /* KCanvasMaskerQuartz.mm in Sources */,
+                               A81655E4096BC13900601058 /* SVGMaskElementImpl.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 645450b13270535a2fc93a4aea4708b346f70426..f34085d77083708f66d913db0ba73cbf4f0f44b0 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "kcanvas/KCanvas.h"
 #include "kcanvas/RenderPath.h"
+#include "kcanvas/KCanvasImage.h"
 #include "KCanvasMatrix.h"
 #include "KCanvasContainer.h"
 #include "KCanvasResources.h"
@@ -119,6 +120,30 @@ QTextStream& KCanvasClipper::externalRepresentation(QTextStream &ts) const
     return ts;
 }
 
+// KCanvasMasker
+KCanvasMasker::KCanvasMasker() : KCanvasResource(), m_mask(0)
+{
+}
+
+KCanvasMasker::~KCanvasMasker()
+{
+    delete m_mask;
+}
+
+void KCanvasMasker::setMask(KCanvasImage *mask)
+{
+    if (m_mask != mask) {
+        delete m_mask;
+        m_mask = mask;
+    }
+}
+
+QTextStream& KCanvasMasker::externalRepresentation(QTextStream &ts) const
+{
+    ts << "[type=MASKER]";
+    return ts;
+}
+
 // KCanvasMarker
 KCanvasMarker::KCanvasMarker(khtml::RenderObject *marker) : KCanvasResource()
 {
@@ -264,6 +289,14 @@ KCanvasClipper *getClipperById(KDOM::DocumentImpl *document, const KDOM::DOMStri
     return 0;
 }
 
+KCanvasMasker *getMaskerById(KDOM::DocumentImpl *document, const KDOM::DOMString &id)
+{
+    KCanvasResource *resource = getResourceById(document, id);
+    if (resource && resource->isMasker())
+        return static_cast<KCanvasMasker *>(resource);
+    return 0;
+}
+
 KRenderingPaintServer *getPaintServerById(KDOM::DocumentImpl *document, const KDOM::DOMString &id)
 {
     KCanvasResource *resource = getResourceById(document, id);
index 30003c88a7b75a8fd4820f420333caec170d93b1..e706e9fa915cdd7c0ca3e2ed413d2462485b2325 100644 (file)
@@ -39,7 +39,8 @@ typedef enum
     RS_CLIPPER = 0,
     RS_MARKER = 1,
     RS_IMAGE = 2,
-    RS_FILTER = 3
+    RS_FILTER = 3,
+    RS_MASKER = 4
 } KCResourceType;
 
 class KCanvasMatrix;
@@ -63,6 +64,7 @@ public:
     virtual bool isFilter() const { return false; }
     virtual bool isClipper() const { return false; }
     virtual bool isMarker() const { return false; }
+    virtual bool isMasker() const { return false; }
     
     virtual QTextStream& externalRepresentation(QTextStream &) const; 
 private:
@@ -88,6 +90,23 @@ protected:
     KCClipDataList m_clipData;
 };
 
+class KCanvasImage;
+
+class KCanvasMasker : public KCanvasResource
+{
+public:
+    KCanvasMasker();
+    virtual ~KCanvasMasker();
+    
+    virtual bool isMasker() const { return true; }
+    void setMask(KCanvasImage *mask);
+    KCanvasImage *mask() const { return m_mask; }
+
+    QTextStream& externalRepresentation(QTextStream &) const; 
+protected:
+    KCanvasImage *m_mask;
+};
+
 class KCanvasMarker : public KCanvasResource
 {
 public:
@@ -129,6 +148,7 @@ QTextStream &operator<<(QTextStream &ts, const KCanvasResource &r);
 KCanvasResource *getResourceById(KDOM::DocumentImpl *document, const KDOM::DOMString &id);
 KCanvasMarker *getMarkerById(KDOM::DocumentImpl *document, const KDOM::DOMString &id);
 KCanvasClipper *getClipperById(KDOM::DocumentImpl *document, const KDOM::DOMString &id);
+KCanvasMasker *getMaskerById(KDOM::DocumentImpl *document, const KDOM::DOMString &id);
 KRenderingPaintServer *getPaintServerById(KDOM::DocumentImpl *document, const KDOM::DOMString &id);
 
 #endif
index 10be607a3699aa227b1fb6855effb49398fa63cd..69b318410d49fddefe775d92a318f87796371b63 100644 (file)
@@ -39,6 +39,7 @@
 #import "KRenderingDeviceQuartz.h"
 #import "KCanvasFilterQuartz.h"
 #import "KCanvasResourcesQuartz.h"
+#import "KCanvasMaskerQuartz.h"
 #import "QuartzSupport.h"
 
 #import "SVGRenderStyle.h"
@@ -222,6 +223,11 @@ void KCanvasItemQuartz::paint(PaintInfo &paintInfo, int parentX, int parentY)
     if (clipper)
         clipper->applyClip(context, CGRect(relativeBBox(true)));
 
+    QString maskname = style()->svgStyle()->maskElement().mid(1);
+    KCanvasMaskerQuartz *masker = static_cast<KCanvasMaskerQuartz *>(getMaskerById(document(), maskname));
+    if (masker)
+        masker->applyMask(context, CGRect(relativeBBox(true)));
+
     CGContextBeginPath(context);
 
     KCanvasCommonArgs args = commonArgs();
diff --git a/WebCore/kcanvas/device/quartz/KCanvasMaskerQuartz.h b/WebCore/kcanvas/device/quartz/KCanvasMaskerQuartz.h
new file mode 100644 (file)
index 0000000..36fb8c5
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ *               2005, 2006 Alexander Kellett <lypanov@kde.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+
+#import "KCanvasImage.h"
+#import "KCanvasResources.h"
+
+typedef struct CGContext *CGContextRef;
+
+class KCanvasMaskerQuartz : public KCanvasMasker {
+public:
+    KCanvasMaskerQuartz() { }
+    
+    void applyMask(CGContextRef context, CGRect relativeBBox) const;
+};
diff --git a/WebCore/kcanvas/device/quartz/KCanvasMaskerQuartz.mm b/WebCore/kcanvas/device/quartz/KCanvasMaskerQuartz.mm
new file mode 100644 (file)
index 0000000..3048e80
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2005, 2006 Alexander Kellett <lypanov@kde.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+
+#include "config.h"
+#import "KCanvasMaskerQuartz.h"
+
+#import "kcanvas/KCanvas.h"
+#import "SVGRenderStyle.h"
+
+#import "KCanvasResourcesQuartz.h"
+#import "KRenderingDeviceQuartz.h"
+#import "QuartzSupport.h"
+
+#import <QuartzCore/CoreImage.h>
+
+static CIImage *applyLuminanceToAlphaFilter(CIImage *inputImage)
+{
+    CIFilter *luminanceToAlpha = [CIFilter filterWithName:@"CIColorMatrix"];
+    [luminanceToAlpha setDefaults];
+    float alpha[4] = {0.2125f, 0.7154f, 0.0721f, 0.f};
+    float zero[4] = {0.f, 0.f, 0.f, 0.f};
+    [luminanceToAlpha setValue:inputImage forKey:@"inputImage"];  
+    [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputRVector"];
+    [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputGVector"];
+    [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBVector"];
+    [luminanceToAlpha setValue:[CIVector vectorWithValues:alpha count:4] forKey:@"inputAVector"];
+    [luminanceToAlpha setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBiasVector"];
+    return [luminanceToAlpha valueForKey:@"outputImage"];
+}
+
+static CIImage *applyExpandAlphatoGrayscaleFilter(CIImage *inputImage)
+{
+    CIFilter *alphaToGrayscale = [CIFilter filterWithName:@"CIColorMatrix"];
+    float zero[4] = {0.f, 0.f, 0.f, 0.f};
+    [alphaToGrayscale setDefaults];
+    [alphaToGrayscale setValue:inputImage forKey:@"inputImage"];
+    [alphaToGrayscale setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputRVector"];
+    [alphaToGrayscale setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputGVector"];
+    [alphaToGrayscale setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBVector"];
+    [alphaToGrayscale setValue:[CIVector vectorWithX:0.0f Y:0.0f Z:0.0f W:1.0f] forKey:@"inputAVector"];
+    [alphaToGrayscale setValue:[CIVector vectorWithX:1.0f Y:1.0f Z:1.0f W:0.0f] forKey:@"inputBiasVector"];
+    return [alphaToGrayscale valueForKey:@"outputImage"];
+}
+
+static CIImage *transformImageIntoGrayscaleMask(CIImage *inputImage)
+{
+    CIFilter *blackBackground = [CIFilter filterWithName:@"CIConstantColorGenerator"];
+    [blackBackground setValue:[CIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f] forKey:@"inputColor"];
+
+    CIFilter *layerOverBlack = [CIFilter filterWithName:@"CISourceOverCompositing"];
+    [layerOverBlack setValue:[blackBackground valueForKey:@"outputImage"] forKey:@"inputBackgroundImage"];  
+    [layerOverBlack setValue:inputImage forKey:@"inputImage"];  
+
+    CIImage *luminanceAlpha = applyLuminanceToAlphaFilter([layerOverBlack valueForKey:@"outputImage"]);
+    CIImage *luminanceAsGrayscale = applyExpandAlphatoGrayscaleFilter(luminanceAlpha);
+    CIImage *alphaAsGrayscale = applyExpandAlphatoGrayscaleFilter(inputImage);
+
+    CIFilter *multipliedGrayscale = [CIFilter filterWithName:@"CIMultiplyCompositing"];
+    [multipliedGrayscale setValue:luminanceAsGrayscale forKey:@"inputBackgroundImage"];  
+    [multipliedGrayscale setValue:alphaAsGrayscale forKey:@"inputImage"];  
+    return [multipliedGrayscale valueForKey:@"outputImage"];
+}
+
+void KCanvasMaskerQuartz::applyMask(CGContextRef context, CGRect relativeBBox) const
+{
+    if (!m_mask)
+        return;
+    // Create grayscale bitmap context
+    int width = m_mask->size().width();
+    int height = m_mask->size().height();
+    void *imageBuffer = fastMalloc(width * height);
+    CGColorSpaceRef grayColorSpace = CGColorSpaceCreateDeviceGray();
+    CGContextRef grayscaleContext = CGBitmapContextCreate(imageBuffer, width, height, 8, width, grayColorSpace, kCGImageAlphaNone);
+    CGColorSpaceRelease(grayColorSpace);
+    CIContext *ciGrayscaleContext = [CIContext contextWithCGContext:grayscaleContext options:nil];
+
+    KCanvasImageQuartz *maskImage = static_cast<KCanvasImageQuartz *>(m_mask);
+    CIImage *grayscaleMask = transformImageIntoGrayscaleMask([CIImage imageWithCGLayer:maskImage->cgLayer()]);
+    [ciGrayscaleContext drawImage:grayscaleMask atPoint:CGPointZero fromRect:CGRectMake(0, 0, width, height)];
+
+    CGImageRef grayscaleImage = CGBitmapContextCreateImage(grayscaleContext);
+    CGContextClipToMask(context, CGRectMake(0, 0, width, height), grayscaleImage);
+    
+    CGImageRelease(grayscaleImage);
+    CGContextRelease(grayscaleContext);
+    fastFree(imageBuffer);
+}
index b424f9852fbe3a647bfece768dd8109e5d0b84e9..c827f3c6e5f590295e916fb7421f18098060fa0a 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ *               2005 Alexander Kellett <lypanov@kde.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +34,7 @@
 
 #import "KCanvasPathQuartz.h"
 #import "KRenderingDeviceQuartz.h"
+#import "KCanvasMaskerQuartz.h"
 #import "KCanvasFilterQuartz.h"
 #import "QuartzSupport.h"
 
@@ -115,7 +117,12 @@ void KCanvasContainerQuartz::paint(PaintInfo &paintInfo, int parentX, int parent
     KCanvasClipperQuartz *clipper = static_cast<KCanvasClipperQuartz *>(getClipperById(document(), clipname));
     if (clipper)
         clipper->applyClip(context, CGRect(relativeBBox(true)));
-    
+
+    QString maskname = style()->svgStyle()->maskElement().mid(1);
+    KCanvasMaskerQuartz *masker = static_cast<KCanvasMaskerQuartz *>(getMaskerById(document(), maskname));
+    if (masker)
+        masker->applyMask(context, CGRect(relativeBBox(true)));
+
     float opacity = style()->opacity();
     if (opacity < 1.0f)
         paintInfo.p->beginTransparencyLayer(opacity);
@@ -231,7 +238,6 @@ void KCanvasClipperQuartz::applyClip(CGContextRef context, CGRect relativeBBox)
     }
 }
 
-
 KCanvasImageQuartz::~KCanvasImageQuartz()
 {
        CGLayerRelease(m_cgLayer);
index 92ce32809d73f307443e5eae2acd281939998bc8..2d6b2fb9f906d028b74c95d702c65a9925037e1b 100644 (file)
@@ -27,6 +27,7 @@
 #include "config.h"
 #import "KCanvasPathQuartz.h"
 #import "KRenderingDeviceQuartz.h"
+#import "KCanvasMaskerQuartz.h"
 #import "KCanvasResourcesQuartz.h"
 #import "KCanvasFilterQuartz.h"
 #import "KRenderingPaintServerQuartz.h"
@@ -216,6 +217,8 @@ KCanvasResource *KRenderingDeviceQuartz::createResource(const KCResourceType &ty
         return new KCanvasImageQuartz();
     case RS_FILTER:
         return new KCanvasFilterQuartz();
+    case RS_MASKER:
+        return new KCanvasMaskerQuartz();
     }
     ERROR("Failed to create resource of type: %i", type);
     return 0;
index dcdb38dfbcae915e530517ab3a5048409edebe74..9f58f6c9a69a0b3ea1ef5192d00077435c2f8916 100644 (file)
@@ -312,4 +312,4 @@ void KRenderingPaintServerRadialGradientQuartz::draw(KRenderingDeviceContext *re
         const_cast<KRenderingPaintServerRadialGradientQuartz *>(this)->updateQuartzGradientCache(this);
     
     drawShadingWithStyle(this, m_shadingCache, args.canvasStyle(), type);
-}
\ No newline at end of file
+}
index 1f96162aa8ec7f955f8d690bd7248d04f83edc8c..2517cc49e2ac684f402f9dd6e86df4c527f20fa4 100644 (file)
@@ -31,6 +31,12 @@ namespace KSVG {
     class SVGRenderStyle;
 }
 
+#ifndef NDEBUG
+void debugDumpCGImageToFile(NSString *filename, CGImageRef image, int width, int height);
+void debugDumpCGImageToFile(NSString *filename, CGImageRef image, int width, int height);
+void debugDumpCIImageToFile(NSString *filename, CIImage *ciImage, int width, int height);
+#endif
+
 CFStringRef CFStringFromCGPath(CGPathRef path);
 CFStringRef CFStringFromCGAffineTransform(CGAffineTransform t);
 CGAffineTransform CGAffineTransformMakeMapBetweenRects(CGRect source, CGRect dest);
index d8d1665533dad01671cc49f7596b474837fe95c7..82142d691f8cb72924d5315ea17429984253ffcb 100644 (file)
 #import "KRenderingStrokePainter.h"
 #import "kxmlcore/Assertions.h"
 
+#import <QuartzCore/CoreImage.h>
+
 #import "SVGRenderStyle.h"
 
+#ifndef NDEBUG
+void debugDumpCGImageToFile(NSString *filename, CGImageRef image, int width, int height)
+{
+    NSImage *fileImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
+    [fileImage lockFocus];
+    CGContextRef fileImageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+    CGContextDrawImage(fileImageContext, CGRectMake(0, 0, width, height), image); 
+    [fileImage unlockFocus];
+    NSData *tiff = [fileImage TIFFRepresentation];
+    [tiff writeToFile:filename atomically:YES];
+    [fileImage release];
+}
+
+void debugDumpCGLayerToFile(NSString *filename, CGLayerRef layer, int width, int height)
+{
+    NSImage *fileImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
+    [fileImage lockFocus];
+    CGContextRef fileImageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+    CGContextDrawLayerAtPoint(fileImageContext, CGPointMake(0, 0), layer); 
+    [fileImage unlockFocus];
+    NSData *tiff = [fileImage TIFFRepresentation];
+    [tiff writeToFile:filename atomically:YES];
+    [fileImage release];
+}
+
+void debugDumpCIImageToFile(NSString *filename, CIImage *ciImage, int width, int height)
+{
+    NSImage *fileImage = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
+    [fileImage lockFocus];
+    CGContextRef fileImageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+    CIContext *ciContext = [CIContext contextWithCGContext:fileImageContext options:nil];
+    [ciContext drawImage:ciImage atPoint:CGPointZero fromRect:CGRectMake(0, 0, width, height)];
+    [fileImage unlockFocus];
+    NSData *tiff = [fileImage TIFFRepresentation];
+    [tiff writeToFile:filename atomically:YES];
+    [fileImage release];
+}
+#endif
 
 CFStringRef CFStringFromCGAffineTransform(CGAffineTransform t)
 {
index 9feb7bfccebebf3416d770a5cb6fdc80cb9295d5..f3595068fe83f4949add251d94a913e37815bf03 100644 (file)
@@ -581,6 +581,22 @@ void KDOM::CSSStyleSelector::applySVGProperty(int id, KDOM::CSSValueImpl *value)
             svgstyle->setFilter(s);
             break;
         }
+        case SVGCSS_PROP_MASK:
+        {
+            HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement)
+            if (!primitiveValue)
+                return;
+
+            QString s;
+            int type = primitiveValue->primitiveType();
+            if (type == KDOM::CSSPrimitiveValue::CSS_URI)
+                s = primitiveValue->getStringValue().qstring();
+            else
+                return;
+
+            svgstyle->setMaskElement(s);
+            break;
+        }
         case SVGCSS_PROP_CLIP_PATH:
         {
             HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath)
index def7b1f6eea461998b1f8e69b595cbe426093fd3..ebc166fdbd56e08267a1e2c8efbe03a1107aae60 100644 (file)
@@ -42,6 +42,7 @@ SVGRenderStyle::SVGRenderStyle()
     stroke = s_defaultStyle->stroke;
     stops = s_defaultStyle->stops;
     clip = s_defaultStyle->clip;
+    mask = s_defaultStyle->mask;
     misc = s_defaultStyle->misc;
     markers = s_defaultStyle->markers;
 
@@ -56,6 +57,7 @@ SVGRenderStyle::SVGRenderStyle(bool)
     stroke.init();
     stops.init();
     clip.init();
+    mask.init();
     misc.init();
     markers.init();
 }
@@ -66,6 +68,7 @@ SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle &other) : khtml::Shared<SVGR
     stroke = other.stroke;
     stops = other.stops;
     clip = other.clip;
+    mask = other.mask;
     misc = other.misc;
     markers = other.markers;
 
@@ -80,7 +83,7 @@ SVGRenderStyle::~SVGRenderStyle()
 bool SVGRenderStyle::operator==(const SVGRenderStyle& o) const
 {
     return (fill == o.fill && stroke == o.stroke &&
-        stops == o.stops && clip == o.clip &&
+        stops == o.stops && clip == o.clip && mask == o.mask &&
         misc == o.misc && markers == o.markers &&
         svg_inherited_flags == o.svg_inherited_flags &&
         svg_noninherited_flags == o.svg_noninherited_flags);
index 786848eb187784a405caf39262df792fea94889f..413d381cbd11335133b1a72427afbd6011bc14db 100644 (file)
@@ -109,6 +109,7 @@ namespace KSVG
         RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(QColor, stops, color, StopColor, stopColor, QColor(Qt::black))    
         
         RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(QString, clip, clipPath, ClipPath, clipPath, QString())
+        RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(QString, mask, maskElement, MaskElement, maskElement, QString())
         RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(QString, markers, startMarker, StartMarker, startMarker, QString())
         RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(QString, markers, midMarker, MidMarker, midMarker, QString())
         RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(QString, markers, endMarker, EndMarker, endMarker, QString())
@@ -179,6 +180,7 @@ namespace KSVG
 
         // non-inherited attributes
         KDOM::DataRef<StyleClipData> clip;
+        KDOM::DataRef<StyleMaskData> mask;
 
         // static default style
         static SVGRenderStyle *s_defaultStyle;
index 974dbf69da1184487b4e09f2a93e68a0d3eec5c5..da36110a39459b7a17ada9ce643e714b0882606a 100644 (file)
@@ -129,6 +129,21 @@ bool StyleClipData::operator==(const StyleClipData &other) const
     return (clipPath == other.clipPath);
 }
 
+StyleMaskData::StyleMaskData() : KDOM::Shared<StyleMaskData>()
+{
+    maskElement = SVGRenderStyle::initialMaskElement();
+}
+
+StyleMaskData::StyleMaskData(const StyleMaskData &other) : KDOM::Shared<StyleMaskData>()
+{
+    maskElement = other.maskElement;
+}
+
+bool StyleMaskData::operator==(const StyleMaskData &other) const
+{
+    return (maskElement == other.maskElement);
+}
+
 StyleMarkerData::StyleMarkerData() : KDOM::Shared<StyleMarkerData>()
 {
     startMarker = SVGRenderStyle::initialStartMarker();
index 11eca51454bee32168c4d0951a50e28d515e2f7d..0eafe779dcd480619bb5f27e86e71c26fbef17dd 100644 (file)
@@ -189,6 +189,21 @@ namespace KSVG
         StyleClipData &operator=(const StyleClipData &);
     };
 
+    class StyleMaskData : public KDOM::Shared<StyleMaskData>
+    {
+    public:
+        StyleMaskData();
+        StyleMaskData(const StyleMaskData &other);
+
+        bool operator==(const StyleMaskData &other) const;
+        bool operator!=(const StyleMaskData &other) const { return !(*this == other); }
+
+        QString maskElement;
+
+    private:
+        StyleMaskData &operator=(const StyleMaskData &);
+    };
+
     class StyleMarkerData : public KDOM::Shared<StyleMarkerData>
     {
     public:
index 7d44dcced00759bde5ddfc2e8e9cb355d6831ddc..9c1b5bb0ec631d515d6b2ae4969be15386f33706 100644 (file)
@@ -78,6 +78,7 @@
 #include "SVGAnimateElement.h"
 #include "SVGPolygonElement.h"
 #include "SVGPatternElement.h"
+#include "SVGMaskElement.h"
 #include "SVGPolylineElement.h"
 #include "SVGClipPathElement.h"
 #include "SVGPathSegClosePath.h"
@@ -262,6 +263,11 @@ KJS::JSObject *Ecma::inheritedGetDOMNode(KJS::ExecState *exec, KDOM::Node n)
             ret = SVGPatternElement(n).bridge(exec);
             break;
         }
+        case ID_MASK:
+        {
+            ret = SVGMaskElement(n).bridge(exec);
+            break;
+        }
         case ID_ANIMATECOLOR:
         {
             ret = SVGAnimateColorElement(n).bridge(exec);
diff --git a/WebCore/ksvg2/svg/SVGMaskElementImpl.cpp b/WebCore/ksvg2/svg/SVGMaskElementImpl.cpp
new file mode 100644 (file)
index 0000000..9c0bd26
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+    Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
+                  2004, 2005 Rob Buis <buis@kde.org>
+                  2005 Alexander Kellett <lypanov@kde.org>
+
+    This file is part of the KDE project
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.
+*/
+
+#include "config.h"
+#include <kdom/core/AttrImpl.h>
+
+#include <kcanvas/KCanvas.h>
+#include <kcanvas/KCanvasPath.h>
+#include <kcanvas/KCanvasImage.h>
+#include <kcanvas/KCanvasContainer.h>
+#include <kcanvas/device/KRenderingDevice.h>
+#include <kdom/css/CSSStyleSelector.h>
+
+#include "ksvg.h"
+#include "SVGNames.h"
+#include "SVGHelper.h"
+#include "SVGRenderStyle.h"
+#include "SVGMaskElementImpl.h"
+#include "SVGAnimatedLengthImpl.h"
+
+
+namespace KSVG {
+
+SVGMaskElementImpl::SVGMaskElementImpl(const KDOM::QualifiedName& tagName, KDOM::DocumentImpl *doc) : SVGStyledLocatableElementImpl(tagName, doc), SVGURIReferenceImpl(), SVGTestsImpl(), SVGLangSpaceImpl(), SVGExternalResourcesRequiredImpl(), m_masker(0), m_dirty(true)
+{
+}
+
+SVGMaskElementImpl::~SVGMaskElementImpl()
+{
+    delete m_masker;
+}
+
+SVGAnimatedLengthImpl *SVGMaskElementImpl::x() const
+{
+    return lazy_create<SVGAnimatedLengthImpl>(m_x, this, LM_WIDTH, viewportElement());
+}
+
+SVGAnimatedLengthImpl *SVGMaskElementImpl::y() const
+{
+    return lazy_create<SVGAnimatedLengthImpl>(m_y, this, LM_HEIGHT, viewportElement());
+}
+
+SVGAnimatedLengthImpl *SVGMaskElementImpl::width() const
+{
+    return lazy_create<SVGAnimatedLengthImpl>(m_width, this, LM_WIDTH, viewportElement());
+}
+
+SVGAnimatedLengthImpl *SVGMaskElementImpl::height() const
+{
+    return lazy_create<SVGAnimatedLengthImpl>(m_height, this, LM_HEIGHT, viewportElement());
+}
+
+void SVGMaskElementImpl::attributeChanged(KDOM::AttributeImpl* attr, bool preserveDecls)
+{
+    QSize newSize = QSize(lroundf(width()->baseVal()->value()), lroundf(height()->baseVal()->value()));
+    if (!m_masker || !m_masker->mask() || (m_masker->mask()->size() != newSize))
+        m_dirty = true;
+    SVGStyledLocatableElementImpl::attributeChanged(attr, preserveDecls);
+}
+
+void SVGMaskElementImpl::childrenChanged()
+{
+    m_dirty = true;
+    SVGStyledLocatableElementImpl::childrenChanged();
+}
+
+void SVGMaskElementImpl::parseMappedAttribute(KDOM::MappedAttributeImpl *attr)
+{
+    KDOM::DOMString value(attr->value());
+    if (attr->name() == SVGNames::xAttr)
+        x()->baseVal()->setValueAsString(value.impl());
+    else if (attr->name() == SVGNames::yAttr)
+        y()->baseVal()->setValueAsString(value.impl());
+    else if (attr->name() == SVGNames::widthAttr)
+        width()->baseVal()->setValueAsString(value.impl());
+    else if (attr->name() == SVGNames::heightAttr)
+        height()->baseVal()->setValueAsString(value.impl());
+    else {
+        if (SVGURIReferenceImpl::parseMappedAttribute(attr))
+            return;
+        if (SVGTestsImpl::parseMappedAttribute(attr))
+            return;
+        if (SVGLangSpaceImpl::parseMappedAttribute(attr))
+            return;
+        if (SVGExternalResourcesRequiredImpl::parseMappedAttribute(attr))
+            return;
+        SVGStyledElementImpl::parseMappedAttribute(attr);
+    }
+}
+
+KCanvasImage *SVGMaskElementImpl::drawMaskerContent()
+{
+    KRenderingDevice *device = QPainter::renderingDevice();
+    if (!device->currentContext()) // FIXME: hack for now until QPixmap::lockFocus exists
+        return 0;
+    if (!attached())
+        return 0;
+    KCanvasImage *maskImage = static_cast<KCanvasImage *>(device->createResource(RS_IMAGE));
+
+    QSize size = QSize(lroundf(width()->baseVal()->value()), lroundf(height()->baseVal()->value()));
+    maskImage->init(size);
+
+    KRenderingDeviceContext *patternContext = device->contextForImage(maskImage);
+    device->pushContext(patternContext);
+
+    KCanvasContainer *maskContainer = static_cast<KCanvasContainer *>(renderer());
+    QPainter p;
+    khtml::RenderObject::PaintInfo info(&p, QRect(), PaintActionForeground, 0);
+    maskContainer->setDrawsContents(true);
+    maskContainer->paint(info, 0, 0);
+    maskContainer->setDrawsContents(false);
+    
+    device->popContext();
+    delete patternContext;
+
+    return maskImage;
+}
+
+khtml::RenderObject *SVGMaskElementImpl::createRenderer(RenderArena *arena, khtml::RenderStyle *style)
+{
+    KCanvasContainer *maskContainer = QPainter::renderingDevice()->createContainer(arena, style, this);
+    maskContainer->setDrawsContents(false);
+    return maskContainer;
+}
+
+KCanvasMasker *SVGMaskElementImpl::canvasResource()
+{
+    if (!m_masker) {
+        m_masker = static_cast<KCanvasMasker *>(QPainter::renderingDevice()->createResource(RS_MASKER));
+        m_dirty = true;
+    }
+    if (m_dirty) {
+        KCanvasImage *newMaskImage = drawMaskerContent();
+        m_masker->setMask(newMaskImage);
+        m_dirty = (newMaskImage != 0);
+    }
+    return m_masker;
+}
+
+}
+
+// vim:ts=4:noet
diff --git a/WebCore/ksvg2/svg/SVGMaskElementImpl.h b/WebCore/ksvg2/svg/SVGMaskElementImpl.h
new file mode 100644 (file)
index 0000000..1dad0c5
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+    Copyright (C) 2005 Alexander Kellett <lypanov@kde.org>
+
+    This file is part of the KDE project
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.
+*/
+
+#ifndef KSVG_SVGMaskElementImpl_H
+#define KSVG_SVGMaskElementImpl_H
+
+#include "SVGTestsImpl.h"
+#include "SVGLangSpaceImpl.h"
+#include "SVGURIReferenceImpl.h"
+#include "SVGStyledLocatableElementImpl.h"
+#include "SVGExternalResourcesRequiredImpl.h"
+
+#include "KCanvasResources.h"
+
+class KCanvasImage;
+
+namespace KSVG
+{
+    class AttributeImpl;
+    class SVGAnimatedLengthImpl;
+    class SVGMaskElementImpl : public SVGStyledLocatableElementImpl,
+                                  public SVGURIReferenceImpl,
+                                  public SVGTestsImpl,
+                                  public SVGLangSpaceImpl,
+                                  public SVGExternalResourcesRequiredImpl
+    {
+    public:
+        SVGMaskElementImpl(const KDOM::QualifiedName& tagName, KDOM::DocumentImpl *doc);
+        virtual ~SVGMaskElementImpl();
+        virtual bool isValid() const { return SVGTestsImpl::isValid(); }
+
+        // 'SVGMaskElement' functions
+        SVGAnimatedLengthImpl *x() const;
+        SVGAnimatedLengthImpl *y() const;
+
+        SVGAnimatedLengthImpl *width() const;
+        SVGAnimatedLengthImpl *height() const;
+
+        virtual void childrenChanged();
+        virtual void attributeChanged(KDOM::AttributeImpl* attr, bool preserveDecls);
+        virtual void parseMappedAttribute(KDOM::MappedAttributeImpl *attr);
+
+        virtual bool rendererIsNeeded(khtml::RenderStyle *) { return true; }
+        virtual khtml::RenderObject *createRenderer(RenderArena *arena, khtml::RenderStyle *style);
+        virtual KCanvasMasker *canvasResource();
+
+    protected:
+        KCanvasImage *drawMaskerContent();
+
+        mutable RefPtr<SVGAnimatedLengthImpl> m_x;
+        mutable RefPtr<SVGAnimatedLengthImpl> m_y;
+        mutable RefPtr<SVGAnimatedLengthImpl> m_width;
+        mutable RefPtr<SVGAnimatedLengthImpl> m_height;
+
+    private:
+        KCanvasMasker *m_masker;
+        bool m_dirty;
+    };
+};
+
+#endif
+
+// vim:ts=4:noet
index 86c29bb907f19b62d071416f6b47275e60ec2750..3fce936749ac6db3809d594cc4931fa80e1ca8f8 100644 (file)
@@ -54,7 +54,7 @@ image
 line
 linearGradient
 marker
-#mask
+mask
 #metadata
 #missing_glyph
 #mpath