+2006-02-15 Oliver Hunt <ojh16@student.canterbury.ac.nz>
+
+ Reviewed by eseidel. Landed by eseidel.
+
+ Implemented feDisplacementMap.
+ http://bugzilla.opendarwin.org/show_bug.cgi?id=5862
+
+ * svg/W3C-SVG-1.1/filters-displace-01-f-expected.checksum:
+ * svg/W3C-SVG-1.1/filters-displace-01-f-expected.png:
+ * svg/W3C-SVG-1.1/filters-displace-01-f-expected.txt:
+ * svg/custom/feDisplacementMap-01.svg: Added.
+ * svg/custom/feDisplacementMap-01-expected.checksum: Added.
+ * svg/custom/feDisplacementMap-01-expected.png: Added.
+ * svg/custom/feDisplacementMap-01-expected.txt: Added.
+ * svg/custom/resources/feDisplacementMap-01-displace.png: Added.
+ * svg/custom/resources/feDisplacementMap-01-source.png: Added.
+
2006-02-15 Eric Seidel <eseidel@apple.com>
Update missing result from last commit.
-8358f9bb800ec982bf0cad2861823a2a
\ No newline at end of file
+fc78a06aa0251b7b03ad6243e2017fb5
\ No newline at end of file
KCanvasResource {id="DispMapChecker" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [subregion="at (0,0) size 480x360"]]]}
KCanvasResource {id="RotateMap" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [subregion="at (0,0) size 480x360"]]]}
KCanvasResource {id="SphereMap" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [subregion="at (0,0) size 480x360"]]]}
-KCanvasResource {id="RotateMapTest" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [result="Map"] [subregion="at (0,0) size 480x360"], [type=IMAGE] [result="Texture"] [subregion="at (0,0) size 480x360"]]]}
-KCanvasResource {id="SphereMapTest" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [result="Map"] [subregion="at (0,0) size 480x360"], [type=IMAGE] [result="Texture"] [subregion="at (0,0) size 480x360"]]]}
+KCanvasResource {id="RotateMapTest" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [result="Map"] [subregion="at (0,0) size 480x360"], [type=IMAGE] [result="Texture"] [subregion="at (0,0) size 480x360"], [type=DISPLACEMENT-MAP] [in="Texture"] [subregion="at (0,0) size 480x360"] [in2=Map] [scale=64.00] [x channel selector=RED] [y channel selector=GREEN]]]}
+KCanvasResource {id="SphereMapTest" [type=FILTER] [bounding box=at (0,0) size 1x1] [effect bounding box mode=0] [effects=[[type=IMAGE] [result="Map"] [subregion="at (0,0) size 480x360"], [type=IMAGE] [result="Texture"] [subregion="at (0,0) size 480x360"], [type=DISPLACEMENT-MAP] [in="Texture"] [subregion="at (0,0) size 480x360"] [in2=Map] [scale=64.00] [x channel selector=RED] [y channel selector=GREEN]]]}
layer at (0,0) size 480x360
RenderCanvas at (0,0) size 480x360
KCanvasContainer {svg} at (0.50,0.50) size 479x359
--- /dev/null
+<svg version="1.1" baseProfile="full" id="svg-root" width="100%" height="100%"\r
+ xmlns="http://www.w3.org/2000/svg" \r
+ xmlns:xlink="http://www.w3.org/1999/xlink" >\r
+ <!-- This testcase provides a simple demonstration of the feDisplacementMap filter.\r
+ The output should be a 100x100 green rectangle, however due to the nature of the\r
+ test it may produce a ~1px red line around the right half of the image. While not\r
+ ideal this is currently expected.\r
+ \r
+ If the square is not at (0,0) then there is some form of colour matching occuring\r
+ outside the domain of the filter. In that case, provided there is still no \r
+ significant red visible the test is a pass. \r
+ -->\r
+ <title id="test-title">Displacement mapping test case</title>\r
+ <g id="test-body-content">\r
+ <defs>\r
+ <filter id="ResultImage">\r
+ <feImage result="Map" xlink:href="resources/feDisplacementMap-01-displace.png" width="100" height="100"/>\r
+ <feImage result="Texture" xlink:href="resources/feDisplacementMap-01-source.png" width="100" height="100"/>\r
+ <feDisplacementMap in="Texture" in2="Map" scale="100" xChannelSelector="R" yChannelSelector="G"/>\r
+ </filter>\r
+ </defs>\r
+ <rect x="0" y="0" width="100" height="100" filter="url(#ResultImage)" />\r
+ <rect fill="none" stroke="blue" x="0" y="0" width="100" height="100"/>\r
+ </g>\r
+</svg>\r
+2006-02-15 Oliver Hunt <ojh16@student.canterbury.ac.nz>
+
+ Reviewed by eseidel. Landed by eseidel.
+
+ Implemented feDisplacementMap.
+ http://bugzilla.opendarwin.org/show_bug.cgi?id=5862
+
+ Test: svg/custom/feDisplacementMap-01.svg
+
+ * WebCore.xcodeproj/project.pbxproj: added files.
+ * kcanvas/KCanvasFilters.cpp:
+ (WebCore::KCanvasFEDisplacementMap::externalRepresentation):
+ * kcanvas/KCanvasFilters.h:
+ (WebCore::KCanvasFEDisplacementMap::KCanvasFEDisplacementMap):
+ (WebCore::KCanvasFEDisplacementMap::xChannelSelector):
+ (WebCore::KCanvasFEDisplacementMap::setXChannelSelector):
+ (WebCore::KCanvasFEDisplacementMap::yChannelSelector):
+ (WebCore::KCanvasFEDisplacementMap::setYChannelSelector):
+ (WebCore::KCanvasFEDisplacementMap::scale):
+ (WebCore::KCanvasFEDisplacementMap::setScale):
+ * kcanvas/device/quartz/KCanvasFilterQuartz.h:
+ * kcanvas/device/quartz/KCanvasFilterQuartz.mm:
+ (WebCore::getVectorForChannel):
+ (WebCore::KCanvasFEDisplacementMapQuartz::getCIFilter):
+ * kcanvas/device/quartz/KRenderingDeviceQuartz.mm:
+ (WebCore::KRenderingDeviceQuartz::createFilterEffect):
+ * kcanvas/device/quartz/filters/WKDisplacementMapFilter.cikernel: Added.
+ * kcanvas/device/quartz/filters/WKDisplacementMapFilter.h: Added.
+ * kcanvas/device/quartz/filters/WKDisplacementMapFilter.m: Added.
+ (+[WKDisplacementMapFilter initialize]):
+ (+[WKDisplacementMapFilter filterWithName:]):
+ (-[WKDisplacementMapFilter init]):
+ (-[WKDisplacementMapFilter outputImage]):
+ * ksvg2/svg/SVGFEDisplacementMapElementImpl.cpp: Added.
+ (SVGFEDisplacementMapElementImpl::SVGFEDisplacementMapElementImpl):
+ (SVGFEDisplacementMapElementImpl::~SVGFEDisplacementMapElementImpl):
+ (SVGFEDisplacementMapElementImpl::in1):
+ (SVGFEDisplacementMapElementImpl::in2):
+ (SVGFEDisplacementMapElementImpl::xChannelSelector):
+ (SVGFEDisplacementMapElementImpl::yChannelSelector):
+ (SVGFEDisplacementMapElementImpl::scale):
+ (SVGFEDisplacementMapElementImpl::stringToChannel):
+ (SVGFEDisplacementMapElementImpl::parseMappedAttribute):
+ (SVGFEDisplacementMapElementImpl::filterEffect):
+ * ksvg2/svg/SVGFEDisplacementMapElementImpl.h: Added.
+ * ksvg2/svg/svgtags.in:
+
2006-02-15 Eric Seidel <eseidel@apple.com>
Reviewed by darin.
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 */; };
+ A7638A8B09958EA50007E14F /* WKDisplacementMapFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = A7638A8909958EA50007E14F /* WKDisplacementMapFilter.h */; };
+ A7638A8C09958EA50007E14F /* WKDisplacementMapFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = A7638A8A09958EA50007E14F /* WKDisplacementMapFilter.m */; };
+ A7638A92099592C30007E14F /* WKDisplacementMapFilter.cikernel in Resources */ = {isa = PBXBuildFile; fileRef = A7638A91099592C30007E14F /* WKDisplacementMapFilter.cikernel */; };
+ A7638A970995965D0007E14F /* SVGFEDisplacementMapElementImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7638A950995965D0007E14F /* SVGFEDisplacementMapElementImpl.h */; };
+ A7638A980995965D0007E14F /* SVGFEDisplacementMapElementImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7638A960995965D0007E14F /* SVGFEDisplacementMapElementImpl.cpp */; };
A81369CA097374F600D74463 /* HTMLIsIndexElementImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369AE097374F500D74463 /* HTMLIsIndexElementImpl.h */; };
A81369CB097374F600D74463 /* HTMLIsIndexElementImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A81369AF097374F500D74463 /* HTMLIsIndexElementImpl.cpp */; };
A81369CC097374F600D74463 /* HTMLInputElementImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = A81369B0097374F500D74463 /* HTMLInputElementImpl.h */; };
93F19B1908245E59001E9ABC /* Info.plist */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
93F19B1A08245E5A001E9ABC /* WebCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WebCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
93F1D31A0558CC5C00821BC0 /* libicucore.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libicucore.dylib; path = /usr/lib/libicucore.dylib; sourceTree = "<absolute>"; };
+ A7638A8909958EA50007E14F /* WKDisplacementMapFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WKDisplacementMapFilter.h; sourceTree = "<group>"; };
+ A7638A8A09958EA50007E14F /* WKDisplacementMapFilter.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WKDisplacementMapFilter.m; sourceTree = "<group>"; };
+ A7638A91099592C30007E14F /* WKDisplacementMapFilter.cikernel */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WKDisplacementMapFilter.cikernel; sourceTree = "<group>"; };
+ A7638A950995965D0007E14F /* SVGFEDisplacementMapElementImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGFEDisplacementMapElementImpl.h; sourceTree = "<group>"; };
+ A7638A960995965D0007E14F /* SVGFEDisplacementMapElementImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFEDisplacementMapElementImpl.cpp; sourceTree = "<group>"; };
A810E39308A4160F00333D98 /* KCanvasTreeDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = KCanvasTreeDebug.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
A810E39408A4160F00333D98 /* KCanvasTreeDebug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KCanvasTreeDebug.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
A8122C7E08D564B000844FA3 /* GetSVGDocument.idl */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = text; path = GetSVGDocument.idl; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
A8C0F842089701F300BA5114 /* SVGEllipseElementImpl.h */,
A8C0F845089701F300BA5114 /* SVGExternalResourcesRequiredImpl.cpp */,
A8C0F846089701F300BA5114 /* SVGExternalResourcesRequiredImpl.h */,
+ A7638A950995965D0007E14F /* SVGFEDisplacementMapElementImpl.h */,
+ A7638A960995965D0007E14F /* SVGFEDisplacementMapElementImpl.cpp */,
A8C0F847089701F300BA5114 /* SVGFEBlendElementImpl.cpp */,
A8C0F848089701F300BA5114 /* SVGFEBlendElementImpl.h */,
A8C0F849089701F300BA5114 /* SVGFEColorMatrixElementImpl.cpp */,
A8C3291F093BB732000B9CAC /* filters */ = {
isa = PBXGroup;
children = (
+ A7638A8909958EA50007E14F /* WKDisplacementMapFilter.h */,
+ A7638A8A09958EA50007E14F /* WKDisplacementMapFilter.m */,
+ A7638A91099592C30007E14F /* WKDisplacementMapFilter.cikernel */,
A8C32920093BB732000B9CAC /* WKArithmeticFilter.cikernel */,
A8C32921093BB732000B9CAC /* WKArithmeticFilter.h */,
A8C32922093BB732000B9CAC /* WKArithmeticFilter.m */,
BC6B7ECF0998AC7F0052867B /* ImageSource.h in Headers */,
6582A14009999CD600BEEB6D /* QString.h in Headers */,
6582A16009999D6D00BEEB6D /* PDFDocumentImage.h in Headers */,
+ A7638A8B09958EA50007E14F /* WKDisplacementMapFilter.h in Headers */,
+ A7638A970995965D0007E14F /* SVGFEDisplacementMapElementImpl.h in Headers */,
93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */,
93309DD9099E64920056E581 /* ApplyStyleCommand.h in Headers */,
93309DDB099E64920056E581 /* BreakBlockquoteCommand.h in Headers */,
BCEA479C097CAAC80094C9E4 /* cssproperties.in in Resources */,
BCEA479F097CAAC80094C9E4 /* cssvalues.in in Resources */,
BCC8CFCD0986CD2400140BF2 /* ColorData.gperf in Resources */,
+ A7638A92099592C30007E14F /* WKDisplacementMapFilter.cikernel in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6582A17809999EA000BEEB6D /* QStringMac.mm in Sources */,
1A2154EE099A11A800343DF8 /* JSDOMCore.cpp in Sources */,
1A2154EF099A11A800343DF8 /* JSDOMEvents.cpp in Sources */,
+ A7638A8C09958EA50007E14F /* WKDisplacementMapFilter.m in Sources */,
+ A7638A980995965D0007E14F /* SVGFEDisplacementMapElementImpl.cpp in Sources */,
93309DD6099E64920056E581 /* AppendNodeCommand.cpp in Sources */,
93309DD8099E64920056E581 /* ApplyStyleCommand.cpp in Sources */,
93309DDA099E64920056E581 /* BreakBlockquoteCommand.cpp in Sources */,
if (!in2().isEmpty())
ts << " [in2=" << in2() << "]";
ts << " [scale=" << m_scale << "]"
- << " [x channel selector=" << m_XChannelSelector << "]"
- << " [y channel selector=" << m_XChannelSelector << "]";
+ << " [x channel selector=" << m_xChannelSelector << "]"
+ << " [y channel selector=" << m_yChannelSelector << "]";
return ts;
}
class KCanvasFEDisplacementMap : public KCanvasFilterEffect
{
public:
+ KCanvasFEDisplacementMap() : m_xChannelSelector(CS_RED), m_yChannelSelector(CS_RED), m_scale(0) {}
+
QString in2() const { return m_in2; }
void setIn2(const QString &in2) { m_in2 = in2; }
+
+ KCChannelSelectorType xChannelSelector() const { return m_xChannelSelector; }
+ void setXChannelSelector(const KCChannelSelectorType xChannelSelector) { m_xChannelSelector = xChannelSelector; }
+
+ KCChannelSelectorType yChannelSelector() const { return m_yChannelSelector; }
+ void setYChannelSelector(const KCChannelSelectorType yChannelSelector) { m_yChannelSelector = yChannelSelector; }
+ float scale() const { return m_scale; }
+ void setScale(float scale) { m_scale = scale; }
+
QTextStream &externalRepresentation(QTextStream &) const;
private:
- float m_scale;
- KCChannelSelectorType m_XChannelSelector;
- KCChannelSelectorType m_YChannelSelector;
QString m_in2;
+ KCChannelSelectorType m_xChannelSelector;
+ KCChannelSelectorType m_yChannelSelector;
+ float m_scale;
};
class KCanvasFEFlood : public KCanvasFilterEffect
virtual CIFilter *getCIFilter(KCanvasFilterQuartz *quartzFilter) const;
};
+class KCanvasFEDisplacementMapQuartz : public KCanvasFEDisplacementMap {
+public:
+ virtual CIFilter *getCIFilter(KCanvasFilterQuartz *quartzFilter) const;
+};
+
class KCanvasFEMergeQuartz : public KCanvasFEMerge {
public:
virtual CIFilter *getCIFilter(KCanvasFilterQuartz *quartzFilter) const;
#import "KRenderingDeviceQuartz.h"
#import "QuartzSupport.h"
#import "KWQExceptions.h"
+#import "WKDisplacementMapFilter.h"
#import "WKDiffuseLightingFilter.h"
#import "WKSpecularLightingFilter.h"
#import "WKSpotLightFilter.h"
FE_QUARTZ_OUTPUT_RETURN;
}
+static inline CIVector *getVectorForChannel(int idx){
+ switch(idx){
+ case 0:
+ return [CIVector vectorWithX:1.0 Y:0.0 Z:0.0 W:0.0];
+ case 1:
+ return [CIVector vectorWithX:0.0 Y:1.0 Z:0.0 W:0.0];
+ case 2:
+ return [CIVector vectorWithX:0.0 Y:0.0 Z:1.0 W:0.0];
+ case 3:
+ return [CIVector vectorWithX:0.0 Y:0.0 Z:0.0 W:1.0];
+ default:
+ return [CIVector vectorWithX:0.0 Y:0.0 Z:0.0 W:0.0];
+ }
+}
+
+CIFilter *KCanvasFEDisplacementMapQuartz::getCIFilter(KCanvasFilterQuartz *quartzFilter) const
+{
+ CIFilter *filter = nil;
+ KWQ_BLOCK_EXCEPTIONS;
+ [WKDisplacementMapFilter class];
+ filter = [CIFilter filterWithName:@"WKDisplacementMapFilter"];
+ [filter setDefaults];
+ CIImage *inputImage = quartzFilter->inputImage(this);
+ CIImage *displacementMap = quartzFilter->imageForName(in2());
+ FE_QUARTZ_CHECK_INPUT(inputImage);
+ FE_QUARTZ_CHECK_INPUT(displacementMap);
+ [filter setValue:inputImage forKey:@"inputImage"];
+ [filter setValue:displacementMap forKey:@"inputDisplacementMap"];
+ [filter setValue:getVectorForChannel(xChannelSelector()) forKey:@"inputXChannelSelector"];
+ [filter setValue:getVectorForChannel(yChannelSelector()) forKey:@"inputYChannelSelector"];
+ [filter setValue:[NSNumber numberWithFloat:scale()] forKey:@"inputScale"];
+ FE_QUARTZ_OUTPUT_RETURN;
+}
+
static inline CIFilter *getPointLightVectors(CIFilter * normals, CIVector * lightPosition, float surfaceScale)
{
CIFilter *filter;
case FE_COMPOSITE: return new KCanvasFECompositeQuartz();
// case FE_CONVOLVE_MATRIX:
case FE_DIFFUSE_LIGHTING: return new KCanvasFEDiffuseLightingQuartz();
-// case FE_DISPLACEMENT_MAP:
+ case FE_DISPLACEMENT_MAP: return new KCanvasFEDisplacementMapQuartz();
case FE_FLOOD: return new KCanvasFEFloodQuartz();
case FE_GAUSSIAN_BLUR: return new KCanvasFEGaussianBlurQuartz();
case FE_IMAGE: return new KCanvasFEImageQuartz();
--- /dev/null
+/*
+ * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>. All rights reserved.
+ *
+ * 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 THE AUTHOR ``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 THE AUTHOR 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.
+ */
+
+/*
+ * Performs the transformation:
+ * P'(x,y) <- P( x + scale * (XC(x,y) - .5), y + scale * (YC(x,y) - .5))
+ *
+ * x/ychannel arguments are used to select the appropriate channel for x and
+ * y displacement. Hence each vector should have only one non-zero element,
+ * which should have the value 1.0.
+ *
+ */
+
+kernel vec4 displacementMap(sampler image, sampler map, vec4 xchannel, vec4 ychannel, float scale)
+{
+ vec2 samplePos = samplerCoord(image);
+ vec4 XCYC = sample(map, samplerCoord(map));
+ float xc = dot(XCYC, xchannel);
+ float yc = dot(XCYC, ychannel);
+ samplePos.x += scale*(xc-0.5);
+ //flip the y-axis
+ samplePos.y -= scale*(yc-0.5);
+ return sample(image, samplePos);
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>. All rights reserved.
+ *
+ * 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 THE AUTHOR ``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 THE AUTHOR 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 <QuartzCore/CoreImage.h>
+
+@interface WKDisplacementMapFilter : CIFilter {
+ CIImage *inputImage;
+ CIImage *inputDisplacementMap;
+ CIVector *inputXChannelSelector;
+ CIVector *inputYChannelSelector;
+ NSNumber *inputScale;
+}
+
+@end
--- /dev/null
+/*
+ * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>. All rights reserved.
+ *
+ * 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 THE AUTHOR ``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 THE AUTHOR 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 "WKDisplacementMapFilter.h"
+
+static CIKernel *displacementMapFilter = nil;
+
+@implementation WKDisplacementMapFilter
+
++ (void)initialize
+{
+ [CIFilter registerFilterName:@"WKDisplacementMapFilter"
+ constructor:self
+ classAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
+ @"WebKit Displacement Map Filter", kCIAttributeFilterDisplayName,
+ [NSArray arrayWithObjects:kCICategoryStylize, kCICategoryVideo,
+ kCICategoryStillImage, kCICategoryNonSquarePixels,nil], kCIAttributeFilterCategories,
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [CIVector vectorWithX:1.0 Y:0.0 Z:0.0 W:0.0],
+ kCIAttributeDefault, nil], @"inputXChannelSelector",
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [CIVector vectorWithX:0.0 Y:1.0 Z:0.0 W:0.0],
+ kCIAttributeDefault, nil], @"inputYChannelSelector",
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithDouble:0.0], kCIAttributeDefault,
+ [NSNumber numberWithDouble:0.0], kCIAttributeIdentity,
+ kCIAttributeTypeScalar, kCIAttributeType,
+ nil], @"inputScale",
+ nil]];
+}
+
++ (CIFilter *)filterWithName:(NSString *)name
+{
+ return [[[self alloc] init] autorelease];
+}
+
+- (id)init
+{
+ if (!displacementMapFilter) {
+ NSBundle *bundle = [NSBundle bundleForClass:[self class]];
+ NSString *kernelFile = [bundle pathForResource:@"WKDisplacementMapFilter" ofType:@"cikernel"];
+ NSString *code = [NSString stringWithContentsOfFile:kernelFile];
+ NSArray *kernels = [CIKernel kernelsWithString:code];
+ displacementMapFilter = [[kernels objectAtIndex:0] retain];
+ }
+ return [super init];
+}
+
+- (CIImage *)outputImage
+{
+ return [self apply:displacementMapFilter, inputImage, inputDisplacementMap, inputXChannelSelector, inputYChannelSelector, inputScale, nil];
+}
+
+@end
--- /dev/null
+/*
+ Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
+
+ 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"
+#if SVG_SUPPORT
+#include <qstringlist.h>
+
+#include <kdom/core/AttrImpl.h>
+
+#include <kcanvas/KCanvas.h>
+#include <kcanvas/KCanvasFilters.h>
+#include <kcanvas/device/KRenderingDevice.h>
+
+#include "ksvg.h"
+#include "SVGHelper.h"
+#include "SVGRenderStyle.h"
+#include "SVGFEDisplacementMapElementImpl.h"
+#include "SVGAnimatedEnumerationImpl.h"
+#include "SVGAnimatedStringImpl.h"
+#include "SVGAnimatedNumberImpl.h"
+#include "SVGDOMImplementationImpl.h"
+
+using namespace KSVG;
+
+SVGFEDisplacementMapElementImpl::SVGFEDisplacementMapElementImpl(const KDOM::QualifiedName& tagName, KDOM::DocumentImpl* doc) :
+SVGFilterPrimitiveStandardAttributesImpl(tagName, doc)
+{
+ m_filterEffect = 0;
+}
+
+SVGFEDisplacementMapElementImpl::~SVGFEDisplacementMapElementImpl()
+{
+ delete m_filterEffect;
+}
+
+SVGAnimatedStringImpl* SVGFEDisplacementMapElementImpl::in1() const
+{
+ SVGStyledElementImpl* dummy = 0;
+ return lazy_create<SVGAnimatedStringImpl>(m_in1, dummy);
+}
+
+SVGAnimatedStringImpl* SVGFEDisplacementMapElementImpl::in2() const
+{
+ SVGStyledElementImpl* dummy = 0;
+ return lazy_create<SVGAnimatedStringImpl>(m_in2, dummy);
+}
+
+SVGAnimatedEnumerationImpl* SVGFEDisplacementMapElementImpl::xChannelSelector() const
+{
+ SVGStyledElementImpl* dummy = 0;
+ return lazy_create<SVGAnimatedEnumerationImpl>(m_xChannelSelector, dummy);
+}
+
+SVGAnimatedEnumerationImpl* SVGFEDisplacementMapElementImpl::yChannelSelector() const
+{
+ SVGStyledElementImpl* dummy = 0;
+ return lazy_create<SVGAnimatedEnumerationImpl>(m_yChannelSelector, dummy);
+}
+
+SVGAnimatedNumberImpl* SVGFEDisplacementMapElementImpl::scale() const
+{
+ SVGStyledElementImpl* dummy = 0;
+ return lazy_create<SVGAnimatedNumberImpl>(m_scale, dummy);
+}
+
+KCChannelSelectorType SVGFEDisplacementMapElementImpl::stringToChannel(KDOM::DOMString& key)
+{
+ if(key == "R")
+ return CS_RED;
+ else if(key == "G")
+ return CS_GREEN;
+ else if(key == "B")
+ return CS_BLUE;
+ else if(key == "A")
+ return CS_ALPHA;
+ //error
+ return (KCChannelSelectorType)-1;
+}
+
+void SVGFEDisplacementMapElementImpl::parseMappedAttribute(KDOM::MappedAttributeImpl* attr)
+{
+ KDOM::DOMString value(attr->value());
+ if (attr->name() == SVGNames::xChannelSelectorAttr)
+ xChannelSelector()->setBaseVal(stringToChannel(value));
+ else if (attr->name() == SVGNames::yChannelSelectorAttr)
+ yChannelSelector()->setBaseVal(stringToChannel(value));
+ else if (attr->name() == SVGNames::inAttr)
+ in1()->setBaseVal(value.impl());
+ else if (attr->name() == SVGNames::in2Attr)
+ in2()->setBaseVal(value.impl());
+ else if (attr->name() == SVGNames::scaleAttr)
+ scale()->setBaseVal(value.qstring().toDouble());
+ else
+ SVGFilterPrimitiveStandardAttributesImpl::parseMappedAttribute(attr);
+}
+
+KCanvasFEDisplacementMap* SVGFEDisplacementMapElementImpl::filterEffect() const
+{
+ if (!m_filterEffect)
+ m_filterEffect = static_cast<KCanvasFEDisplacementMap *>(QPainter::renderingDevice()->createFilterEffect(FE_DISPLACEMENT_MAP));
+ if (!m_filterEffect)
+ return 0;
+ m_filterEffect->setXChannelSelector((KCChannelSelectorType)(xChannelSelector()->baseVal()));
+ m_filterEffect->setYChannelSelector((KCChannelSelectorType)(yChannelSelector()->baseVal()));
+ m_filterEffect->setIn(KDOM::DOMString(in1()->baseVal()).qstring());
+ m_filterEffect->setIn2(KDOM::DOMString(in2()->baseVal()).qstring());
+ m_filterEffect->setScale(scale()->baseVal());
+ setStandardAttributes(m_filterEffect);
+ return m_filterEffect;
+}
+#endif // SVG_SUPPORT
--- /dev/null
+/*
+ Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
+
+ 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_SVGFEDisplacementMapElementImpl_H
+#define KSVG_SVGFEDisplacementMapElementImpl_H
+#if SVG_SUPPORT
+
+#include "SVGFilterPrimitiveStandardAttributesImpl.h"
+#include "KCanvasFilters.h"
+
+namespace KSVG
+{
+ class SVGAnimatedNumberImpl;
+ class SVGAnimatedStringImpl;
+ class SVGAnimatedEnumerationImpl;
+
+ class SVGFEDisplacementMapElementImpl : public SVGFilterPrimitiveStandardAttributesImpl
+ {
+public:
+ SVGFEDisplacementMapElementImpl(const KDOM::QualifiedName& tagName, KDOM::DocumentImpl *doc);
+ virtual ~SVGFEDisplacementMapElementImpl();
+
+ // 'SVGFEDisplacementMapElement' functions
+ SVGAnimatedStringImpl* in1() const;
+ SVGAnimatedStringImpl* in2() const;
+ SVGAnimatedEnumerationImpl* xChannelSelector() const;
+ SVGAnimatedEnumerationImpl* yChannelSelector() const;
+ SVGAnimatedNumberImpl* scale() const;
+
+ static KCChannelSelectorType stringToChannel(KDOM::DOMString &key);
+
+ // Derived from: 'ElementImpl'
+ virtual void parseMappedAttribute(KDOM::MappedAttributeImpl *attr);
+
+ virtual KCanvasFEDisplacementMap* filterEffect() const;
+
+private:
+ mutable RefPtr<SVGAnimatedStringImpl> m_in1;
+ mutable RefPtr<SVGAnimatedStringImpl> m_in2;
+ mutable RefPtr<SVGAnimatedEnumerationImpl> m_xChannelSelector;
+ mutable RefPtr<SVGAnimatedEnumerationImpl> m_yChannelSelector;
+ mutable RefPtr<SVGAnimatedNumberImpl> m_scale;
+ mutable KCanvasFEDisplacementMap *m_filterEffect;
+ };
+};
+
+#endif // SVG_SUPPORT
+#endif // KSVG_SVGFEDisplacementMapElementImpl_H
+
feComposite
#feConvolveMatrix
feDiffuseLighting
-#feDisplacementMap
+feDisplacementMap
feDistantLight
feFlood
feFuncA