Wed, 18 Apr 2012 17:47:14 -0700
Added section on security concern + called out link to canvas blending wiki
1 <!DOCTYPE html public '-//W3C//DTD HTML 4.01//EN'
2 'http://www.w3.org/TR/html4/strict.dtd'>
3 <html lang="en">
4 <head profile="http://www.w3.org/2006/03/hcard">
5 <title>Filter Effects 1.0</title>
6 <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
7 <link rel="stylesheet" type="text/css" href="style/default.css">
8 <link rel="stylesheet" type="text/css" href="http://www.w3.org/StyleSheets/TR/W3C-ED.css">
9 <link id="st" href="style/alternate-spec-style.css" rel="stylesheet" type="text/css" title="additional spec styles">
10 <script type="text/javascript" src="style/style-toggle.js"></script>
11 <style type="text/css">
13 /* Alternate stylesheet fonts are here because in some browsers (Opera 11.5) */
14 /* The fonts are not applied if only loaded from the alternate stylesheet */
15 @import url(http://fonts.googleapis.com/css?family=Droid+Serif:700,400,400italic,700italic);
16 @import url(http://fonts.googleapis.com/css?family=Droid+Sans+Mono);
18 a.toggle {
19 position: fixed;
20 top: 0.5em;
21 right: 0.5em;
22 font-size: smaller;
23 color: gray;
24 opacity: 0.2;
25 }
27 a.toggle:hover {
28 opacity: 1;
29 color: #46A4E9;
30 }
32 div.issue-marker {
33 position: absolute;
34 width: 20ex;
35 margin-left: -26ex;
36 padding-left: 1em;
37 padding: 5px;
38 font-weight: normal;
39 font-size: 11px;
40 text-align: right;
41 background-color: white;
42 font-size: 90%;
43 }
45 div.issue-marker a {
46 color: red;
47 }
49 .todo {
50 font-weight: bold;
51 border-left: 0.5em solid #f44;
52 padding-left: 1em;
53 margin-top: 0.5em;
54 color: #a0a0a0;
55 }
57 .todo:before {
58 content: "TO DO : ";
59 color: #f44;
60 }
61 </style>
62 </head>
64 <div id="div-head" class="head">
65 <!--logo-->
67 <h1>Filter Effects 1.0</h1>
69 <h2 class="no-num no-toc">16 December 2011</h2>
70 <dl>
71 <dt>Editors:</dt>
72 <dd class="vcard">
73 <span class="fn">Vincent Hardy</span>,
74 <span class="org">Adobe Systems</span>,
75 <span class="email">vhardy@adobe.com</span>
76 </dd>
77 <dd class="vcard">
78 <span class="fn">Dean Jackson</span>,
79 <span class="org">Apple Inc.</span>,
80 <span class="email">dino@apple.com</span>
81 </dd>
82 <dd class="vcard">
83 <span class="fn">Erik Dahlström</span>,
84 <span class="org">Opera Software ASA</span>,
85 <span class="email">ed@opera.com</span>
86 </dd>
87 <dt>Authors:</dt>
88 <dd>
89 The authors of this specification are the participants
90 of the W3C CSS and SVG Working Groups.
91 </dd>
92 </dl>
94 <!--copyright-->
96 <hr title="Separator for header">
97 </div>
99 <h2 class="no-num no-toc" id="abstract">Abstract</h2>
101 <p>
102 Filter effects are a way of processing an element's rendering before it is
103 displayed in the document. Typically, rendering an element via CSS or SVG
104 can conceptually described as if the element, including its children, are
105 drawn into a buffer (such as a raster image) and then that buffer is
106 composited into the elements parent. Filters apply an effect before the
107 compositing stage. Examples of such effects are blurring, changing color
108 intensity and warping the image.
109 </p>
111 <p>
112 Although originally designed for use in SVG, filter effects are a set a set of
113 operations to apply on an image buffer and therefore can be applied to nearly
114 any presentational environment, including CSS. They are triggered by a style
115 instruction (the 'filter' property). This specification describes filters in a
116 manner that allows them to be used in content styled by CSS, such as HTML and
117 SVG. It also defines a CSS property value function that produces a CSS
118 <image> value.
119 </p>
121 <h2 class="no-num no-toc" id="status">Status of This Document</h2>
123 <p>
124 <em>This section describes the status of this document at the time of its
125 publication. Other documents may supersede this document. A list of current W3C
126 publications and the latest revision of this technical report can be found in
127 the <a href="http://www.w3.org/TR/">W3C technical reports index</a> at
128 http://www.w3.org/TR/.</em>
129 </p>
131 <p>
132 This document is the first public working draft of this specification.
133 </p>
135 <p>
136 Publication as a Working Draft does not imply endorsement by the W3C
137 Membership. This is a draft document and may be updated, replaced or obsoleted
138 by other documents at any time. It is inappropriate to cite this document as
139 other than work in progress.
140 </p>
142 <p>
143 The (<a href="http://lists.w3.org/Archives/Public/public-fx/">archived</a>)
144 public mailing list <a href="mailto:public-fx@w3.org">public-fx@w3.org</a> (see
145 <a href="http://www.w3.org/Mail/Request">instructions</a>) is preferred for
146 discussion of this specification. When sending e-mail, please put the text
147 “Filter Effects” in the subject, preferably like this: “[Filter
148 Effects] <em>…summary of comment…</em>”
149 </p>
151 <p>
152 This document was produced by the <a
153 href="http://www.w3.org/Style/CSS/members">CSS Working Group</a> (part of the
154 <a href="http://www.w3.org/Style/">Style Activity</a>) and the <a
155 href="http://www.w3.org/Graphics/SVG/">SVG Working Group</a> (part of the <a
156 href="http://www.w3.org/Graphics/">Graphics Activity</a>)
157 </p>
159 <p>
160 This document was produced by groups operating under the <a
161 href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 W3C
162 Patent Policy</a>. W3C maintains a <a
163 href="http://www.w3.org/2004/01/pp-impl/32061/status">public list of any patent
164 disclosures (CSS)</a> and a <a
165 href="http://www.w3.org/2004/01/pp-impl/19480/status">public list of any patent
166 disclosures (SVG)</a> made in connection with the deliverables of each group;
167 these pages also include instructions for disclosing a patent. An individual
168 who has actual knowledge of a patent which the individual believes contains <a
169 href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential
170 Claim(s)</a> must disclose the information in accordance with <a
171 href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section
172 6 of the W3C Patent Policy</a>.
173 </p>
175 <p>
176 The <a href="ChangeLog">list of changes made to this specification</a> is
177 available.
178 </p>
180 <h2 class="no-num no-toc" id="contents">Table of contents</h2>
182 <!--toc-->
184 <h2 id="introduction">Introduction</h2>
186 <p>
187 A filter effect is a graphical operation that is applied to an element as it is
188 drawn into the document. It is an image-based effect, in that it takes zero or
189 more images as input, a number of parameters specific to the effect, and then
190 produces an image as output. The output image is either rendered into the
191 document instead of the original element, used as an input image to another
192 filter effect, or provided as a CSS image value.
193 </p>
195 <p>
196 A simple example of a filter effect is a "flood". It takes no image inputs but
197 has a parameter defining a color. The effect produces an output image that is
198 completely filled with the given color. A slightly more complex example is an
199 "inversion" which takes a single image input (typically an image of the element
200 as it would normally be rendered into its parent) and adjusts each pixel such
201 that they have the opposite color values.
202 </p>
204 <p>
205 Filter effects are exposed with three levels of complexity:
206 </p>
208 <ol>
209 <li>
210 A small set of canned filter functions that are given by name. While not
211 particularly powerful, these are convenient and easily understood and provide
212 a simple approach to achieving common effects, such as blurring.
213 </li>
214 <li>
215 A graph of individual filter effects described in markup that define an overall effect.
216 The graph is agnostic to its input in that the effect can be applied to any content.
217 While such graphs are the combination of effects that may be simple in isolation, the
218 graph as a whole can produce complex effects. An example is given below.
219 </li>
220 <li>
221 A customizable system that exposes a shading language allowing control over the
222 geometry and pixel values of filtered output.
223 </li>
224 </ol>
226 <p>
227 The following shows an example of a filter effect.
228 </p>
230 <p>
231 <span class="example-ref">Example filters01</span> - introducing filter
232 effects.
233 </p>
235 <edit:example href="examples/filters01.svg" image="yes" link="yes"/>
237 <p>
238 The filter effect used in the example above is repeated here with reference
239 numbers in the left column before each of the six filter primitives:
240 </p>
242 <table summary="filter example with reference numbers">
243 <tbody>
244 <tr>
245 <td valign="top"><pre>
248 1
249 2
250 3
255 4
256 5
258 6
261 </pre>
262 </td>
263 <td valign="top"><pre><filter id="MyFilter" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
264 <desc>Produces a 3D lighting effect.</desc>
265 <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
266 <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
267 <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75"
268 specularExponent="20" lighting-color="#bbbbbb"
269 result="specOut">
270 <fePointLight x="-5000" y="-10000" z="20000"/>
271 </feSpecularLighting>
272 <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
273 <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic"
274 k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
275 <feMerge>
276 <feMergeNode in="offsetBlur"/>
277 <feMergeNode in="litPaint"/>
278 </feMerge>
279 </filter></pre>
280 </td>
281 </tr>
282 </tbody>
283 </table>
285 <p>
286 The following pictures show the intermediate image results from each of the six
287 filter elements:
288 </p>
290 <table summary="filter example intermediate results">
291 <tbody>
292 <tr>
293 <td><p><img width="115" height="70"
294 alt="filters01 - original source graphic"
295 src="examples/filters01-0.png" /><br />
296 Source graphic</p>
297 </td>
298 <td> </td>
299 <td><p><img width="115" height="70"
300 alt="filters01 - after filter element 1"
301 src="examples/filters01-1.png" /><br />
302 After filter primitive 1</p>
303 </td>
304 <td> </td>
305 <td><p><img width="115" height="70"
306 alt="filters01 - after filter element 2"
307 src="examples/filters01-2.png" /><br />
308 After filter primitive 2</p>
309 </td>
310 <td> </td>
311 <td><p><img width="115" height="70"
312 alt="filters01 - after filter element 3"
313 src="examples/filters01-3.png" /><br />
314 After filter primitive 3</p>
315 </td>
316 </tr>
317 <tr>
318 <td> </td>
319 <td> </td>
320 <td></td>
321 <td></td>
322 <td></td>
323 <td></td>
324 <td></td>
325 </tr>
326 <tr>
327 <td> </td>
328 <td> </td>
329 <td><p><img width="115" height="70"
330 alt="filters01 - after filter element 4"
331 src="examples/filters01-4.png" /><br />
332 After filter primitive 4</p>
333 </td>
334 <td> </td>
335 <td><p><img width="115" height="70"
336 alt="filters01 - after filter element 5"
337 src="examples/filters01-5.png" /><br />
338 After filter primitive 5</p>
339 </td>
340 <td> </td>
341 <td><p><img width="115" height="70"
342 alt="filters01 - after filter element 6"
343 src="examples/filters01-6.png" /><br />
344 After filter primitive 6</p>
345 </td>
346 </tr>
347 </tbody>
348 </table>
349 <ol>
350 <li>
351 Filter primitive <code>feGaussianBlur</code> takes input <a>SourceAlpha</a>,
352 which is the alpha channel of the source graphic. The result is stored in a
353 temporary buffer named "blur". Note that "blur" is used as input to both
354 filter primitives 2 and 3.
355 </li>
356 <li>
357 Filter primitive <code>feOffset</code> takes buffer "blur", shifts the result in
358 a positive direction in both x and y, and creates a new buffer named
359 "offsetBlur". The effect is that of a drop shadow.
360 </li>
361 <li>
362 Filter primitive <code>feSpecularLighting</code>, uses buffer "blur" as a model
363 of a surface elevation and generates a lighting effect from a single point
364 source. The result is stored in buffer "specOut".
365 </li>
366 <li>
367 Filter primitive <code>feComposite</code> masks out the result of filter
368 primitive 3 by the original source graphics alpha channel so that the
369 intermediate result is no bigger than the original source graphic.
370 </li>
371 <li>
372 Filter primitive <code>feComposite</code> composites the result of the specular
373 lighting with the original source graphic.
374 </li>
375 <li>
376 Filter primitive <code>feMerge</code> composites two layers together. The lower
377 layer consists of the drop shadow result from filter primitive 2. The upper
378 layer consists of the specular lighting result from filter primitive 5.
379 </li>
380 </ol>
382 <!-- ****************************************************************************** -->
384 <h2 id="about">Reading This Document</h2>
386 <p>
387 Each section of this document is normative unless otherwise specified.
388 </p>
390 <p>
391 This document contains explicit conformance criteria that overlap with some
392 RelaxNG definitions in requirements. If there is any conflict between the two,
393 the explicit conformance criteria are the definitive reference.
394 </p>
396 <p>
397 Note that even though this specification references parts of <a
398 href="#ref-svg11">SVG 1.1</a> it does not require an SVG 1.1
399 implementation. <span class="note">Add link to conformance classes
400 here.</span>
401 </p>
403 <!-- ****************************************************************************** -->
405 <h2 id="definitions">Definitions</h2>
407 <p>
408 When used in this specification, terms have the meanings assigned in this section.
409 </p>
411 <dl>
412 <dt id="term-null-filter"><span
413 class="termDefine">null filter</span></dt>
414 <dd>
415 <p>
416 The null filter output is all transparent black pixels. If applied to an element it means
417 that the element (and children if any) becomes invisible. Note that it does not affect event processing.
418 </p>
419 </dd>
420 <dt id="TermTransferFunctionElements"><span
421 class="SVG-TermDefine">transfer function elements</span></dt>
422 <dd>
423 <p>
424 The set of elements,
425 <a>'feFuncR'</a>, <a>'feFuncG'</a>, <a>'feFuncB'</a>, <a>'feFuncA'</a>, that define the transfer function for the <a>'feComponentTransfer'</a> filter primitive.
426 </p>
427 </dd>
428 <dt id="TermClientBoundingRect"><span
429 class="SVG-TermDefine">bounding client rect</span></dt>
430 <dd>
431 <p>
432 The union of all CSS border-boxes for the element if formatted with the CSS box model, as defined by the CSS OM method
433 <a href="http://www.w3.org/TR/cssom-view/#dom-element-getboundingclientrect">getBoundingClientRect</a> [<a href="#ref-CSSOM">CSSOM</a>].
434 </p>
435 </dd>
436 <dt id="TermCSSBoundingBox"><span
437 class="SVG-TermDefine">CSS bounding box</span></dt>
438 <dd>
439 <p>
440 The union of all CSS border-boxes for the element and all it's descendant elements, provided the element is formatted with the CSS box model [<a href="#ref-CSS21">CSS</a>].
441 </p>
442 </dd>
443 <dt id="TermCurrentUserCoordinateSystem"><span
444 class="SVG-TermDefine">current user coordinate system</span></dt>
445 <dd>
446 <p>
447 For elements formatted with the CSS box model: the current user coordinate system has its origin at the top-left corner of the
448 <a href="#TermClientBoundingRect">bounding client rect</a> and one unit equals on CSS px. The viewport for resolving percentage values is defined by the width and height of the
449 <a href="#TermClientBoundingRect">bounding client rect</a>.
450 </p>
451 <p>
452 For elements using SVG layout see <a>user coordinate system</a>.
453 </p>
454 </dd>
455 <dt id="TermObjectBoundingBoxUnits"><span
456 class="SVG-TermDefine">object bounding box units</span></dt>
457 <dd>
458 For elements formatted with the CSS box model: the bounding box is defined by <a href="#TermCSSBoundingBox">the CSS bounding box.</a>
459 <p>
460 For elements using SVG layout the bounding box is defined by <a href="http://www.w3.org/TR/2008/REC-SVGTiny12-20081222/intro.html#TermBoundingBox">the SVG bounding box</a>.
461 </p>
462 <p>
463 For both cases the bounding box defines the coordinate system in which to resolve values, as defined in <a>object bounding box units</a>.
464 </p>
465 </dd>
466 <dt id="TermFilterPrimitiveReference"><span
467 class="SVG-TermDefine"><filter-primitive-reference></span></dt>
468 <dd>
469 <p>
470 A string that identifies a particular filter primitive's output.
471 </p>
472 </dd>
473 <dt id="TermFilterPrimitiveElements"><span
474 class="SVG-TermDefine">filter primitives, filter primitive elements</span></dt>
475 <dd>
476 <p>
477 The set of elements that control the output of a <a>'filter element'</a> element, particularly:
478 <a>'feDistantLight'</a>,
479 <a>'fePointLight'</a>,
480 <a>'feSpotLight'</a>,
481 <a>'feBlend'</a>,
482 <a>'feColorMatrix'</a>,
483 <a>'feComponentTransfer'</a>,
484 <a>'feComposite'</a>,
485 <a>'feConvolveMatrix'</a>,
486 <a>'feDiffuseLighting'</a>,
487 <a>'feDisplacementMap'</a>,
488 <a>'feFlood'</a>,
489 <a>'feGaussianBlur'</a>,
490 <a>'feImage'</a>,
491 <a>'feMerge'</a>,
492 <a>'feMorphology'</a>,
493 <a>'feOffset'</a>,
494 <a>'feSpecularLighting'</a>,
495 <a>'feTile'</a>,
496 <a>'feTurbulence'</a>,
497 <a>'feDropShadow'</a>,
498 <a>'feDiffuseSpecular'</a>,
499 <a>'feUnsharpMask'</a>,
500 <a>'feCustom'</a>.
501 </p>
502 </dd>
503 </dl>
505 <!-- ****************************************************************************** -->
507 <h2 id="security">Security</h2>
509 <p class="todo">Should this section be merged with the CSS shaders
510 <a href="https://dvcs.w3.org/hg/FXTF/raw-file/tip/custom/index.html#security-considerations">security
511 considerations</a> section?</a>
513 <h3 id="timing-attacks">Timing Attacks</h3>
515 <p>
516 Since a filter effect is applying a processing operation on input values, it
517 is vital that no private information leaks from that operation. The same rules
518 for cross-origin restrictions and tainting of data values apply to filtered
519 content. There are a number of extra cases that are called out here.
520 </p>
522 <p>
523 A timing attack is a method of obtaining information about content that is
524 otherwise protected, based on studying the amount of time it takes for an
525 operation to occur. For example, rendering is an operation that takes a
526 significant amount of time, and that time depends on the complexity of the
527 drawing operations involved. If, for example, red pixels took longer to draw
528 than green pixels, one might be able to obtain an indication of the proportion
529 of red to green in the element being rendered, even without ever having access
530 to the content of the element. Taking that to its theoretical extreme, an
531 attack may be able to modify content in a way that exposes such variations in
532 timing over a long enough period.
533 </p>
535 <p>
536 Filter effects do not add new vulnerabilities to such attacks, but they
537 possibly allow malicious code to be written that accelerates the process. For
538 example, a filter effect might be able to modify input pixel values in a manner
539 that amplifies the differences in rendering. It is essential that a filter
540 effect expose as little private information to the system as possible. One of
541 the well-documented security issues is exposing the user's browsing history to
542 script based on detecting the color of link elements styled with the 'visited'
543 pseudo-class.
544 </p>
546 <p>
547 A user agent must ensure that any content passed to a filter effect has
548 discernible information removed. This includes, but is not limited-to:
549 </p>
551 <ul>
552 <li>visited link styles must not be applied</li>
553 <li>file input should not identify any file names</li>
554 <li>editable content should not highlight dictionary information</li>
555 <li>cross-origin restrictions described below</li>
556 </ul>
558 <h3 id="origin-restrictions">Origin Restrictions</h3>
560 <p>
561 Input to a filter effect must not include anything as input that would
562 violate cross-origin restrictions. If cross-origin access is required,
563 then the requested content should be explicitly marked with CORS data.
564 </p>
566 <p>
567 This restriction includes:
568 </p>
570 <ul>
571 <li>Any 'iframe' content</li>
572 <li>Any images, either as content or via styling, that are not exposed with CORS</li>
573 <li>Any tainted canvas</li>
574 <li>Any cross-origin content referenced by 'use'</li>
575 </ul>
577 <p>
578 For content that falls under this restriction, it should not be rendered into
579 the input image. For example, a filter effect that is applying to a cross-origin
580 'iframe' element would receive a completely blank input image.
581 </p>
583 <h2 id="FilterProperty">The <span class="prop-name">'filter'</span>
584 property</h2>
586 <p>
587 The description of the <span class="prop-name">'filter'</span> property is
588 as follows:</p>
590 <div class="propdef">
591 <dl>
592 <dt id='propdef-filter'><span class='propdef-title prop-name'>'filter'</span></dt>
593 <dd>
594 <table summary="filter property" class="propinfo" cellspacing="0"
595 cellpadding="0">
596 <tbody>
597 <tr valign="baseline">
598 <td><em>Value:</em> </td>
599 <td>none | <a href="#FilterFunction"><filter-function></a> [ <a href="#FilterFunction"><filter-function></a> ]* </td>
600 </tr>
601 <tr valign="baseline">
602 <td><em>Initial:</em> </td>
603 <td>none</td>
604 </tr>
605 <tr valign="baseline">
606 <td><em>Applies to:</em> </td>
607 <td>All elements <span class="specissue">In SVG 1.1 it applies only to "container elements (except ‘mask’) and graphics elements"</span></td>
608 </tr>
609 <tr valign="baseline">
610 <td><em>Inherited:</em> </td>
611 <td>no</td>
612 </tr>
613 <tr valign="baseline">
614 <td><em>Percentages:</em> </td>
615 <td>N/A</td>
616 </tr>
617 <tr valign="baseline">
618 <td><em>Media:</em> </td>
619 <td>visual</td>
620 </tr>
621 <tr valign="baseline">
622 <td><em>Animatable:</em> </td>
623 <td>yes</td>
624 </tr>
625 </tbody>
626 </table>
627 </dd>
628 </dl>
629 </div>
631 <p>
632 If the value of the <a>'filter property'</a> property is <span class="prop-value">none</span> then there
633 is no filter effect applied. Otherwise, the list of functions (described <a href="#FilterFunction">below</a>)
634 are applied in order.
635 </p>
637 <h3 id="filters-in-css">How the 'filter' property property applies to content formatted with the CSS box model (e.g HTML)</h3>
638 <p>
639 The application of the <a>'filter property'</a> property to an element
640 formatted with the CSS box model establishes a pseudo-stacking-context the same way that CSS
641 <a href="http://www.w3.org/TR/css3-color/#transparency">'opacity'</a> does,
642 and all the element's boxes are rendered together as a group with the filter
643 effect applied to the group as a whole.
644 </p>
645 <p>
646 The <a>'filter property'</a> property has no effect on the geometry of the
647 target element's CSS boxes, even though <a>'filter property'</a> can cause
648 painting outside of an element's border-box.
649 </p>
650 <p>
651 The compositing model follows the <a
652 href="http://www.w3.org/TR/SVG11/render.html#Introduction">SVG compositing
653 model</a>: first any filter effect is applied, then any clipping, masking
654 and opacity. These effects all apply after any other CSS effects such as
655 'border'. As per SVG, the application of <a>'filter property'</a> has no
656 effect on hit-testing.
657 </p>
659 <br />
661 <h2 id="FilterFunction">Filter Functions</h2>
663 <p>
664 The value of the <a>'filter'</a> property is a list of <filter-functions>
665 applied in the order provided. The individual filter functions are
666 separated by whitespace. The set of allowed filter functions is given
667 below.
668 </p>
670 <dl>
671 <dt>
672 <a><FuncIRI></a>
673 </dt>
674 <dd>
675 An <a>IRI reference</a>
676 to a <a>'filter element'</a> element that defines the
677 filter effect. For example "url(commonfilters.xml#large-blur)". If the IRI references a non-existent object or the referenced
678 object is not a <a>'filter element'</a> element, then the <a>null filter</a> will be applied instead.
679 </dd>
681 <dt>
682 grayscale(amount)
683 </dt>
684 <dd>
685 Converts the input image to grayscale. The value of 'amount' defines the proportion
686 of the conversion. A value of 100% is completely grayscale. A value of 0% leaves the
687 input unchanged. Values between 0% and 100% are linear multipliers on the effect.
688 If the 'amount' parameter is missing, a value of 100% is used.
689 The markup equivalent of this function is <a href="#grayscaleEquivalent">given below</a>.
690 </dd>
692 <dt>
693 sepia(amount)
694 </dt>
695 <dd>
696 Converts the input image to sepia. The value of 'amount' defines the proportion
697 of the conversion. A value of 100% is completely sepia. A value of 0 leaves the
698 input unchanged. Values between 0% and 100% are linear multipliers on the effect.
699 If the 'amount' parameter is missing, a value of 100% is used.
700 The markup equivalent of this function is <a href="#sepiaEquivalent">given below</a>.
701 </dd>
703 <dt>
704 saturate(amount)
705 </dt>
706 <dd>
707 Saturates the input image. The value of 'amount' defines the proportion
708 of the conversion. A value of 0% is completely un-saturated. A value of 100% leaves the
709 input unchanged. Other values are linear multipliers on the effect.
710 Values of amount over 100% are allowed, providing super-saturated results.
711 If the 'amount' parameter is missing, a value of 100% is used.
712 The markup equivalent of this function is <a href="#saturateEquivalent">given below</a>.
713 </dd>
715 <dt>
716 hue-rotate(angle)
717 </dt>
718 <dd>
719 Applies a hue rotation on the input image. The value of 'angle' defines the
720 number of degrees around the color circle the input samples will be adjusted.
721 A value of 0deg leaves the input unchanged. If the 'angle' parameter is missing,
722 a value of 0deg is used. Implementations should not normalize this value in order
723 to allow animations beyond 360deg.
724 The markup equivalent of this function is <a href="#huerotateEquivalent">given below</a>.
725 </dd>
727 <dt>
728 invert(amount)
729 </dt>
730 <dd>
731 Inverts the samples in the input image. The value of 'amount' defines the proportion
732 of the conversion. A value of 100% is completely inverted. A value of 0% leaves the
733 input unchanged. Values between 0% and 100% are linear multipliers on the effect.
734 If the 'amount' parameter is missing, a value of 100% is used.
735 The markup equivalent of this function is <a href="#invertEquivalent">given below</a>.
736 </dd>
738 <dt>
739 opacity(amount)
740 </dt>
741 <dd>
742 Applies transparency to the samples in the input image. The value of 'amount' defines the proportion
743 of the conversion. A value of 0% is completely transparent. A value of 100% leaves the
744 input unchanged. Values between 0% and 100% are linear multipliers on the effect.
745 This is equivalent to multiplying the input image samples by amount.
746 If the 'amount' parameter is missing, a value of 100% is used.
747 The markup equivalent of this function is <a href="#opacityEquivalent">given below</a>.
748 </dd>
750 <dt>
751 brightness(amount)
752 </dt>
753 <dd>
754 Applies a linear multiplier to input image, making it appear more
755 or less bright.
756 A value of 0% will create an image that is completely black. A value of 100% leaves the
757 input unchanged. Other values are linear multipliers on the effect.
758 Values of amount over 100% are allowed, providing brighter results.
759 If the 'amount' parameter is missing, a value of 100% is used.
760 The markup equivalent of this function is <a href="#brightnessEquivalent">given below</a>.
761 </dd>
763 <dt>
764 contrast(amount)
765 </dt>
766 <dd>
767 Adjusts the contrast of the input.
768 A value of 0% will create an image that is completely black. A value of 100% leaves the
769 input unchanged. Values of amount over 100% are allowed, providing results with less contrast.
770 If the 'amount' parameter is missing, a value of 100% is used.
771 The markup equivalent of this function is <a href="#contrastEquivalent">given below</a>.
772 </dd>
774 <dt>
775 blur(radius)
776 </dt>
777 <dd>
778 Applies a Gaussian blur to the input image.
779 The value of 'radius' defines the value of the standard deviation to the Gaussian function.
780 If no parameter is provided, then a value 0 is used. The parameter is
781 specified a CSS length, but does not accept percentage values.
782 The markup equivalent of this function is <a href="#blurEquivalent">given below</a>.
783 </dd>
785 <dt>
786 drop-shadow(<shadow>)
787 </dt>
788 <dd>
789 Applies a drop shadow effect to the input image. A drop shadow is
790 effectively a blurred, offset version of the input image's alpha mask
791 drawn in a particular color, composited below the image. The function
792 accepts a parameter of type <shadow> (defined in CSS3 Backgrounds),
793 with the exception that the 'inset' keyword is not allowed. The markup
794 equivalent of this function is <a href="#dropshadowEquivalent">given
795 below</a>.
796 </dd>
798 <dt>
799 <code>custom(<span class="highlight"><vertex-shader></span><span class="highlight2">[</span><span class="fade">wsp</span><span class="highlight"><fragment-shader></span><span class="highlight2">][,</span><span class="highlight"><vertex-mesh></span><span class="highlight2">][,</span><span class="highlight"><params></span><span class="highlight2">]</span>)</code>
800 </dt>
801 <dd>
802 <table class="values-desc">
803 <tr>
804 <td><code><vertex-shader></code></td>
805 <td><code><uri> | none</code></td>
806 </tr>
807 <tr>
808 <td><code><fragment-shader></code></td>
809 <td><code><uri> | none</code></td>
810 </tr>
811 <tr>
812 <td><code><vertex-mesh></code></td>
813 <td><code>+<integer>{1,2}[wsp<box>][wsp'detached']</code><br />
814 where: <code><box> = filter-box | border-box | padding-box | content-box</code></td>
815 </tr>
816 <tr>
817 <td id='#shader-params'><code><params></code></td>
818 <td>See the <code><feCustom></code>'s <a href='#feCustomParamsAttribute'><code>params</code></a> attribute.</td>
819 </tr>
820 </table>
822 <div class="todo">Add description to the filter here and reference to equivalent.</div>
824 <div class="note">It might be clearer to name the <code>custom()</code> function
825 the <code>shader()</code> function instead and introduce an <code>feCustomShader</code>
826 filter primitive instead of <code>feCustom</code>.</div>
828 </dd>
829 </dl>
831 <div class="note">
832 <p>
833 The above list is a collection of effects that can be easily defined in
834 terms of SVG filters. However, there are many more interesting effects
835 that can be considered for inclusion. If accepted, there will have to
836 be equivalent XML elements for the effect. Effects considered include:
837 </p>
838 <ul>
839 <li>brightness, contrast, exposure</li>
840 <li>halftone</li>
841 <li>motion-blur(radius, angle)</li>
842 <li>posterize(levels)</li>
843 <li>bump(x, y, radius, intensity)</li>
844 <li>generators</li>
845 <li>circle-crop(x, y, radius)</li>
846 <li>affine-transform(some matrix)</li>
847 <li>crop(x, y, w, h)</li>
848 <li>bloom(radius, intensity)</li>
849 <li>gloom(radius, intensity)</li>
850 <li>mosaic(w,h)</li>
851 <li>displace(url, intensity)</li>
852 <li>edge-detect(intensity)</li>
853 <li>pinch(x, y, radius, scale)</li>
854 <li>twirl(x, y, radius, angle)</li>
855 </ul>
856 </div>
858 <p>
859 The first function in the list takes the element (<a href="#SourceGraphic">SourceGraphic</a>) as
860 the input image. Subsequent operations take the output from the
861 previous function as the input image. The exception is the function
862 that references a 'filter element' element, which can specify an
863 alternate input, but still uses the previous output as its
864 <a href="#SourceGraphic">SourceGraphic</a>.
865 </p>
867 <h2 id="FilterElement">The <span class="element-name">'filter'</span>
868 element</h2>
870 <div class="element-summary">
871 <div class="element-summary-name">
872 <span class="element-name">
873 ‘filter’
874 </span>
875 </div>
876 <dl>
877 <dt>
878 Categories:</dt>
879 <dd>
880 None</dd>
881 <dt>
882 Content model:</dt>
883 <dd>
884 Any number of the following elements, in any order:
885 <ul class="no-bullets">
886 <li>
887 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermDescriptiveElement">
888 descriptive elements</a>
889 <span class="expanding">
890 — <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#DescElement">
891 <span class="element-name">
892 ‘desc’
893 </span>
894 </a>
895 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/metadata.html#MetadataElement">
896 <span class="element-name">
897 ‘metadata’
898 </span>
899 </a>
900 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#TitleElement">
901 <span class="element-name">
902 ‘title’
903 </span>
904 </a>
906 </span>
907 </li>
908 <li>
909 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermFilterPrimitiveElement">
910 filter primitive elements</a>
911 <span class="expanding">
912 — <a href="#feBlendElement">
913 <span class="element-name">
914 ‘feBlend’
915 </span>
916 </a>
917 , <a href="#feColorMatrixElement">
918 <span class="element-name">
919 ‘feColorMatrix’
920 </span>
921 </a>
922 , <a href="#feComponentTransferElement">
923 <span class="element-name">
924 ‘feComponentTransfer’
925 </span>
926 </a>
927 , <a href="#feCompositeElement">
928 <span class="element-name">
929 ‘feComposite’
930 </span>
931 </a>
932 , <a href="#feConvolveMatrixElement">
933 <span class="element-name">
934 ‘feConvolveMatrix’
935 </span>
936 </a>
937 , <a href="#feDiffuseLightingElement">
938 <span class="element-name">
939 ‘feDiffuseLighting’
940 </span>
941 </a>
942 , <a href="#feDisplacementMapElement">
943 <span class="element-name">
944 ‘feDisplacementMap’
945 </span>
946 </a>
947 , <a href="#feFloodElement">
948 <span class="element-name">
949 ‘feFlood’
950 </span>
951 </a>
952 , <a href="#feGaussianBlurElement">
953 <span class="element-name">
954 ‘feGaussianBlur’
955 </span>
956 </a>
957 , <a href="#feImageElement">
958 <span class="element-name">
959 ‘feImage’
960 </span>
961 </a>
962 , <a href="#feMergeElement">
963 <span class="element-name">
964 ‘feMerge’
965 </span>
966 </a>
967 , <a href="#feMorphologyElement">
968 <span class="element-name">
969 ‘feMorphology’
970 </span>
971 </a>
972 , <a href="#feOffsetElement">
973 <span class="element-name">
974 ‘feOffset’
975 </span>
976 </a>
977 , <a href="#feSpecularLightingElement">
978 <span class="element-name">
979 ‘feSpecularLighting’
980 </span>
981 </a>
982 , <a href="#feTileElement">
983 <span class="element-name">
984 ‘feTile’
985 </span>
986 </a>
987 , <a href="#feTurbulenceElement">
988 <span class="element-name">
989 ‘feTurbulence’
990 </span>
991 </a>
993 </span>
994 </li>
995 <li>
996 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/animate.html#AnimateElement">
997 <span class="element-name">
998 ‘animate’
999 </span>
1000 </a>
1001 </li>
1002 <li>
1003 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/animate.html#SetElement">
1004 <span class="element-name">
1005 ‘set’
1006 </span>
1007 </a>
1008 </li>
1009 </ul>
1010 </dd>
1011 <dt>
1012 Attributes:</dt>
1013 <dd>
1014 <ul class="no-bullets">
1015 <li>
1016 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermCoreAttributes">
1017 core attributes</a>
1018 <span class="expanding">
1019 — <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#IDAttribute">
1020 <span class="attr-name">
1021 ‘id’
1022 </span>
1023 </a>
1024 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#XMLBaseAttribute">
1025 <span class="attr-name">
1026 ‘xml:base’
1027 </span>
1028 </a>
1029 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#XMLLangAttribute">
1030 <span class="attr-name">
1031 ‘xml:lang’
1032 </span>
1033 </a>
1034 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#XMLSpaceAttribute">
1035 <span class="attr-name">
1036 ‘xml:space’
1037 </span>
1038 </a>
1040 </span>
1041 </li>
1042 <li>
1043 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermPresentationAttribute">
1044 presentation attributes</a>
1045 <span class="expanding">
1046 — <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#AlignmentBaselineProperty">
1047 <span class="attr-name" title="Presentation attribute for property ‘alignment-baseline’">
1048 ‘alignment-baseline’
1049 </span>
1050 </a>
1051 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#BaselineShiftProperty">
1052 <span class="attr-name" title="Presentation attribute for property ‘baseline-shift’">
1053 ‘baseline-shift’
1054 </span>
1055 </a>
1056 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/masking.html#ClipProperty">
1057 <span class="attr-name" title="Presentation attribute for property ‘clip’">
1058 ‘clip’
1059 </span>
1060 </a>
1061 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/masking.html#ClipPathProperty">
1062 <span class="attr-name" title="Presentation attribute for property ‘clip-path’">
1063 ‘clip-path’
1064 </span>
1065 </a>
1066 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/masking.html#ClipRuleProperty">
1067 <span class="attr-name" title="Presentation attribute for property ‘clip-rule’">
1068 ‘clip-rule’
1069 </span>
1070 </a>
1071 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/color.html#ColorProperty">
1072 <span class="attr-name" title="Presentation attribute for property ‘color’">
1073 ‘color’
1074 </span>
1075 </a>
1076 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#ColorInterpolationProperty">
1077 <span class="attr-name" title="Presentation attribute for property ‘color-interpolation’">
1078 ‘color-interpolation’
1079 </span>
1080 </a>
1081 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#ColorInterpolationFiltersProperty">
1082 <span class="attr-name" title="Presentation attribute for property ‘color-interpolation-filters’">
1083 ‘color-interpolation-filters’
1084 </span>
1085 </a>
1086 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/color.html#ColorProfileProperty">
1087 <span class="attr-name" title="Presentation attribute for property ‘color-profile’">
1088 ‘color-profile’
1089 </span>
1090 </a>
1091 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#ColorRenderingProperty">
1092 <span class="attr-name" title="Presentation attribute for property ‘color-rendering’">
1093 ‘color-rendering’
1094 </span>
1095 </a>
1096 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/interact.html#CursorProperty">
1097 <span class="attr-name" title="Presentation attribute for property ‘cursor’">
1098 ‘cursor’
1099 </span>
1100 </a>
1101 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#DirectionProperty">
1102 <span class="attr-name" title="Presentation attribute for property ‘direction’">
1103 ‘direction’
1104 </span>
1105 </a>
1106 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#DisplayProperty">
1107 <span class="attr-name" title="Presentation attribute for property ‘display’">
1108 ‘display’
1109 </span>
1110 </a>
1111 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#DominantBaselineProperty">
1112 <span class="attr-name" title="Presentation attribute for property ‘dominant-baseline’">
1113 ‘dominant-baseline’
1114 </span>
1115 </a>
1116 , <a href="#EnableBackgroundProperty">
1117 <span class="attr-name" title="Presentation attribute for property ‘enable-background’">
1118 ‘enable-background’
1119 </span>
1120 </a>
1121 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#FillProperty">
1122 <span class="attr-name" title="Presentation attribute for property ‘fill’">
1123 ‘fill’
1124 </span>
1125 </a>
1126 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#FillOpacityProperty">
1127 <span class="attr-name" title="Presentation attribute for property ‘fill-opacity’">
1128 ‘fill-opacity’
1129 </span>
1130 </a>
1131 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#FillRuleProperty">
1132 <span class="attr-name" title="Presentation attribute for property ‘fill-rule’">
1133 ‘fill-rule’
1134 </span>
1135 </a>
1136 , <a href="#FilterProperty">
1137 <span class="attr-name" title="Presentation attribute for property ‘filter’">
1138 ‘filter’
1139 </span>
1140 </a>
1141 , <a href="#FloodColorProperty">
1142 <span class="attr-name" title="Presentation attribute for property ‘flood-color’">
1143 ‘flood-color’
1144 </span>
1145 </a>
1146 , <a href="#FloodOpacityProperty">
1147 <span class="attr-name" title="Presentation attribute for property ‘flood-opacity’">
1148 ‘flood-opacity’
1149 </span>
1150 </a>
1151 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontFamilyProperty">
1152 <span class="attr-name" title="Presentation attribute for property ‘font-family’">
1153 ‘font-family’
1154 </span>
1155 </a>
1156 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontSizeProperty">
1157 <span class="attr-name" title="Presentation attribute for property ‘font-size’">
1158 ‘font-size’
1159 </span>
1160 </a>
1161 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontSizeAdjustProperty">
1162 <span class="attr-name" title="Presentation attribute for property ‘font-size-adjust’">
1163 ‘font-size-adjust’
1164 </span>
1165 </a>
1166 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontStretchProperty">
1167 <span class="attr-name" title="Presentation attribute for property ‘font-stretch’">
1168 ‘font-stretch’
1169 </span>
1170 </a>
1171 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontStyleProperty">
1172 <span class="attr-name" title="Presentation attribute for property ‘font-style’">
1173 ‘font-style’
1174 </span>
1175 </a>
1176 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontVariantProperty">
1177 <span class="attr-name" title="Presentation attribute for property ‘font-variant’">
1178 ‘font-variant’
1179 </span>
1180 </a>
1181 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#FontWeightProperty">
1182 <span class="attr-name" title="Presentation attribute for property ‘font-weight’">
1183 ‘font-weight’
1184 </span>
1185 </a>
1186 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#GlyphOrientationHorizontalProperty">
1187 <span class="attr-name" title="Presentation attribute for property ‘glyph-orientation-horizontal’">
1188 ‘glyph-orientation-horizontal’
1189 </span>
1190 </a>
1191 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#GlyphOrientationVerticalProperty">
1192 <span class="attr-name" title="Presentation attribute for property ‘glyph-orientation-vertical’">
1193 ‘glyph-orientation-vertical’
1194 </span>
1195 </a>
1196 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#ImageRenderingProperty">
1197 <span class="attr-name" title="Presentation attribute for property ‘image-rendering’">
1198 ‘image-rendering’
1199 </span>
1200 </a>
1201 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#KerningProperty">
1202 <span class="attr-name" title="Presentation attribute for property ‘kerning’">
1203 ‘kerning’
1204 </span>
1205 </a>
1206 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#LetterSpacingProperty">
1207 <span class="attr-name" title="Presentation attribute for property ‘letter-spacing’">
1208 ‘letter-spacing’
1209 </span>
1210 </a>
1211 , <a href="#LightingColorProperty">
1212 <span class="attr-name" title="Presentation attribute for property ‘lighting-color’">
1213 ‘lighting-color’
1214 </span>
1215 </a>
1216 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#MarkerEndProperty">
1217 <span class="attr-name" title="Presentation attribute for property ‘marker-end’">
1218 ‘marker-end’
1219 </span>
1220 </a>
1221 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#MarkerMidProperty">
1222 <span class="attr-name" title="Presentation attribute for property ‘marker-mid’">
1223 ‘marker-mid’
1224 </span>
1225 </a>
1226 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#MarkerStartProperty">
1227 <span class="attr-name" title="Presentation attribute for property ‘marker-start’">
1228 ‘marker-start’
1229 </span>
1230 </a>
1231 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/masking.html#MaskProperty">
1232 <span class="attr-name" title="Presentation attribute for property ‘mask’">
1233 ‘mask’
1234 </span>
1235 </a>
1236 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/masking.html#OpacityProperty">
1237 <span class="attr-name" title="Presentation attribute for property ‘opacity’">
1238 ‘opacity’
1239 </span>
1240 </a>
1241 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/masking.html#OverflowProperty">
1242 <span class="attr-name" title="Presentation attribute for property ‘overflow’">
1243 ‘overflow’
1244 </span>
1245 </a>
1246 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/interact.html#PointerEventsProperty">
1247 <span class="attr-name" title="Presentation attribute for property ‘pointer-events’">
1248 ‘pointer-events’
1249 </span>
1250 </a>
1251 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#ShapeRenderingProperty">
1252 <span class="attr-name" title="Presentation attribute for property ‘shape-rendering’">
1253 ‘shape-rendering’
1254 </span>
1255 </a>
1256 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/pservers.html#StopColorProperty">
1257 <span class="attr-name" title="Presentation attribute for property ‘stop-color’">
1258 ‘stop-color’
1259 </span>
1260 </a>
1261 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/pservers.html#StopOpacityProperty">
1262 <span class="attr-name" title="Presentation attribute for property ‘stop-opacity’">
1263 ‘stop-opacity’
1264 </span>
1265 </a>
1266 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeProperty">
1267 <span class="attr-name" title="Presentation attribute for property ‘stroke’">
1268 ‘stroke’
1269 </span>
1270 </a>
1271 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeDasharrayProperty">
1272 <span class="attr-name" title="Presentation attribute for property ‘stroke-dasharray’">
1273 ‘stroke-dasharray’
1274 </span>
1275 </a>
1276 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeDashoffsetProperty">
1277 <span class="attr-name" title="Presentation attribute for property ‘stroke-dashoffset’">
1278 ‘stroke-dashoffset’
1279 </span>
1280 </a>
1281 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeLinecapProperty">
1282 <span class="attr-name" title="Presentation attribute for property ‘stroke-linecap’">
1283 ‘stroke-linecap’
1284 </span>
1285 </a>
1286 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeLinejoinProperty">
1287 <span class="attr-name" title="Presentation attribute for property ‘stroke-linejoin’">
1288 ‘stroke-linejoin’
1289 </span>
1290 </a>
1291 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeMiterlimitProperty">
1292 <span class="attr-name" title="Presentation attribute for property ‘stroke-miterlimit’">
1293 ‘stroke-miterlimit’
1294 </span>
1295 </a>
1296 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeOpacityProperty">
1297 <span class="attr-name" title="Presentation attribute for property ‘stroke-opacity’">
1298 ‘stroke-opacity’
1299 </span>
1300 </a>
1301 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#StrokeWidthProperty">
1302 <span class="attr-name" title="Presentation attribute for property ‘stroke-width’">
1303 ‘stroke-width’
1304 </span>
1305 </a>
1306 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#TextAnchorProperty">
1307 <span class="attr-name" title="Presentation attribute for property ‘text-anchor’">
1308 ‘text-anchor’
1309 </span>
1310 </a>
1311 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#TextDecorationProperty">
1312 <span class="attr-name" title="Presentation attribute for property ‘text-decoration’">
1313 ‘text-decoration’
1314 </span>
1315 </a>
1316 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#TextRenderingProperty">
1317 <span class="attr-name" title="Presentation attribute for property ‘text-rendering’">
1318 ‘text-rendering’
1319 </span>
1320 </a>
1321 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#UnicodeBidiProperty">
1322 <span class="attr-name" title="Presentation attribute for property ‘unicode-bidi’">
1323 ‘unicode-bidi’
1324 </span>
1325 </a>
1326 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/painting.html#VisibilityProperty">
1327 <span class="attr-name" title="Presentation attribute for property ‘visibility’">
1328 ‘visibility’
1329 </span>
1330 </a>
1331 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#WordSpacingProperty">
1332 <span class="attr-name" title="Presentation attribute for property ‘word-spacing’">
1333 ‘word-spacing’
1334 </span>
1335 </a>
1336 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/text.html#WritingModeProperty">
1337 <span class="attr-name" title="Presentation attribute for property ‘writing-mode’">
1338 ‘writing-mode’
1339 </span>
1340 </a>
1342 </span>
1343 </li>
1344 <li>
1345 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermXLinkAttributes">
1346 xlink attributes</a>
1347 <span class="expanding">
1348 — <a href="#FilterElementHrefAttribute">
1349 <span class="attr-name">
1350 ‘xlink:href’
1351 </span>
1352 </a>
1353 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/linking.html#XLinkShowAttribute">
1354 <span class="attr-name">
1355 ‘xlink:show’
1356 </span>
1357 </a>
1358 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/linking.html#XLinkActuateAttribute">
1359 <span class="attr-name">
1360 ‘xlink:actuate’
1361 </span>
1362 </a>
1363 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/linking.html#XLinkTypeAttribute">
1364 <span class="attr-name">
1365 ‘xlink:type’
1366 </span>
1367 </a>
1368 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/linking.html#XLinkRoleAttribute">
1369 <span class="attr-name">
1370 ‘xlink:role’
1371 </span>
1372 </a>
1373 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/linking.html#XLinkArcRoleAttribute">
1374 <span class="attr-name">
1375 ‘xlink:arcrole’
1376 </span>
1377 </a>
1378 , <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/linking.html#XLinkTitleAttribute">
1379 <span class="attr-name">
1380 ‘xlink:title’
1381 </span>
1382 </a>
1384 </span>
1385 </li>
1386 <li>
1387 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/styling.html#ClassAttribute">
1388 <span class="attr-name">
1389 ‘class’
1390 </span>
1391 </a>
1392 </li>
1393 <li>
1394 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/styling.html#StyleAttribute">
1395 <span class="attr-name">
1396 ‘style’
1397 </span>
1398 </a>
1399 </li>
1400 <li>
1401 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#ExternalResourcesRequiredAttribute">
1402 <span class="attr-name">
1403 ‘externalResourcesRequired’
1404 </span>
1405 </a>
1406 </li>
1407 <li>
1408 <a href="#FilterElementXAttribute">
1409 <span class="attr-name">
1410 ‘x’
1411 </span>
1412 </a>
1413 </li>
1414 <li>
1415 <a href="#FilterElementYAttribute">
1416 <span class="attr-name">
1417 ‘y’
1418 </span>
1419 </a>
1420 </li>
1421 <li>
1422 <a href="#FilterElementWidthAttribute">
1423 <span class="attr-name">
1424 ‘width’
1425 </span>
1426 </a>
1427 </li>
1428 <li>
1429 <a href="#FilterElementHeightAttribute">
1430 <span class="attr-name">
1431 ‘height’
1432 </span>
1433 </a>
1434 </li>
1435 <li>
1436 <a href="#FilterElementFilterResAttribute">
1437 <span class="attr-name">
1438 ‘filterRes’
1439 </span>
1440 </a>
1441 </li>
1442 <li>
1443 <a href="#FilterElementFilterUnitsAttribute">
1444 <span class="attr-name">
1445 ‘filterUnits’
1446 </span>
1447 </a>
1448 </li>
1449 <li>
1450 <a href="#FilterElementPrimitiveUnitsAttribute">
1451 <span class="attr-name">
1452 ‘primitiveUnits’
1453 </span>
1454 </a>
1455 </li>
1456 <li>
1457 <a href="#FilterElementHrefAttribute">
1458 <span class="attr-name">
1459 ‘xlink:href’
1460 </span>
1461 </a>
1462 </li>
1463 </ul>
1464 </dd>
1465 <dt>
1466 DOM Interfaces:</dt>
1467 <dd>
1468 <ul class="no-bullets">
1469 <li>
1470 <a class="idlinterface" href="#InterfaceSVGFilterElement">
1471 SVGFilterElement</a>
1472 </li>
1473 </ul>
1474 </dd>
1475 </dl>
1476 </div>
1478 <p>
1479 The description of the <a>'filter element'</a> element
1480 follows:</p>
1482 <div class="adef-list">
1483 <p><em>Attribute definitions:</em></p>
1484 <dl>
1485 <dt id="FilterElementFilterUnitsAttribute"><span
1486 class="adef">filterUnits</span> = "<em>userSpaceOnUse</em> |
1487 <em>objectBoundingBox</em>"</dt>
1488 <dd>See <a>filter effects region</a>.</dd>
1489 <dt id="FilterElementPrimitiveUnitsAttribute"><span
1490 class="adef">primitiveUnits</span> = "<em>userSpaceOnUse</em> |
1491 <em>objectBoundingBox</em>"</dt>
1492 <dd>Specifies the coordinate system for the various length values within
1493 the <a>filter primitives</a> and for the attributes that define the <a>filter primitive subregion</a>.<br />
1494 If <span class='attr-value'>primitiveUnits="userSpaceOnUse"</span>, any length values
1495 within the filter definitions represent values in the <a href="#TermCurrentUserCoordinateSystem">current user
1496 coordinate system</a> in place at the time when the <a>'filter element'</a>
1497 element is referenced (i.e., the user coordinate system for the element
1498 referencing the <a>'filter element'</a> element via a <a>'filter property'</a>
1499 property).<br />
1500 If <span class='attr-value'>primitiveUnits="objectBoundingBox"</span>, then any length
1501 values within the filter definitions represent fractions or percentages
1502 of the bounding box on the referencing element (see <a href="#TermObjectBoundingBoxUnits">object bounding box
1503 units</a>). Note that if only one number was specified in a <a><number-optional-number></a> value
1504 this number is expanded out before the <a>'filter/primitiveUnits'</a> computation takes place.
1505 <br />
1506 The <a>lacuna value</a> for <a>'filter/primitiveUnits'</a> is <span class="attr-value">userSpaceOnUse</span>.<br />
1507 <span class="anim-target">Animatable: yes.</span></dd>
1508 <dt id="FilterElementXAttribute">
1509 <span class="adef">x</span> = "<em><a><coordinate></a></em>"</dt>
1510 <dd>See <a>filter effects region</a>.</dd>
1511 <dt id="FilterElementYAttribute">
1512 <span class="adef">y</span> = "<em><a><coordinate></a></em>"</dt>
1513 <dd>See <a>filter effects region</a>.</dd>
1514 <dt id="FilterElementWidthAttribute"><span class="adef">width</span> =
1515 "<em><a><length></a></em>"</dt>
1516 <dd>See <a>filter effects region</a>.</dd>
1517 <dt id="FilterElementHeightAttribute"><span class="adef">height</span> =
1518 "<em><a><length></a></em>"</dt>
1519 <dd>See <a>filter effects region</a>.</dd>
1520 <dt id="FilterElementFilterResAttribute"><span
1521 class="adef">filterRes</span> = "<em><a><number-optional-number></a></em>"
1522 </dt>
1523 <dd>See <a>filter effects region</a>.</dd>
1524 <dt id="FilterElementHrefAttribute"><span class="adef">xlink:href</span>
1525 = "<span class="attr-value"><IRI></span>"</dt>
1526 <dd>An <a>IRI reference</a>
1527 to another <a>'filter element'</a> element within
1528 the current <a>SVG document fragment</a>. Any attributes which are defined on
1529 the referenced <a>'filter element'</a> element which
1530 are not defined on this element are inherited by this element. If this
1531 element has no defined filter nodes, and the referenced element has
1532 defined filter nodes (possibly due to its own <span
1533 class="attr-name">href</span> attribute), then this element inherits
1534 the filter nodes defined from the referenced <a>'filter element'</a> element. Inheritance can be
1535 indirect to an arbitrary level; thus, if the referenced <a>'filter element'</a> element inherits attributes or its
1536 filter node specification due to its own <span
1537 class="attr-name">href</span> attribute, then the current element can
1538 inherit those attributes or filter node specifications.
1540 <div class="note">
1541 This attribute is deprecated and should not be used in new content, it's included for
1542 backwards compatibility reasons only.</div>
1543 <br />
1544 <span class="anim-target">Animatable: yes.</span></dd>
1545 </dl>
1546 </div>
1548 <p>
1549 Properties inherit into the <a>'filter element'</a>
1550 element from its ancestors; properties do <em>not</em> inherit from the
1551 element referencing the <a>'filter element'</a>
1552 element.</p>
1554 <p><a>'filter element'</a> elements are never rendered
1555 directly; their only usage is as something that can be referenced using the
1556 <a>'filter property'</a>
1557 property. The <a>'display'</a> property does not
1558 apply to the <a>'filter element'</a> element; thus, <a>'filter element'</a> elements are not directly rendered even
1559 if the <a>'display'</a> property is set to a value
1560 other than <span class="prop-value">none</span>, and <a>'filter element'</a> elements are available for referencing
1561 even when the <a>'display'</a> property on the <a>'filter element'</a> element or any of its ancestors is set
1562 to <span class="prop-value">none</span>.</p>
1563 <br />
1565 <h2 id="FilterEffectsRegion">Filter effects region</h2>
1567 <p>
1568 A <a>'filter element'</a>
1569 element can define a region on the canvas to which a given filter effect
1570 applies and can provide a resolution for any intermediate continuous tone
1571 images used to process any raster-based <a>filter primitives</a>.
1573 The <a>'filter element'</a>
1574 element has the following attributes which work together to define the filter
1575 effects region:</p>
1577 <dl class='definitions unemphasized-names'>
1578 <dt id="FilterUnitsAttribute"><a>'filterUnits'</a></dt>
1579 <dd>
1580 <p>
1581 Defines the coordinate system for attributes <a>'x'</a>, <a>'y'</a>,
1582 <a>'width'</a>, <a>'height'</a>.</p>
1584 <p>
1585 If <span class="attr-value">filterUnits="userSpaceOnUse"</span>, <a>'x'</a>, <a>'y'</a>,
1586 <a>'width'</a>, <a>'height'</a> represent values in the current user coordinate
1587 system in place at the time when the <a>'filter element'</a> element is referenced (i.e., the
1588 user coordinate system for the element referencing the <a>'filter element'</a>
1589 element via a <a>'filter property'</a> property).</p>
1591 <p>
1592 If <span class="attr-value">filterUnits="objectBoundingBox"</span>, then <a>'x'</a>, <a>'y'</a>,
1593 <a>'width'</a>, <a>'height'</a> represent fractions or percentages of the
1594 bounding box on the referencing element (see <a>object bounding box units</a>).</p>
1596 <p>
1597 The <a>lacuna value</a> for <a>'filterUnits'</a> is <span
1598 class="attr-value">objectBoundingBox</span>.</p>
1600 <p><span class="anim-target">Animatable: yes.</span></p>
1601 </dd>
1602 <dt id="FilterRegionXYWidthHeightAttributes"><a>'x'</a>, <a>'y'</a>, <a>'width'</a>, <a>'height'</a></dt>
1603 <dd>
1604 <p>
1605 These attributes define a rectangular region on the canvas to which this filter applies.</p>
1606 <p>
1607 The amount of memory and processing time required to apply the filter are
1608 related to the size of this rectangle and the <a>'filter/filterRes'</a> attribute of the filter.</p>
1609 <p>
1610 The coordinate system for these attributes depends on the value for attribute <a>'filterUnits'</a>.</p>
1611 <p>
1612 The bounds of this rectangle act as a hard clipping region for each <a>filter primitive</a>
1613 included with a given <a>'filter element'</a> element; thus, if the effect of
1614 a given filter primitive would extend beyond the bounds of the rectangle
1615 (this sometimes happens when using a <a>'feGaussianBlur'</a> filter primitive with a
1616 very large <a>'feGaussianBlur/stdDeviation'</a>), parts of the effect will get clipped.</p>
1618 <p>
1619 The <a>lacuna value</a> for <a>'x'</a> and <a>'y'</a> is <span class="attr-value">-10%</span>.</p>
1620 <p>
1621 The <a>lacuna value</a> for <a>'width'</a> and <a>'height'</a> is <span class="attr-value">120%</span>.</p>
1622 <p>
1623 Negative or zero values for <a>'width'</a> or <a>'height'</a> disable rendering of the element which
1624 referenced the filter. </p>
1626 <p><span class="anim-target">Animatable: yes.</span></p>
1627 </dd>
1629 <dt id="FilterRegionFilterRes"><a>'filter/filterRes'</a></dt>
1630 <dd>
1631 <p>
1632 Defines the width and height of the intermediate
1633 images in pixels. If not provided, then the user agent will use reasonable
1634 values to produce a high-quality result on the output device.</p>
1636 <p>
1637 Care should be taken when assigning a non-default value to this
1638 attribute. Too small of a value may result in unwanted pixelation in the
1639 result. Too large of a value may result in slow processing and large
1640 memory usage.</p>
1642 <p>
1643 Non-integer values are truncated, i.e rounded to the closest integer value towards zero.</p>
1645 <p><span class="requirement" id="assert_OORFilterRegion">Negative or zero values disable rendering of the element which referenced the filter.</span></p>
1646 <p><span class="anim-target">Animatable: yes.</span></p>
1647 </dd>
1648 </dl>
1650 <p>
1651 Note that both of the two possible value for <a>'filterUnits'</a> (i.e., <span
1652 class="attr-value">objectBoundingBox</span> and <span
1653 class="attr-value">userSpaceOnUse</span>) result in a <a>filter region</a> whose
1654 coordinate system has its X-axis and Y-axis each parallel to the X-axis and
1655 Y-axis, respectively, of the <a>user coordinate system</a> for the element to which
1656 the filter will be applied.</p>
1658 <p class="note implementation">Sometimes implementers can achieve faster performance when the filter
1659 region can be mapped directly to device pixels; thus, for best performance on
1660 display devices, it is suggested that authors define their region such that
1661 the user agent can align the <a>filter region</a> pixel-for-pixel with the
1662 background. In particular, for best filter effects performance, avoid
1663 rotating or skewing the user coordinate system. Explicit values for attribute
1664 <a>'filter/filterRes'</a> can either help or harm performance.
1665 If <a>'filter/filterRes'</a> is smaller than the automatic
1666 (i.e., default) filter resolution, then filter effect might have faster
1667 performance (usually at the expense of quality). If <a>'filter/filterRes'</a> is larger than the automatic (i.e.,
1668 default) filter resolution, then filter effects performance will usually be
1669 slower.</p>
1671 <p class="note authoring">It is often necessary to provide padding space because the filter effect
1672 might impact bits slightly outside the tight-fitting <a>'bounding box'</a> on a given
1673 object. For these purposes, it is possible to provide negative percentage
1674 values for <a>'x'</a>, <a>'y'</a> and percentages values greater than <span class="attr-value">100%</span> for
1675 <a>'width'</a>, <a>'height'</a>. This, for example, is why the defaults for
1676 the filter effects region are <span class="attr-value">x="-10%" y="-10%" width="120%"
1677 height="120%"</span>.</p>
1679 <h2 id="AccessBackgroundImage">Accessing the background image</h2>
1681 <p id="AccessingBackgroundImage">Two possible pseudo input images for filter effects are <a>BackgroundImage</a> and <a>BackgroundAlpha</a>, which each represent an image
1682 snapshot of the canvas under the <a>filter region</a> at the time that the <a
1683 href="#FilterElement"><span class="element-name">'filter'</span></a> element
1684 is invoked. <a>BackgroundImage</a> represents both
1685 the color values and alpha channel of the canvas (i.e., RGBA pixel values),
1686 whereas <a>BackgroundAlpha</a> represents only the
1687 alpha channel.</p>
1689 <p>
1690 Implementations <!--of SVG user agents often-->
1691 will often need to maintain supplemental background image buffers in order to
1692 support the <a>BackgroundImage</a> and <a>BackgroundAlpha</a> pseudo input images. Sometimes,
1693 the background image buffers will contain an in-memory copy of the
1694 accumulated painting operations on the current canvas.</p>
1696 <p>
1697 Because in-memory image buffers can take up significant system resources, <!--SVG-->
1698 content must explicitly indicate to the <!--SVG-->
1699 user agent that the document needs access to the background image before <a>BackgroundImage</a> and <a>BackgroundAlpha</a> pseudo input images can be used.
1700 </p>
1702 A background image is what's been <i>rendered before</i> the current element.
1703 <edit:hostreq>The host language is responsible for defining what <i>rendered before</i> in
1704 this context means
1705 .</edit:hostreq> For SVG, that uses the painter's algorithm, <i>rendered before</i> means
1706 all of the prior elements in pre order traversal previous to the element to
1707 which the filter is applied.
1709 <p>
1710 The property which enables access to the background image is
1711 <a>'enable-background'</a>:</p>
1714 <div class="propdef">
1715 <dl>
1716 <dt id="EnableBackgroundProperty"><span class='propdef-title prop-name'>'enable-background'</span></dt>
1717 <dd>
1718 <table summary="enable-background property" class="propinfo"
1719 cellspacing="0" cellpadding="0">
1720 <tbody>
1721 <tr valign="baseline">
1722 <td><em>Value:</em> </td>
1723 <td>accumulate | new | <a class="noxref"
1724 href="http://www.w3.org/TR/2009/CR-CSS2-20090423/cascade.html#value-def-inherit"><span
1725 class="value-inst-inherit noxref">inherit</span></a></td>
1726 </tr>
1727 <tr valign="baseline">
1728 <td><em>Initial:</em> </td>
1729 <td>accumulate</td>
1730 </tr>
1731 <tr valign="baseline">
1732 <td><em>Applies to:</em> </td>
1733 <td>Typically elements that can contain renderable elements.
1734 language is responsible for defining the applicable set of
1735 elements.
1736 For SVG: <a>container elements</a></td>
1737 </tr>
1738 <tr valign="baseline">
1739 <td><em>Inherited:</em> </td>
1740 <td>no</td>
1741 </tr>
1742 <tr valign="baseline">
1743 <td><em>Percentages:</em> </td>
1744 <td>N/A</td>
1745 </tr>
1746 <tr valign="baseline">
1747 <td><em>Media:</em> </td>
1748 <td>visual</td>
1749 </tr>
1750 <tr valign="baseline">
1751 <td><em>Animatable:</em> </td>
1752 <td>no</td>
1753 </tr>
1754 </tbody>
1755 </table>
1756 </dd>
1757 </dl>
1758 </div>
1759 <p><a>'enable-background'</a> is only
1760 applicable to <a>container elements</a>
1761 and specifies how the <a>SVG user agent</a> manages the accumulation
1762 of the background image.</p>
1764 <p>
1765 A value of <strong>new</strong> indicates two things:</p>
1766 <ul>
1767 <li>It enables the ability of children of the current <a>container element</a>
1768 element to access the background image.</li>
1769 <li>It indicates that a new (i.e., initially transparent black) background
1770 image canvas is established and that (in effect) all children of the
1771 current <a>container element</a>
1772 element shall be rendered into the new background image canvas in
1773 addition to being rendered onto the target device.</li>
1774 </ul>
1776 <p>
1777 A meaning of <span class="attr-value">enable-background: accumulate</span> (the
1778 initial/default value) depends on context:</p>
1779 <ul>
1780 <li>If an ancestor <a>container element</a>
1781 element has a property value of <span class="attr-value">'enable-background:new'</span>, then all
1782 renderable child elements of the current <a>container element</a>
1783 element are rendered both onto the parent <a>container element</a>
1784 element's background image canvas and onto the target device.</li>
1785 <li>Otherwise, there is no current background image canvas, so it is only
1786 necessary to render <a>graphics elements</a>
1787 the renderable elements onto the target device. (No need to render to the
1788 background image canvas.)</li>
1789 </ul>
1791 <p>
1792 If a filter effect specifies either the <a>BackgroundImage</a> or the
1793 <a>BackgroundAlpha</a> pseudo input images and no
1794 ancestor <a>container element</a>
1795 element has a property value of <span class="attr-value">'enable-background:new'</span>, then the background
1796 image request is technically in error. Processing will proceed without
1797 interruption (i.e., no error message) and a transparent black image shall be
1798 provided in response to the request.</p>
1800 <h3 id="AccessBackgroundImageSVG">Accessing the background image in SVG</h3>
1801 <p>
1802 This section only applies to the SVG definition of enable-background.</p>
1804 <p>
1805 Assume you have an element E in the document and that E has a series of
1806 ancestors A<sub>1</sub> (its immediate parent), A<sub>2</sub>, etc. (Note:
1807 A<sub>0</sub> is E.) Each ancestor A<sub>i</sub> will have a corresponding
1808 temporary background image offscreen buffer BUF<sub>i</sub>. The contents of
1809 the <em>background image</em> available to a <a href="#FilterElement"><span
1810 class="element-name">'filter'</span></a> referenced by E is defined as
1811 follows:</p>
1812 <ul>
1813 <li>Find the element A<sub>i</sub> with the smallest subscript i (including
1814 A<sub>0</sub>=E) for which the <a href="#EnableBackgroundProperty"><span
1815 class="prop-name">'enable-background'</span></a> property has the value
1816 <span class="prop-value">new</span>. (Note: if there is no such ancestor
1817 element, then there is no background image available to E, in which case
1818 a transparent black image will be used as E's background image.)</li>
1819 <li>For each A<sub>i</sub> (from i=n to 1), initialize BUF<sub>i</sub> to
1820 transparent black. Render all children of A<sub>i</sub> up to but not
1821 including A<sub>i-1</sub> into BUF<sub>i</sub>. The children are painted,
1822 then filtered, clipped, masked and composited using the various painting,
1823 filtering, clipping, masking and object opacity settings on the given
1824 child. Any filter effects, masking and group opacity that might be set on
1825 A<sub>i</sub> do <em>not</em> apply when rendering the children of
1826 A<sub>i</sub> into BUF<sub>i</sub>.<br />
1827 (Note that for the case of A<sub>0</sub>=E, the graphical contents of E
1828 are not rendered into BUF<sub>1</sub> and thus are not part of the
1829 background image available to E. Instead, the graphical contents of E are
1830 available via the <a href="#SourceGraphic">SourceGraphic</a> and <a
1831 href="#SourceAlpha">SourceAlpha</a> pseudo input images.)</li>
1832 <li>Then, for each A<sub>i</sub> (from i=1 to n-1), composite
1833 BUF<sub>i</sub> into BUF<sub>i+1</sub>.</li>
1834 <li>The accumulated result (i.e., BUF<sub>n</sub>) represents the
1835 background image available to E.</li>
1836 </ul>
1838 <edit:example href="examples/enable-background-01.svg" image="yes" link="yes"/>
1840 <p>
1841 The example above contains five parts, described as follows:</p>
1842 <ol>
1843 <li>The first set is the reference graphic. The reference graphic consists
1844 of a red rectangle followed by a 50% transparent <span
1845 class="element-name">'g'</span>
1846 element. Inside the <span class="element-name">'g'</span>
1847 is a green circle that partially overlaps the rectangle and a a blue
1848 triangle that partially overlaps the circle. The three objects are then
1849 outlined by a rectangle stroked with a thin blue line. No filters are
1850 applied to the reference graphic.</li>
1851 <li>The second set enables background image processing and adds an empty
1852 <span class="element-name">'g'</span>
1853 element which invokes the ShiftBGAndBlur filter. This filter takes the
1854 current accumulated background image (i.e., the entire reference graphic)
1855 as input, shifts its offscreen down, blurs it, and then writes the result
1856 to the canvas. Note that the offscreen for the filter is initialized to
1857 transparent black, which allows the already rendered rectangle, circle
1858 and triangle to show through after the filter renders its own result to
1859 the canvas.</li>
1860 <li>The third set enables background image processing and instead invokes
1861 the ShiftBGAndBlur filter on the inner <span
1862 class="element-name">'g'</span>
1863 element. The accumulated background at the time the filter is applied
1864 contains only the red rectangle. Because the children of the inner <span
1865 class="element-name">'g'</span>
1866 (i.e., the circle and triangle) are not part of the inner <span
1867 class="element-name">'g'</span>
1868 element's background and because ShiftBGAndBlur ignores SourceGraphic,
1869 the children of the inner <span class="element-name">'g'</span>
1870 do not appear in the result.</li>
1871 <li>The fourth set enables background image processing and invokes the
1872 ShiftBGAndBlur on the <span class="element-name">'polygon'</span>
1873 element that draws the triangle. The accumulated background at the time
1874 the filter is applied contains the red rectangle plus the green circle
1875 ignoring the effect of the <span class="prop-name">'opacity'</span>
1876 property on the inner <span class="element-name">'g'</span>
1877 element. (Note that the blurred green circle at the bottom does not let
1878 the red rectangle show through on its left side. This is due to ignoring
1879 the effect of the <span class="prop-name">'opacity'</span>
1880 property.) Because the triangle itself is not part of the accumulated
1881 background and because ShiftBGAndBlur ignores SourceGraphic, the triangle
1882 does not appear in the result.</li>
1883 <li>The fifth set is the same as the fourth except that filter
1884 ShiftBGAndBlur_WithSourceGraphic is invoked instead of ShiftBGAndBlur.
1885 ShiftBGAndBlur_WithSourceGraphic performs the same effect as
1886 ShiftBGAndBlur, but then renders the SourceGraphic on top of the shifted,
1887 blurred background image. In this case, SourceGraphic is the blue
1888 triangle; thus, the result is the same as in the fourth case except that
1889 the blue triangle now appears.</li>
1890 </ol>
1891 </edit:with>
1893 <h2 id="FilterPrimitivesOverview">Filter primitives overview</h2>
1895 <h3 id="FilterPrimitivesOverviewIntro">Overview</h3>
1897 <p>
1898 This section describes the various filter primtives that can be assembled
1899 to achieve a particular filter effect.</p>
1901 <p>
1902 Unless otherwise stated, all image filters operate on premultiplied RGBA
1903 samples. Filters which work more naturally on non-premultiplied data
1904 (<a>'feColorMatrix'</a> and <a>'feComponentTransfer'</a>) will temporarily undo and redo
1905 premultiplication as specified. All raster effect filtering operations take 1
1906 to N input RGBA images, additional attributes as parameters, and produce a
1907 single output RGBA image.</p>
1909 <p>
1910 The RGBA result from each filter primitive will be clamped into the
1911 allowable ranges for colors and opacity values. Thus, for example, the result
1912 from a given <a>filter primitive</a> will have any negative color values or opacity
1913 values adjusted up to color/opacity of zero.</p>
1915 <p id="filtersColorSpace">The color space in which a particular <a>filter primitive</a> performs its
1916 operations is determined by the value of property <a>'color-interpolation-filters'</a> on the given <a>filter
1917 primitive</a>. A different property, <a>'color-interpolation'</a> determines the color space for
1918 other color operations. Because these two properties have different initial
1919 values (<a>'color-interpolation-filters'</a> has an
1920 initial value of <span class="prop-value">linearRGB</span> whereas <a>'color-interpolation'</a> has an initial value of <span class="prop-value">sRGB</span>), in some cases to achieve certain results
1921 (e.g., when coordinating gradient interpolation with a filtering operation)
1922 it will be necessary to explicitly set <a>'color-interpolation'</a> to <span
1923 class="prop-value">linearRGB</span> or <a>'color-interpolation-filters'</a> to <span
1924 class="prop-value">sRGB</span> on particular elements. Note that the examples
1925 below do not explicitly set either <a>'color-interpolation'</a> or <a>'color-interpolation-filters'</a>, so the initial values for these properties apply to the examples.</p>
1927 <p><span class="requirement" id="assert_undefinedPixels">Sometimes <a>filter primitives</a> result in undefined pixels. For example,
1928 filter primitive <a>'feOffset'</a> can shift an image down and to the
1929 right, leaving undefined pixels at the top and left. In these cases, the
1930 undefined pixels are set to transparent black.</span></p>
1932 <h3 id="CommonAttributes">Common attributes</h3>
1934 <p>
1935 The following attributes are available for most of the filter
1936 primitives:</p>
1938 <div class="adef-list">
1939 <p><em>Attribute definitions:</em></p>
1940 <dl>
1941 <dt id="FilterPrimitiveXAttribute">
1942 <span class="adef">x</span> = "<em><a><coordinate></a></em>"</dt>
1943 <dd><p>
1944 The minimum x coordinate for the subregion which restricts
1945 calculation and rendering of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.</p>
1946 <p>
1947 The <a>lacuna value</a> for <span class="attr-name">x</span> is <span class="attr-value">0%</span>.</p>
1948 <p><span class="anim-target">Animatable: yes.</span></p>
1949 </dd>
1950 <dt id="FilterPrimitiveYAttribute">
1951 <span class="adef">y</span> = "<em><a><coordinate></a></em>"</dt>
1952 <dd><p>
1953 The minimum y coordinate for the subregion which restricts
1954 calculation and rendering of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>. </p>
1955 <p>
1956 The <a>lacuna value</a> for <span class="attr-name">y</span> is <span class="attr-value">0%</span>.</p>
1957 <p><span class="anim-target">Animatable: yes.</span></p>
1958 </dd>
1959 <dt id="FilterPrimitiveWidthAttribute">
1960 <span class="adef">width</span> = "<em><a><length></a></em>"</dt>
1961 <dd><p>
1962 The width of the subregion which restricts calculation and rendering
1963 of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.</p>
1964 <p>
1965 A negative or zero value disables the effect of the given filter
1966 primitive (i.e., the result is a transparent black image).</p>
1967 <p>
1968 The <a>lacuna value</a> for <span class="attr-name">width</span> is <span class="attr-value">100%</span>.</p>
1969 <p><span class="anim-target">Animatable: yes.</span></p>
1970 </dd>
1971 <dt id="FilterPrimitiveHeightAttribute">
1972 <span class="adef">height</span> = "<em><a><length></a></em>"</dt>
1973 <dd><p>
1974 The height of the subregion which restricts calculation and rendering
1975 of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.</p>
1976 <p>
1977 A negative or zero value disables the effect of the given filter
1978 primitive (i.e., the result is a transparent black image).</p>
1979 <p>
1980 The <a>lacuna value</a> for <span class="attr-name">height</span> is <span class="attr-value">100%</span>.</p>
1981 <p><span class="anim-target">Animatable: yes.</span></p>
1982 </dd>
1983 <dt id="FilterPrimitiveResultAttribute">
1984 <span class="adef">result</span> =
1985 "<em><a><filter-primitive-reference></a></em>"</dt>
1986 <dd><p>
1987 Assigned name for this <a>filter primitive</a>. If supplied, then graphics
1988 that result from processing this <a>filter primitive</a> can be referenced by
1989 an <a>'in'</a> attribute on a subsequent filter
1990 primitive within the same <a>'filter element'</a> element. If no value is
1991 provided, the output will only be available for re-use as the implicit
1992 input into the next <a>filter primitive</a> if that <a>filter primitive</a> provides
1993 no value for its <a>'in'</a> attribute.</p>
1994 <p>
1995 Note that a <a><filter-primitive-reference></a> is not an XML
1996 ID; instead, a <a><filter-primitive-reference></a> is only
1997 meaningful within a given <a>'filter element'</a> element and thus have only
1998 local scope. It is legal for the same
1999 <a><filter-primitive-reference></a> to appear multiple times
2000 within the same <a>'filter element'</a> element. When referenced, the
2001 <a><filter-primitive-reference></a> will use the closest
2002 preceding <a>filter primitive</a> with the given result.</p>
2003 <p><span class="anim-target">Animatable: yes.</span></p>
2004 </dd>
2005 <dt id="FilterPrimitiveInAttribute">
2006 <span class="adef">in</span> = "<em><a>SourceGraphic</a> | <a>SourceAlpha</a> | <a>BackgroundImage</a> | <a>BackgroundAlpha</a> | <a>FillPaint</a> | <a>StrokePaint</a> |
2007 <a><filter-primitive-reference></a></em>"</dt>
2008 <dd><p>
2009 Identifies input for the given filter primitive. The value can be
2010 either one of six keywords or can be a string which matches a previous
2011 <a>'feBlend/result'</a> attribute value within the same <a>'filter element'</a>
2012 element. If no value is provided and this is the first <a>filter primitive</a>,
2013 then this <a>filter primitive</a> will use <a>SourceGraphic</a>
2014 as its input. If no value is provided and this is a subsequent <a>filter primitive</a>,
2015 then this <a>filter primitive</a> will use the result from the
2016 previous <a>filter primitive</a> as its input.</p>
2017 <p>
2018 If the value for <span class="attr-name">result</span> appears
2019 multiple times within a given <a>'filter element'</a> element, then a reference to
2020 that result will use the closest preceding <a>filter primitive</a> with the
2021 given value for attribute <a>'feBlend/result'</a>.
2022 Forward references to results are not allowed, and will be treated as
2023 if no result was specified. </p>
2024 <p>
2025 Definitions for the six keywords: </p>
2026 <dl>
2027 <dt id="SourceGraphic"><span class="attr-value">SourceGraphic</span></dt>
2028 <dd><p>
2029 This keyword represents the graphics elements
2030 that were the original input into the <a>'filter element'</a> element. For raster
2031 effects <a>filter primitives</a>, the graphics elements
2032 will be rasterized into an initially clear RGBA raster in image
2033 space. Pixels left untouched by the original graphic will be left
2034 clear. The image is specified to be rendered in linear RGBA
2035 pixels. The alpha channel of this image captures any
2036 anti-aliasing specified by SVG. (Since the raster is linear, the
2037 alpha channel of this image will represent the exact percent
2038 coverage of each pixel.)</p></dd>
2039 <dt id="SourceAlpha"><span class="attr-value">SourceAlpha</span></dt>
2040 <dd><p>
2041 This keyword represents the graphics elements
2042 that were the original input into the <a>'filter element'</a> element.
2043 <a>SourceAlpha</a> has all of the same rules
2044 as <a>SourceGraphic</a> except that only the
2045 alpha channel is used. The input image is an RGBA image
2046 consisting of implicitly black color values for the RGB channels,
2047 but whose alpha channel is the same as <a>SourceGraphic</a>.</p>
2048 <p class="note implementation">If this option is
2049 used, then some implementations might need to rasterize the
2050 graphics elements
2051 in order to extract the alpha channel.</p>
2052 </dd>
2053 <dt id="BackgroundImage"><span class="attr-value">BackgroundImage</span></dt>
2054 <dd><p>
2055 This keyword represents an image snapshot of the canvas under
2056 the <a>filter region</a> at the time that the <a>'filter element'</a> element was invoked. See
2057 <a href="#AccessingBackgroundImage">accessing the background
2058 image</a>.</p>
2059 </dd>
2060 <dt id="BackgroundAlpha"><span class="attr-value">BackgroundAlpha</span></dt>
2061 <dd><p>
2062 Same as <a>BackgroundImage</a> except
2063 only the alpha channel is used. See <a>SourceAlpha</a> and <a
2064 href="#AccessingBackgroundImage">accessing the background
2065 image</a>.</p>
2066 </dd>
2068 <dt id="FillPaint"><span class="attr-value">FillPaint</span></dt>
2069 <dd>
2070 <p>
2071 This keyword represents the target element <i>rendered filled</i>.</p>
2072 <p>
2073 For svg this keyword represents the value of the <a>'fill'</a>
2074 property on the target element for the filter effect.</p>
2075 <p>
2076 For non-SVG cases <a>FillPaint</a> generates a transparent black image.
2077 <span class="specissue">ISSUE: Consider whether this should be e.g the CSS bounding box filled with the current color, or if it makes sense to use the 'fill' property for this case too.</span>
2078 </p>
2079 <p class="note authoring">Note that text is generally painted filled, not stroked.</p>
2080 <p>
2081 The <a>FillPaint</a> image has conceptually infinite extent.
2082 Frequently this image is opaque everywhere, but it might not be if the "paint"
2083 itself has alpha, as in the case of a gradient or pattern which
2084 itself includes transparent or semi-transparent parts.</p>
2085 </dd>
2086 <dt id="StrokePaint"><span class="attr-value">StrokePaint</span></dt>
2087 <dd>
2088 <p>
2089 This keyword represents the target element <i>rendered stroked</i>.</p>
2090 <p>
2091 For svg this keyword represents the value of the <a>'stroke'</a>
2092 on the target element for the filter effect.</p>
2093 <p>
2094 For non-SVG cases <a>StrokePaint</a> generates a transparent black image.
2095 <span class="specissue">ISSUE: Consider whether this should be e.g the CSS bounding box filled with the one of the border colors, or if it makes sense to use the 'stroke' property for this case too.</span>
2096 </p>
2097 <p class="note authoring">Note that text is generally painted filled, not stroked.</p>
2098 <p>
2099 The <a>StrokePaint</a> image has conceptually infinite extent.
2100 Frequently this image is opaque everywhere, but it
2101 might not be if the "paint"
2102 itself has alpha, as in the case of a gradient or pattern which
2103 itself includes transparent or semi-transparent parts.
2104 </p>
2105 </dd>
2106 </dl>
2107 <p><span class="anim-target">Animatable: yes.</span></p>
2108 </dd>
2109 </dl>
2110 </div>
2112 <h3 id="FilterPrimitiveSubRegion">Filter primitive subregion</h3>
2114 <p class="todo">Merge <a href="">CSS shaders <a href="https://dvcs.w3.org/hg/FXTF/raw-file/tip/custom/index.html#shader-model">processing model</p> with
2115 this section or the filter regions section.</p>
2117 <edit:with element="feBlend">
2118 <p>
2119 All <a>filter primitives</a> have attributes <a>'x'</a>, <a>'y'</a>,
2120 <a>'width'</a> and <a>'height'</a> which
2121 together identify a subregion which restricts calculation and rendering of
2122 the given <a>filter primitive</a>. The <a>'x'</a>, <a>'y'</a>,
2123 <a>'width'</a> and <a>'height'</a> attributes are defined
2124 according to the same rules as other <a>filter primitives</a>' coordinate and length
2125 attributes and thus represent values in the coordinate system established by
2126 attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a> element.
2127 </p>
2129 <p><a>'x'</a>, <a>'y'</a>,
2130 <a>'width'</a> and <a>'height'</a> default to the union (i.e., tightest fitting bounding
2131 box) of the subregions defined for all referenced nodes. If there are no
2132 referenced nodes (e.g., for <a>'feImage'</a> or <a>'feTurbulence'</a>), or one or more of the
2133 referenced nodes is a standard input (one of <a>SourceGraphic</a>, <a>SourceAlpha</a>, <a>BackgroundImage</a>, <a>BackgroundAlpha</a>,
2134 <a href="#FillPaint"><span class="attr-value">FillPaint</span></a> or <a
2135 href="#StrokePaint"><span class="attr-value">StrokePaint</span></a>), or for
2136 <a href="#feTileElement"><span class="element-name">'feTile'</span></a>
2137 (which is special because its principal function is to replicate the
2138 referenced node in X and Y and thereby produce a usually larger result), the
2139 default subregion is <span class="attr-value">0%, 0%, 100%, 100%</span>,
2140 where as a special-case the percentages are relative to the dimensions of the <a>filter region</a>,
2141 thus making the default <a>filter primitive subregion</a> equal to the <a>filter region</a>.
2142 </p>
2144 <p>
2145 If the <a>filter primitive
2146 subregion</a> has a negative or zero width or height, the effect of the filter
2147 primitive is disabled. </p>
2149 <p>
2150 The <a>filter primitive subregion</a> act as a hard clip clipping rectangle on both the
2151 filter primitive's input image(s) and the filter primitive result.</p>
2152 <p class="specissue">ISSUE: Consider making it possible to do select between clip-input, clip-output, clip-both or none.</p>
2154 <p>
2155 All intermediate offscreens are defined to not exceed the intersection of
2156 the <a>filter primitive subregion</a> with the <a>filter region</a>.
2157 The <a>filter region</a> and any of the filter primitive subregions are
2158 to be set up such that all offscreens are made big enough to accommodate any
2159 pixels which even partly intersect with either the <a>filter region</a> or the
2160 filter primitive subregions.</p>
2162 <p><a>'feTile'</a> references a previous filter primitive and then stitches the tiles together
2163 based on the <a>filter primitive subregion</a> of the referenced filter primitive in
2164 order to fill its own <a>filter primitive subregion</a>.</p>
2166 <edit:example href="examples/filtersubregion00.svg" image="yes" link="yes"/>
2168 <p>
2169 In the example above there are three rects that each have a cross and a circle in them.
2171 The circle element in each one has a different filter applied, but with the same <a>filter primitive subregion</a>.
2172 The filter output should be limited to the <a>filter primitive subregion</a>, so you should never see the circles
2173 themselves, just the rects that make up the <a>filter primitive subregion</a>.
2174 </p>
2175 <ul>
2176 <li>
2177 The upper left rect shows an <a>'feFlood'</a> with <span class="attr-name">flood-opacity</span>="<span class="attr-value">75%</span>" so the cross should be visible through the green rect in the middle.
2178 </li>
2179 <li>
2180 The lower left rect shows an <a>'feMerge'</a> that merges <a>SourceGraphic</a> with <a>FillPaint</a>. Since the circle has <span class="attr-name">fill-opacity</span>="<span class="attr-value">0.5</span>" it will also be transparent so that the cross is visible through the green rect in the middle.
2181 </li>
2182 <li>The upper right rect shows an <a>'feBlend'</a> that has <span class="attr-name">mode</span>="<span class="attr-value">multiply</span>". Since the circle in this case isn't transparent the result is totally opaque. The rect should be dark green and the cross should not be visible through it.
2183 </li>
2184 </ul>
2186 </edit:with>
2188 <h2 id="LightSourceDefinitions">Light source elements and properties</h2>
2190 <h3 id="LightSourceIntro">Introduction</h3>
2192 <p>
2193 The following sections define the elements that define a light source, <a>'feDistantLight'</a>,
2194 <a>'fePointLight'</a> and <a>'feSpotLight'</a>,
2195 and property <a>'lighting-color'</a>, which defines the color of the
2196 light.</p>
2198 <h3 id="feDistantLightElement">Light source <span class="element-name">'feDistantLight'</span></h3>
2200 <edit:elementsummary name='feDistantLight'/>
2201 <edit:with element='feDistantLight'>
2203 <div class="adef-list">
2204 <p><em>Attribute definitions:</em></p>
2205 <dl>
2206 <dt id="feDistantLightAzimuthAttribute"><span
2207 class="adef">azimuth</span> = "<em><a><number></a></em>"</dt>
2208 <dd>Direction angle for the light source on the XY plane (clockwise), in
2209 degrees from the x axis.<br />
2210 The <a>lacuna value</a> for <a>'azimuth'</a> is <span class="attr-value">0</span>.<br />
2211 <span class="anim-target">Animatable: yes.</span></dd>
2212 <dt id="feDistantLightElevationAttribute"><span
2213 class="adef">elevation</span> = "<em><a><number></a></em>"</dt>
2214 <dd>Direction angle for the light source from the XY plane towards the Z-axis, in degrees.
2215 Note that the positive Z-axis points towards the viewer.<br />
2216 The <a>lacuna value</a> for <a>'elevation'</a> is <span class="attr-value">0</span>.<br />
2217 <span class="anim-target">Animatable: yes.</span></dd>
2218 </dl>
2219 </div>
2221 <p>
2222 The following diagram illustrates the angles which <a>'azimuth'</a>
2223 and <a>'elevation'</a> represent in an XYZ coordinate system.
2224 </p>
2225 <img src="examples/azimuth-elevation.png" alt="Angles which azimuth and elevation represent" width="480" height="360" />
2226 </edit:with>
2228 <h3 id="fePointLightElement">Light source <span class="element-name">'fePointLight'</span></h3>
2230 <edit:elementsummary name='fePointLight'/>
2232 <div class="adef-list">
2233 <p><em>Attribute definitions:</em></p>
2234 <dl>
2235 <dt id="fePointLightXAttribute"><span
2236 class="adef">x</span> = "<em><a><number></a></em>"</dt>
2237 <dd>X location for the light source in the coordinate system established
2238 by attribute <a>'filter/primitiveUnits'</a> on the <a
2239 href="#FilterElement"><span class="element-name">'filter'</span></a>
2240 element.<br />
2241 The <a>lacuna value</a> for <a>'fePointLight/x'</a> is <span class="attr-value">0</span>.<br />
2242 <span class="anim-target">Animatable: yes.</span></dd>
2243 <dt id="fePointLightYAttribute"><span
2244 class="adef">y</span> = "<em><a><number></a></em>"</dt>
2245 <dd>Y location for the light source in the coordinate system established
2246 by attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
2247 element.<br />
2248 The <a>lacuna value</a> for <a>'fePointLight/y'</a> is <span class="attr-value">0</span>.<br />
2249 <span class="anim-target">Animatable: yes.</span></dd>
2250 <dt id="fePointLightZAttribute"><span
2251 class="adef">z</span> = "<em><a><number></a></em>"</dt>
2252 <dd>Z location for the light source in the coordinate system established
2253 by attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
2254 element, assuming that, in the <a>initial coordinate system</a>
2255 , the positive Z-axis comes out towards the person viewing the content
2256 and assuming that one unit along the Z-axis equals <a href="http://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage">one unit in X and Y</a>.<br />
2257 The <a>lacuna value</a> for <a>'fePointLight/z'</a> is <span class="attr-value">0</span>.<br />
2258 <span class="anim-target">Animatable: yes.</span></dd>
2259 </dl>
2260 </div>
2262 <h3 id="feSpotLightElement">Light source <span class="element-name">'feSpotLight'</span></h3>
2264 <edit:elementsummary name='feSpotLight'/>
2265 <edit:with element='feSpotLight'>
2267 <div class="adef-list">
2268 <p><em>Attribute definitions:</em></p>
2269 <dl>
2270 <dt id="feSpotLightXAttribute"><span
2271 class="adef">x</span> = "<em><a><number></a></em>"</dt>
2272 <dd>X location for the light source in the coordinate system established
2273 by attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
2274 element.<br />
2275 The <a>lacuna value</a> for <a>'feSpotLight/x'</a> is <span class="attr-value">0</span>.<br />
2276 <span class="anim-target">Animatable: yes.</span></dd>
2277 <dt id="feSpotLightYAttribute"><span
2278 class="adef">y</span> = "<em><a><number></a></em>"</dt>
2279 <dd>Y location for the light source in the coordinate system established
2280 by attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
2281 element.<br />
2282 The <a>lacuna value</a> for <a>'feSpotLight/y'</a> is <span class="attr-value">0</span>.<br />
2283 <span class="anim-target">Animatable: yes.</span></dd>
2284 <dt id="feSpotLightZAttribute"><span
2285 class="adef">z</span> = "<em><a><number></a></em>"</dt>
2286 <dd>Z location for the light source in the coordinate system established
2287 by attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
2288 element, assuming that, in the <a>initial coordinate system</a>
2289 , the positive Z-axis comes out towards the person viewing the content
2290 and assuming that one unit along the Z-axis equals <a href="http://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage">one unit in X and Y</a>.<br />
2291 The <a>lacuna value</a> for <a>'feSpotLight/z'</a> is <span class="attr-value">0</span>.<br />
2292 <span class="anim-target">Animatable: yes.</span></dd>
2293 <dt id="feSpotLightPointsAtXAttribute"><span
2294 class="adef">pointsAtX</span> = "<em><a><number></a></em>"</dt>
2295 <dd>X location in the coordinate system established by attribute <a>'filter/primitiveUnits'</a>
2296 on the <a>'filter element'</a>
2297 element of the point at which the light source is pointing.<br />
2298 The <a>lacuna value</a> for <a>'pointsAtX'</a> is <span class="attr-value">0</span>.<br />
2299 <span class="anim-target">Animatable: yes.</span></dd>
2300 <dt id="feSpotLightPointsAtYAttribute"><span
2301 class="adef">pointsAtY</span> = "<em><a><number></a></em>"</dt>
2302 <dd>Y location in the coordinate system established by attribute <a>'filter/primitiveUnits'</a>
2303 on the <a>'filter element'</a> element of the point at which the light source is pointing.<br />
2304 The <a>lacuna value</a> for <a>'pointsAtY'</a> is <span class="attr-value">0</span>.<br />
2305 <span class="anim-target">Animatable: yes.</span></dd>
2306 <dt id="feSpotLightPointsAtZAttribute"><span
2307 class="adef">pointsAtZ</span> = "<em><a><number></a></em>"</dt>
2308 <dd>Z location in the coordinate system established by the
2309 attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a> element of
2310 the point at which the light source is pointing, assuming that, in the
2311 <a>initial coordinate system</a>, the positive Z-axis comes out
2312 towards the person viewing the content and assuming that
2313 one unit along the Z-axis equals
2314 <a href="http://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage">
2315 one unit in X and Y</a>.<br />
2316 The <a>lacuna value</a> for <a>'pointsAtZ'</a> is <span class="attr-value">0</span>.<br />
2317 <span class="anim-target">Animatable: yes.</span></dd>
2318 <dt id="feSpotLightSpecularExponentAttribute"><span
2319 class="adef">specularExponent</span> = "<em><a><number></a></em>"</dt>
2320 <dd>Exponent value controlling the focus for the light source.<br />
2321 The <a>lacuna value</a> for <a>'specularExponent'</a> is <span class="attr-value">1</span>.<br />
2322 <span class="anim-target">Animatable: yes.</span></dd>
2323 <dt id="feSpotLightLimitingConeAngleAttribute"><span
2324 class="adef">limitingConeAngle</span> = "<em><a><number></a></em>"</dt>
2325 <dd>A limiting cone which restricts the region where the light is
2326 projected. No light is projected outside the cone. <span
2327 class="attr-name">limitingConeAngle</span> represents the angle in degrees between
2328 the spot light axis (i.e. the axis between the light source and the
2329 point to which it is pointing at) and the spot light cone. <span class="requirement" id="assert_userAgentLightingConeSmoothing">User agents
2330 should apply a smoothing technique such as anti-aliasing at the
2331 boundary of the cone.</span><br />
2332 If no value is specified, then no limiting cone will be applied.<br />
2333 <span class="anim-target">Animatable: yes.</span></dd>
2334 </dl>
2335 </div>
2336 </edit:with>
2338 <h3 id="LightingColorProperty">The <span class="prop-name">'lighting-color'</span> property</h3>
2340 <p>
2341 The <a>'lighting-color'</a> property defines the
2342 color of the light source for <a>filter primitives</a> <a>'feDiffuseLighting'</a> and <a>'feSpecularLighting'</a>.</p>
2344 <div class="propdef">
2345 <dl>
2346 <dt><span class="index-def" title="'margin-top'"><a
2347 id="propdef-lighting-color" name="propdef-lighting-color"
2348 class="propdef-title"><span
2349 class="prop-name">'lighting-color'</span></a></span></dt>
2350 <dd>
2351 <table summary="lighting-color property" class="propinfo"
2352 cellspacing="0" cellpadding="0">
2353 <tbody>
2354 <tr valign="baseline">
2355 <td><em>Value:</em> </td>
2356 <td>currentColor |<br />
2357 <a><color></a>
2358 [<a><icccolor></a>] |<br />
2359 <a class="noxref"
2360 href="http://www.w3.org/TR/2009/CR-CSS2-20090423/cascade.html#value-def-inherit"><span
2361 class="value-inst-inherit noxref">inherit</span></a></td>
2362 </tr>
2363 <tr valign="baseline">
2364 <td><em>Initial:</em> </td>
2365 <td>white</td>
2366 </tr>
2367 <tr valign="baseline">
2368 <td><em>Applies to:</em> </td>
2369 <td><a>'feDiffuseLighting'</a> and <a>'feSpecularLighting'</a>
2370 elements</td>
2371 </tr>
2372 <tr valign="baseline">
2373 <td><em>Inherited:</em> </td>
2374 <td>no</td>
2375 </tr>
2376 <tr valign="baseline">
2377 <td><em>Percentages:</em> </td>
2378 <td>N/A</td>
2379 </tr>
2380 <tr valign="baseline">
2381 <td><em>Media:</em> </td>
2382 <td>visual</td>
2383 </tr>
2384 <tr valign="baseline">
2385 <td><em>Animatable:</em> </td>
2386 <td>yes</td>
2387 </tr>
2388 </tbody>
2389 </table>
2390 </dd>
2391 </dl>
2392 </div>
2394 <h2 id="feBlendElement">Filter primitive <span class="element-name">'feBlend'</span></h2>
2396 <edit:elementsummary name='feBlend'/>
2397 <edit:with element='feBlend'>
2399 <p>
2400 This filter composites two objects together using commonly used imaging
2401 software blending modes. It performs a pixel-wise combination of two input
2402 images.</p>
2404 <div class="adef-list">
2405 <p><em>Attribute definitions:</em></p>
2406 <dl>
2407 <dt id="feBlendModeAttribute"><span
2408 class="adef">mode</span> = "<em>normal | multiply | screen | darken |
2409 lighten</em>"</dt>
2410 <dd>One of the image blending modes (see <a
2411 href="#BlendingTable">table</a> below). The <a>lacuna value</a> for <a>'mode'</a> is <span class="attr-value">normal</span>.<br />
2412 <span class="anim-target">Animatable: yes.</span></dd>
2413 <dt id="feBlendIn2Attribute"><span
2414 class="adef">in2</span> = "<em>(see <a
2415 href="#FilterPrimitiveInAttribute"><span class="attr-name">in</span></a>
2416 attribute)</em>"</dt>
2417 <dd>The second input image to the blending operation. This attribute can
2418 take on the same values as the <a
2419 href="#FilterPrimitiveInAttribute"><span
2420 class="attr-name">in</span></a> attribute.<br />
2421 <span class="anim-target">Animatable: yes.</span></dd>
2422 </dl>
2423 </div>
2425 <p>
2426 For all feBlend modes, the result opacity is computed as follows:</p>
2427 <pre>qr = 1 - (1-qa)*(1-qb)</pre>
2429 <p>
2430 For the compositing formulas below, the following definitions apply:</p>
2431 <pre>image A = in
2432 image B = in2
2433 cr = Result color (RGB) - premultiplied
2434 qa = Opacity value at a given pixel for image A
2435 qb = Opacity value at a given pixel for image B
2436 ca = Color (RGB) at a given pixel for image A - premultiplied
2437 cb = Color (RGB) at a given pixel for image B - premultiplied </pre>
2439 <p id="BlendingTable">The following table
2440 provides the list of available image blending modes:</p>
2442 <div class="note-editor">
2443 ED: make table look nicer</div>
2445 <table summary="blending modes" width="500" border="1">
2446 <tbody>
2447 <tr>
2448 <td>Image Blending Mode</td>
2449 <td>Formula for computing result color</td>
2450 </tr>
2451 <tr>
2452 <td>normal</td>
2453 <td>cr = (1 - qa) * cb + ca</td>
2454 </tr>
2455 <tr>
2456 <td>multiply</td>
2457 <td>cr = (1-qa)*cb + (1-qb)*ca + ca*cb</td>
2458 </tr>
2459 <tr>
2460 <td>screen</td>
2461 <td>cr = cb + ca - ca * cb</td>
2462 </tr>
2463 <tr>
2464 <td>darken</td>
2465 <td>cr = Min ((1 - qa) * cb + ca, (1 - qb) * ca + cb)</td>
2466 </tr>
2467 <tr>
2468 <td>lighten</td>
2469 <td>cr = Max ((1 - qa) * cb + ca, (1 - qb) * ca + cb)</td>
2470 </tr>
2471 </tbody>
2472 </table>
2474 <p>
2475 The <span class="attr-value">'normal'</span> blend mode is equivalent to <a
2476 href="#feCompositeOperatorAttribute"><span
2477 class="attr-value">operator="over"</span></a> on the <a>'feComposite'</a>
2478 filter primitive, matches the blending method used by <a>'feMerge'</a> and matches
2479 the <a>simple alpha compositing</a> technique used in SVG for all compositing outside of filter effects.</p>
2481 </edit:with>
2482 <edit:example href="examples/feBlend.svg" image="yes" link="yes"/>
2484 <h2 id="feColorMatrixElement">Filter primitive <span class="element-name">'feColorMatrix'</span></h2>
2486 <edit:elementsummary name='feColorMatrix'/>
2488 <p>
2489 This filter applies a matrix transformation:</p>
2490 <object data="mathml/feColorMatrix00.mml" type="application/mathml+xml" width="100%" height="140">
2491 <pre>| R' | | a00 a01 a02 a03 a04 | | R |
2492 | G' | | a10 a11 a12 a13 a14 | | G |
2493 | B' | = | a20 a21 a22 a23 a24 | * | B |
2494 | A' | | a30 a31 a32 a33 a34 | | A |
2495 | 1 | | 0 0 0 0 1 | | 1 |</pre>
2496 </object>
2498 <p>
2499 on the RGBA color and alpha values of every pixel on the input graphics to
2500 produce a result with a new set of RGBA color and alpha values.</p>
2502 <p>
2503 The calculations are performed on non-premultiplied color values. If the
2504 input graphics consists of premultiplied color values, those values are
2505 automatically converted into non-premultiplied color values for this
2506 operation.</p>
2508 <p>
2509 These matrices often perform an identity mapping in the alpha channel. If
2510 that is the case, an implementation can avoid the costly undoing and redoing
2511 of the premultiplication for all pixels with A = 1.</p>
2513 <div class="adef-list">
2514 <p><em>Attribute definitions:</em></p>
2515 <dl>
2516 <dt id="feColorMatrixTypeAttribute"><span class="adef">type</span> =
2517 "<em>matrix | saturate | hueRotate | luminanceToAlpha</em>"</dt>
2518 <dd>Indicates the type of matrix operation. The keyword <span
2519 class="attr-name">matrix</span> indicates that a full 5x4 matrix of
2520 values will be provided. The other keywords represent convenience
2521 shortcuts to allow commonly used color operations to be performed
2522 without specifying a complete matrix.
2523 The <a>lacuna value</a> for <a>'type'</a> is <span class="attr-value">matrix</span>.
2524 <br />
2525 <span class="anim-target">Animatable: yes.</span></dd>
2526 <dt id="feColorMatrixValuesAttribute"><span class="adef">values</span> =
2527 "<em>list of <a><number></a>s</em>"</dt>
2528 <dd>The contents of <span class="attr-name">values</span> depends on the
2529 value of attribute <a href="#feColorMatrixTypeAttribute"><span
2530 class="attr-name">type</span></a>:
2531 <ul>
2532 <li>For <span class="attr-value">type="matrix"</span>, <span
2533 class="attr-name">values</span> is a list of 20 matrix values (a00
2534 a01 a02 a03 a04 a10 a11 ... a34), separated by whitespace and/or a
2535 comma. For example, the identity matrix could be expressed as:
2536 <pre>type="matrix"
2537 values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"</pre>
2538 </li>
2539 <li>For <span class="attr-value">type="saturate"</span>, <span
2540 class="attr-name">values</span> is a single real number value.
2541 A <span class="attr-value">saturate</span> operation is
2542 equivalent to the following matrix operation:
2543 <p>
2544 <object data="mathml/feColorMatrix01.mml" type="application/mathml+xml" width="100%" height="130">
2545 <pre>| R' | | (0.2126 + 0.7873s) (0.7152 - 0.7152s) (0.0722 - 0.0722s) 0 0 | | R |
2546 | G' | | (0.2126 - 0.2126s) (0.7152 + 0.2848s) (0.0722 - 0.0722s) 0 0 | | G |
2547 | B' | = | (0.2126 - 0.2126s) (0.7152 - 0.7152s) (0.0722 + 0.9278s) 0 0 | * | B |
2548 | A' | | 0 0 0 1 0 | | A |
2549 | 1 | | 0 0 0 0 1 | | 1 |</pre>
2550 </object>
2551 </p>
2552 <div class="note authoring">A value of <span class="attr-value">0</span> produces a fully desaturated (grayscale) filter result,
2553 while a value of <span class="attr-value">1</span> passes the filter input image through unchanged.
2554 Values outside the 0..1 range under- or oversaturates the filter input image respectively.</div>
2555 </li>
2556 <li>For <span class="attr-value">type="hueRotate"</span>, <span
2557 class="attr-name">values</span> is a single one real number value
2558 (degrees). A <span class="attr-value">hueRotate</span> operation is
2559 equivalent to the following matrix operation:
2560 <p>
2561 <object data="mathml/feColorMatrix02.mml" type="application/mathml+xml" width="100%" height="130">
2562 <pre>| R' | | a00 a01 a02 0 0 | | R |
2563 | G' | | a10 a11 a12 0 0 | | G |
2564 | B' | = | a20 a21 a22 0 0 | * | B |
2565 | A' | | 0 0 0 1 0 | | A |
2566 | 1 | | 0 0 0 0 1 | | 1 |</pre>
2567 </object>
2568 </p>
2570 where the terms a00, a01, etc. are calculated as follows:
2571 <p>
2572 <object data="mathml/feColorMatrix03.mml" type="application/mathml+xml" width="100%" height="230">
2573 <pre>| a00 a01 a02 | [0.2126 0.7152 0.0722]
2574 | a10 a11 a12 | = [0.2126 0.7152 0.0722] +
2575 | a20 a21 a22 | [0.2126 0.7152 0.0722]
2577 [ 0.7873 -0.7152 -0.0722]
2578 cos(hueRotate value) * [-0.2126 0.2848 -0.0722] +
2579 [-0.2126 -0.7152 0.9278]
2581 [-0.2126 -0.7152 0.9278]
2582 sin(hueRotate value) * [ 0.143 0.140 -0.283 ]
2583 [-0.7873 0.7152 0.0722]</pre>
2584 </object>
2585 </p>
2586 Thus, the upper left term of the hue matrix turns out to be:
2587 <p>
2588 <object data="mathml/feColorMatrix04.mml" type="application/mathml+xml" width="100%" height="30">
2589 <pre>0.2127 + cos(hueRotate value) * 0.7873 - sin(hueRotate value) * 0.2127</pre>
2590 </object>
2591 </p>
2593 </li>
2594 <li>For <span class="attr-value">type="luminanceToAlpha"</span>,
2595 <span class="attr-name">values</span> is not applicable. A <span
2596 class="attr-value">luminanceToAlpha</span> operation is equivalent
2597 to the following matrix operation:
2598 <p>
2599 <object data="mathml/feColorMatrix05.mml" type="application/mathml+xml" width="100%" height="130">
2600 <pre> | R' | | 0 0 0 0 0 | | R |
2601 | G' | | 0 0 0 0 0 | | G |
2602 | B' | = | 0 0 0 0 0 | * | B |
2603 | A' | | 0.2126 0.7152 0.0722 0 0 | | A |
2604 | 1 | | 0 0 0 0 1 | | 1 |</pre>
2605 </object>
2606 </p>
2607 </li>
2608 </ul>
2609 If the attribute is not specified, then the default behavior depends on
2610 the value of attribute <a>'feColorMatrix/type'</a>. If <span
2611 class="attr-value">type="matrix"</span>, then this attribute defaults
2612 to the identity matrix. If <span
2613 class="attr-value">type="saturate"</span>, then this attribute defaults
2614 to the value <span class="attr-value">1</span>, which results in the
2615 identity matrix. If <span class="attr-value">type="hueRotate"</span>,
2616 then this attribute defaults to the value <span
2617 class="attr-value">0</span>, which results in the identity matrix.<br />
2618 <span class="anim-target">Animatable: yes.</span> </dd>
2619 </dl>
2620 </div>
2622 <edit:example href="examples/feColorMatrix.svg" image="yes" link="yes"/>
2624 <h2 id="feComponentTransferElement">Filter primitive <span class="element-name">'feComponentTransfer'</span></h2>
2626 <edit:elementsummary name='feComponentTransfer'/>
2628 <p>
2629 This filter primitive performs component-wise remapping of data as
2630 follows:</p>
2631 <pre>R' = <a href="#feFuncRElement">feFuncR</a>( R )
2632 G' = <a href="#feFuncGElement">feFuncG</a>( G )
2633 B' = <a href="#feFuncBElement">feFuncB</a>( B )
2634 A' = <a href="#feFuncAElement">feFuncA</a>( A )</pre>
2636 <p>
2637 for every pixel. It allows operations like brightness adjustment, contrast
2638 adjustment, color balance or thresholding.</p>
2640 <p>
2641 The calculations are performed on non-premultiplied color values. If the
2642 input graphics consists of premultiplied color values, those values are
2643 automatically converted into non-premultiplied color values for this
2644 operation. (Note that the undoing and redoing of the premultiplication can be
2645 avoided if <a>'feFuncA'</a> is the identity transform
2646 and all alpha values on the source graphic are set to 1.)</p>
2648 <p>
2649 The child elements of a <a>'feComponentTransfer'</a> element specify the
2650 transfer functions for the four channels:</p>
2652 <ul id="transferFuncElements">
2653 <li><a>'feFuncR'</a> — transfer function for the red component of the input graphic</li>
2654 <li><a>'feFuncG'</a> — transfer function for the green component of the input graphic</li>
2655 <li><a>'feFuncB'</a> — transfer function for the blue component of the input graphic</li>
2656 <li><a>'feFuncA'</a> — transfer function for the alpha component of the input graphic</li>
2657 </ul>
2659 <p>
2660 The following rules apply to the processing of the <a>'feComponentTransfer'</a> element:</p>
2661 <ul>
2662 <li>If more than one <a>transfer function element</a> of the same kind is specified, the last occurrence is to be used.</li>
2663 <li>If any of the <a>transfer function elements</a> are unspecified, the <a>'feComponentTransfer'</a> must be processed as if those <a>transfer function elements</a> were specified with their <a>'type'</a> attributes set to <span class="attr-value">'identity'</span>.</li>
2664 </ul>
2666 <edit:with element='feFuncR'>
2668 <div id='feFuncRElement'>
2669 <edit:elementsummary name='feFuncR'/>
2670 </div>
2672 <div id='feFuncGElement'>
2673 <edit:elementsummary name='feFuncG'/>
2674 </div>
2676 <div id='feFuncBElement'>
2677 <edit:elementsummary name='feFuncB'/>
2678 </div>
2680 <div id='feFuncAElement'>
2681 <edit:elementsummary name='feFuncA'/>
2682 </div>
2684 <p id="TransferFunctionElementAttributes">The attributes below are the
2685 <span class='SVG-TermDefine'>transfer function element attributes</span>,
2686 which apply to the <a>transfer function elements</a>.</p>
2688 <div class="adef-list">
2689 <p><em>Attribute definitions:</em></p>
2690 <dl>
2691 <dt id="feComponentTransferTypeAttribute"><span class="adef">type</span>
2692 = "<em>identity | table | discrete | linear | gamma</em>"</dt>
2693 <dd><p>
2694 Indicates the type of component transfer function. The type of
2695 function determines the applicability of the other attributes.</p>
2696 <p>
2697 In the following, C is the initial component (e.g.,
2698 <a>'feFuncR'</a>), C' is the remapped component; both
2699 in the closed interval [0,1].</p>
2700 <ul>
2701 <li>For <span class="attr-value">identity</span>:
2702 <pre>C' = C</pre>
2703 </li>
2704 <li>For <span class="attr-value">table</span>, the function is
2705 defined by linear interpolation
2706 between values given in the attribute
2707 <a>'tableValues'</a>. The table has <em>n+1</em>
2708 values (i.e., v<sub>0</sub> to v<sub>n</sub>)
2709 specifying the start and end values for <em>n</em>
2710 evenly sized interpolation regions. Interpolations
2711 use the following formula:
2713 <p>
2714 For a value <code>C < 1</code> find <code>k</code> such that:</p>
2715 <p class="filterformula">k/n <= C < (k+1)/n</p>
2717 <p>
2718 The result <code>C'</code> is given by:</p>
2719 <p class="filterformula">C' = v<sub>k</sub> + (C - k/n)*n * (v<sub>k+1</sub> - v<sub>k</sub>)</p>
2721 <p>
2722 If <code>C = 1</code> then:</p>
2723 <p class="filterformula">C' = v<sub>n</sub>.</p>
2724 </li>
2725 <li>For <span class="attr-value">discrete</span>, the function is defined by the step function
2726 given in the attribute <a>'tableValues'</a>, which provides a list of
2727 <em>n</em> values (i.e., v<sub>0</sub> to v<sub>n-1</sub>) in order
2728 to identify a step function consisting of <em>n</em> steps. The
2729 step function is defined by the following formula:
2731 <p>
2732 For a value <code>C < 1</code> find <code>k</code> such that:</p>
2733 <p class="filterformula">k/n <= C < (k+1)/n</p>
2735 <p>
2736 For a value <code>C</code> pick a <code>k</code> such that:</p>
2737 <p class="filterformula">k/N <= C < (k+1)/N</p>
2739 <p>
2740 The result <code>C'</code> is given by:</p>
2741 <p class="filterformula">C' = v<sub>k</sub></p>
2742 <p>
2743 If <code>C = 1</code> then:</p>
2744 <p class="filterformula">C' = v<sub>n-1</sub>.</p>
2745 </li>
2746 <li>For <span class="attr-value">linear</span>, the function is
2747 defined by the following linear equation:
2748 <p class="filterformula">C' = <a
2749 href="#feComponentTransferSlopeAttribute"><span
2750 class="attr-name">slope</span></a> * C + <a
2751 href="#feComponentTransferInterceptAttribute"><span
2752 class="attr-name">intercept</span></a></p>
2753 </li>
2754 <li>For <span class="attr-value">gamma</span>, the function is
2755 defined by the following exponential function:
2756 <p class="filterformula">C' = <a
2757 href="#feComponentTransferAmplitudeAttribute"><span
2758 class="attr-name">amplitude</span></a> * pow(C, <a
2759 href="#feComponentTransferExponentAttribute"><span
2760 class="attr-name">exponent</span></a>) + <a
2761 href="#feComponentTransferOffsetAttribute"><span
2762 class="attr-name">offset</span></a></p>
2763 </li>
2764 </ul>
2765 <span class="anim-target">Animatable: yes.</span> </dd>
2766 <dt id="feComponentTransferTableValuesAttribute"><span
2767 class="adef">tableValues</span> = "<em>(list of <a><number></a>s)</em>"</dt>
2768 <dd>When <span class="attr-value">type="table"</span>, the list of
2769 <a><number></a>
2770 s <em>v0,v1,...vn</em>, separated by white space and/or a comma, which
2771 define the lookup table. An empty list results in an identity transfer
2772 function. If the attribute is not specified, then the effect is as if
2773 an empty list were provided.<br />
2774 <span class="anim-target">Animatable: yes.</span></dd>
2775 <dt id="feComponentTransferSlopeAttribute"><span
2776 class="adef">slope</span> = "<em><a><number></a></em>"</dt>
2777 <dd>When <span class="attr-value">type="linear"</span>, the slope of the
2778 linear function.<br />
2779 The <a>lacuna value</a> for <a>'slope'</a> is <span class="attr-value">1</span>.<br />
2780 <span class="anim-target">Animatable: yes.</span></dd>
2781 <dt id="feComponentTransferInterceptAttribute"><span
2782 class="adef">intercept</span> = "<em><a><number></a></em>"</dt>
2783 <dd>When <span class="attr-value">type="linear"</span>, the intercept of
2784 the linear function.<br />
2785 The <a>lacuna value</a> for <a>'intercept'</a> is <span class="attr-value">0</span>.<br />
2786 <span class="anim-target">Animatable: yes.</span></dd>
2787 <dt id="feComponentTransferAmplitudeAttribute"><span
2788 class="adef">amplitude</span> = "<em><a><number></a></em>"</dt>
2789 <dd>When <span class="attr-value">type="gamma"</span>, the amplitude of
2790 the gamma function.<br />
2791 The <a>lacuna value</a> for <a>'amplitude'</a> is <span class="attr-value">1</span>.<br />
2792 <span class="anim-target">Animatable: yes.</span></dd>
2793 <dt id="feComponentTransferExponentAttribute"><span
2794 class="adef">exponent</span> = "<em><a><number></a></em>"</dt>
2795 <dd>When <span class="attr-value">type="gamma"</span>, the exponent of
2796 the gamma function.<br />
2797 The <a>lacuna value</a> for <a>'exponent'</a> is <span class="attr-value">1</span>.<br />
2798 <span class="anim-target">Animatable: yes.</span></dd>
2799 <dt id="feComponentTransferOffsetAttribute"><span
2800 class="adef">offset</span> = "<em><a><number></a></em>"</dt>
2801 <dd>When <span class="attr-value">type="gamma"</span>, the offset of the
2802 gamma function.<br />
2803 The <a>lacuna value</a> for <a>'offset'</a> is <span class="attr-value">0</span>.<br />
2804 <span class="anim-target">Animatable: yes.</span></dd>
2805 </dl>
2806 </div>
2807 </edit:with>
2809 <edit:example href="examples/feComponentTransfer.svg" image="yes" link="yes"/>
2811 <h2 id="feCompositeElement">Filter primitive <span class="element-name">'feComposite'</span></h2>
2813 <edit:elementsummary name='feComposite'/>
2814 <edit:with element='feComposite'>
2816 <p>
2817 This filter performs the combination of the two input images pixel-wise in
2818 image space using one of the Porter-Duff [<a
2819 href="#ref-PORTERDUFF">PORTERDUFF</a>] compositing operations: <em>over, in,
2820 atop, out, xor</em> [<a href="#ref-SVG-COMPOSITING">SVG-COMPOSITING</a>]. Additionally, a component-wise <em>arithmetic</em>
2821 operation (with the result clamped between [0..1]) can be applied.</p>
2823 <p>
2824 The <em>arithmetic</em> operation is useful for combining the output from
2825 the <a>'feDiffuseLighting'</a> and <a>'feSpecularLighting'</a> filters with texture
2826 data. It is also useful for implementing <em>dissolve</em>. If the
2827 <em>arithmetic</em> operation is chosen, each result pixel is computed using
2828 the following formula:</p>
2829 <pre>result = k1*i1*i2 + k2*i1 + k3*i2 + k4</pre>
2830 where:
2831 <ul>
2832 <li>
2833 <code>i1</code> and <code>i2</code> indicate the corresponding pixel channel values of the input image, which map to <a>'in'</a> and <a>'in2'</a> respectively
2834 </li>
2835 <li>
2836 <code>k1, k2, k3</code> and <code>k4</code> indicate the values of the attributes with the same name
2837 </li>
2838 </ul>
2840 <p>
2841 For this filter primitive, the extent of the resulting image might grow as
2842 described in the section that describes the <a>filter primitive subregion</a>.</p>
2844 <div class="adef-list">
2845 <p><em>Attribute definitions:</em></p>
2846 <dl>
2847 <dt id="feCompositeOperatorAttribute"><span class="adef">operator</span>
2848 = "<em>over | in | out | atop | xor | arithmetic</em>"</dt>
2849 <dd>The compositing operation that is to be performed. All of the <span
2850 class="attr-name">operator</span> types except <span
2851 class="attr-value">arithmetic</span> match the corresponding operation as
2852 described in [<a href="#ref-PORTERDUFF">PORTERDUFF</a>]. The <span
2853 class="attr-value">arithmetic</span> operator is described above.
2854 The <a>lacuna value</a> for <a>'operator'</a> is <span class="attr-value">over</span>.
2855 <br />
2856 <span class="anim-target">Animatable: yes.</span></dd>
2857 <dt id="feCompositeK1Attribute"><span
2858 class="adef">k1</span> = "<em><a><number></a></em>"</dt>
2859 <dd>Only applicable if <span
2860 class="attr-value">operator="arithmetic"</span>.<br />
2861 The <a>lacuna value</a> for <a>'k1'</a> is <span class="attr-value">0</span>. <br />
2862 <span class="anim-target">Animatable: yes.</span></dd>
2863 <dt id="feCompositeK2Attribute"><span
2864 class="adef">k2</span> = "<em><a><number></a></em>"</dt>
2865 <dd>Only applicable if <span
2866 class="attr-value">operator="arithmetic"</span>.<br />
2867 The <a>lacuna value</a> for <a>'k2'</a> is <span class="attr-value">0</span>. <br />
2868 <span class="anim-target">Animatable: yes.</span></dd>
2869 <dt id="feCompositeK3Attribute"><span
2870 class="adef">k3</span> = "<em><a><number></a></em>"</dt>
2871 <dd>Only applicable if <span
2872 class="attr-value">operator="arithmetic"</span>.<br />
2873 The <a>lacuna value</a> for <a>'k3'</a> is <span class="attr-value">0</span>. <br />
2874 <span class="anim-target">Animatable: yes.</span></dd>
2875 <dt id="feCompositeK4Attribute"><span
2876 class="adef">k4</span> = "<em><a><number></a></em>"</dt>
2877 <dd>Only applicable if <span
2878 class="attr-value">operator="arithmetic"</span>.<br />
2879 The <a>lacuna value</a> for <a>'k4'</a> is <span class="attr-value">0</span>. <br />
2880 <span class="anim-target">Animatable: yes.</span></dd>
2881 <dt id="feCompositeIn2Attribute">
2882 <span class="adef">in2</span> = "<em>(see <a
2883 href="#FilterPrimitiveInAttribute"><span class="attr-name">in</span></a>
2884 attribute)</em>"</dt>
2885 <dd>The second input image to the compositing operation. This attribute
2886 can take on the same values as the <a
2887 href="#FilterPrimitiveInAttribute"><span
2888 class="attr-name">in</span></a> attribute.<br />
2889 <span class="anim-target">Animatable: yes.</span></dd>
2890 </dl>
2891 </div>
2892 </edit:with>
2894 <edit:example href="examples/feComposite.svg" image="yes" link="yes"/>
2896 <h2 id="feConvolveMatrixElement">Filter primitive <span class="element-name">'feConvolveMatrix'</span></h2>
2898 <edit:elementsummary name='feConvolveMatrix'/>
2899 <edit:with element='feConvolveMatrix'>
2901 <p>
2902 feConvolveMatrix applies a matrix convolution filter effect. A convolution
2903 combines pixels in the input image with neighboring pixels to produce a
2904 resulting image. A wide variety of imaging operations can be achieved through
2905 convolutions, including blurring, edge detection, sharpening, embossing and
2906 beveling.</p>
2908 <p>
2909 A matrix convolution is based on an n-by-m matrix (the convolution kernel)
2910 which describes how a given pixel value in the input image is combined with
2911 its neighboring pixel values to produce a resulting pixel value. Each result
2912 pixel is determined by applying the kernel matrix to the corresponding source
2913 pixel and its neighboring pixels. The basic convolution formula which is
2914 applied to each color value for a given pixel is:</p>
2916 <p class="filterformula" id="feConvolveMatrixElementFormula">COLOR<sub>X,Y</sub> = ( <br />
2917 SUM <sub>I=0 to [<a
2918 href="#feConvolveMatrixElementOrderAttribute">'orderY'</a>-1]</sub> { <br />
2919 SUM <sub>J=0 to [<a
2920 href="#feConvolveMatrixElementOrderAttribute">'orderX'</a>-1]</sub> { <br />
2921 SOURCE <sub>X-<a>'targetX'</a>+J, Y-<a>'targetY'</a>+I</sub> * <a>'kernelMatrix'</a><sub><a
2922 href="#feConvolveMatrixElementOrderAttribute">'orderX'</a>-J-1, <a
2923 href="#feConvolveMatrixElementOrderAttribute">'orderY'</a>-I-1</sub> <br />
2924 } <br />
2925 } <br />
2926 ) / <a>'divisor'</a> + <a>'bias'</a> * ALPHA<sub>X,Y</sub><br />
2927 </p>
2929 <div class="note-editor">
2930 ED: Consider making this into mathml</div>
2932 <p>
2933 where "orderX" and "orderY" represent the X and Y values for the <a>'order'</a> attribute, "targetX" represents the value
2934 of the <a>'targetX'</a> attribute, "targetY" represents the
2935 value of the <a>'targetY'</a> attribute, "kernelMatrix" represents the
2936 value of the <a>'kernelMatrix'</a> attribute, "divisor" represents the
2937 value of the <a>'divisor'</a> attribute, and "bias" represents the
2938 value of the <a>'bias'</a> attribute.</p>
2940 <p>
2941 Note in the above formulas that the values in the kernel matrix are
2942 applied such that the kernel matrix is rotated 180 degrees relative to the
2943 source and destination images in order to match convolution theory as
2944 described in many computer graphics textbooks.</p>
2946 <p>
2947 To illustrate, suppose you have a input image which is 5 pixels by 5
2948 pixels, whose color values for one of the color channels are as follows:</p>
2949 <pre> 0 20 40 235 235
2950 100 120 140 235 235
2951 200 220 240 235 235
2952 225 225 255 255 255
2953 225 225 255 255 255</pre>
2955 <div class="note-editor">
2956 ED: Consider making this into mathml</div>
2958 <p>
2959 and you define a 3-by-3 convolution kernel as follows:</p>
2960 <pre> 1 2 3
2961 4 5 6
2962 7 8 9</pre>
2964 <div class="note-editor">
2965 ED: Consider making this into mathml</div>
2967 <p>
2968 Let's focus on the color value at the second row and second column of the
2969 image (source pixel value is 120). Assuming the simplest case (where the
2970 input image's pixel grid aligns perfectly with the kernel's pixel grid) and
2971 assuming default values for attributes <a>'divisor'</a>, <a>'targetX'</a> and
2972 <a>'targetY'</a>, then resulting color value will
2973 be:</p>
2974 <pre>(9* 0 + 8* 20 + 7* 40 +
2975 6*100 + 5*120 + 4*140 +
2976 3*200 + 2*220 + 1*240) / (9+8+7+6+5+4+3+2+1)</pre>
2978 <div class="note-editor">
2979 ED: Consider making this into mathml</div>
2981 <p>
2982 Because they operate on pixels, matrix convolutions are inherently
2983 resolution-dependent. To make <a>'feConvolveMatrix'</a> produce resolution-independent
2984 results, an explicit value should be provided for either the <a>'filter/filterRes'</a> attribute on the <a>'filter element'</a> element
2985 and/or attribute <a>'kernelUnitLength'</a>.</p>
2987 <p><a>'kernelUnitLength'</a>, in combination with the other
2988 attributes, defines an implicit pixel grid in the filter effects coordinate
2989 system (i.e., the coordinate system established by the <a>'filter/primitiveUnits'</a> attribute). If the pixel grid
2990 established by <a>'kernelUnitLength'</a> is not scaled to match the
2991 pixel grid established by attribute <a>'filter/filterRes'</a> (implicitly or explicitly), then the
2992 input image will be temporarily rescaled to match its pixels with <a>'kernelUnitLength'</a>. The convolution happens on the
2993 resampled image. After applying the convolution, the image is resampled back
2994 to the original resolution.</p>
2996 <p>
2997 When the image must be resampled to match the coordinate system defined by
2998 <a>'kernelUnitLength'</a> prior to convolution, or
2999 resampled to match the device coordinate system after convolution, it is
3000 recommended that high quality viewers make use of appropriate interpolation
3001 techniques, for example bilinear or bicubic. Depending on the speed of the
3002 available interpolents, this choice may be affected by the <a>'image-rendering'</a> property setting. Note that
3003 implementations might choose approaches that minimize or eliminate resampling
3004 when not necessary to produce proper results, such as when the document is
3005 zoomed out such that <a>'kernelUnitLength'</a> is
3006 considerably smaller than a device pixel.</p>
3008 <div class="adef-list">
3009 <p><em>Attribute definitions:</em></p>
3010 <dl>
3011 <dt id="feConvolveMatrixElementOrderAttribute"><span
3012 class="adef">order</span> = "<span
3013 class="attr-value"><a><number-optional-number></a></span>"</dt>
3014 <dd>Indicates the number of cells in each dimension for <a>'kernelMatrix'</a>. The values provided must be
3015 <a><integer></a>
3016 s greater than zero. The first number, <orderX>, indicates the
3017 number of columns in the matrix. The second number, <orderY>,
3018 indicates the number of rows in the matrix. If <orderY> is not
3019 provided, it defaults to <orderX>.<br />
3020 A typical value is order="3". It is recommended that only small values
3021 (e.g., 3) be used; higher values may result in very high CPU overhead
3022 and usually do not produce results that justify the impact on
3023 performance.<br />
3024 If the attribute is not specified, the effect is as if a value of "3"
3025 were specified.<br />
3026 <span class="anim-target">Animatable: yes.</span></dd>
3027 <dt id="feConvolveMatrixElementKernelMatrixAttribute"><span
3028 class="adef">kernelMatrix</span> = "<span class="attr-value"><list of
3029 numbers></span>"</dt>
3030 <dd>The list of <a><number></a>
3031 s that make up the kernel matrix for the convolution. Values are
3032 separated by space characters and/or a comma. The number of entries in
3033 the list must equal <orderX> times <orderY>.<br />
3034 <span class="anim-target">Animatable: yes.</span></dd>
3035 <dt id="feConvolveMatrixElementDivisorAttribute"><span
3036 class="adef">divisor</span> = "<span
3037 class="attr-value"><a><number></a></span>"</dt>
3038 <dd>After applying the <span class="attr-name">kernelMatrix</span> to the
3039 input image to yield a number, that number is divided by <a>'divisor'</a> to yield the final destination color
3040 value. A divisor that is the sum of all the matrix values tends to have
3041 an evening effect on the overall color intensity of the result. If the
3042 specified divisor is zero then the default value will be used instead.
3043 The default value is the sum of all values in kernelMatrix, with the
3044 exception that if the sum is zero, then the divisor is set to 1.<br />
3045 <span class="anim-target">Animatable: yes.</span></dd>
3046 <dt id="feConvolveMatrixElementBiasAttribute"><span
3047 class="adef">bias</span> = "<span
3048 class="attr-value"><a><number></a></span>"</dt>
3049 <dd>After applying the <span class="attr-name">kernelMatrix</span> to the
3050 input image to yield a number and applying the <a>'divisor'</a>, the <a>'bias'</a> attribute is added to each component. One
3051 application of <a>'bias'</a> is when it is
3052 desirable to have <span class="attr-value">.5</span> gray value be the zero response of the filter.
3053 The bias property shifts the range of the filter. This allows representation of values that would
3054 otherwise be clamped to 0 or 1.<br />
3055 The <a>lacuna value</a> for <a>'bias'</a> is <span class="attr-value">0</span>.<br />
3056 <span class="anim-target">Animatable: yes.</span></dd>
3057 <dt id="feConvolveMatrixElementTargetXAttribute"><span
3058 class="adef">targetX</span> = "<span
3059 class="attr-value"><a><integer></a></span>"</dt>
3060 <dd>Determines the positioning in X of the convolution matrix relative to
3061 a given target pixel in the input image. The leftmost column of the
3062 matrix is column number zero. The value must be such that: 0 <=
3063 targetX < orderX. By default, the convolution matrix is centered in
3064 X over each pixel of the input image (i.e., targetX = floor ( orderX /
3065 2 )).<br />
3066 <span class="anim-target">Animatable: yes.</span></dd>
3067 <dt id="feConvolveMatrixElementTargetYAttribute"><span
3068 class="adef">targetY</span> = "<span
3069 class="attr-value"><a><integer></a></span>"</dt>
3070 <dd>Determines the positioning in Y of the convolution matrix relative to
3071 a given target pixel in the input image. The topmost row of the matrix
3072 is row number zero. The value must be such that: 0 <= targetY <
3073 orderY. By default, the convolution matrix is centered in Y over each
3074 pixel of the input image (i.e., targetY = floor ( orderY / 2 )).<br />
3075 <span class="anim-target">Animatable: yes.</span></dd>
3076 <dt id="feConvolveMatrixElementEdgeModeAttribute"><span
3077 class="adef">edgeMode</span> = "<span class="attr-value">duplicate | wrap |
3078 none</span>"</dt>
3079 <dd><p>
3080 Determines how to extend the input image as necessary with color
3081 values so that the matrix operations can be applied when the kernel is
3082 positioned at or near the edge of the input image.</p>
3083 <p>"duplicate" indicates that the input image is extended along each of
3084 its borders as necessary by duplicating the color values at the given
3085 edge of the input image.</p>
3086 <pre>Original N-by-M image, where m=M-1 and n=N-1:
3087 11 12 ... 1m 1M
3088 21 22 ... 2m 2M
3089 .. .. ... .. ..
3090 n1 n2 ... nm nM
3091 N1 N2 ... Nm NM
3092 Extended by two pixels using "duplicate":
3093 11 11 11 12 ... 1m 1M 1M 1M
3094 11 11 11 12 ... 1m 1M 1M 1M
3095 11 11 11 12 ... 1m 1M 1M 1M
3096 21 21 21 22 ... 2m 2M 2M 2M
3097 .. .. .. .. ... .. .. .. ..
3098 n1 n1 n1 n2 ... nm nM nM nM
3099 N1 N1 N1 N2 ... Nm NM NM NM
3100 N1 N1 N1 N2 ... Nm NM NM NM
3101 N1 N1 N1 N2 ... Nm NM NM NM</pre>
3103 <div class="note-editor">
3104 ED: Consider making this into mathml</div>
3105 <p>"wrap" indicates that the input image is extended by taking the
3106 color values from the opposite edge of the image.</p>
3107 <pre>Extended by two pixels using "wrap":
3108 nm nM n1 n2 ... nm nM n1 n2
3109 Nm NM N1 N2 ... Nm NM N1 N2
3110 1m 1M 11 12 ... 1m 1M 11 12
3111 2m 2M 21 22 ... 2m 2M 21 22
3112 .. .. .. .. ... .. .. .. ..
3113 nm nM n1 n2 ... nm nM n1 n2
3114 Nm NM N1 N2 ... Nm NM N1 N2
3115 1m 1M 11 12 ... 1m 1M 11 12
3116 2m 2M 21 22 ... 2m 2M 21 22</pre>
3118 <div class="note-editor">
3119 ED: Consider making this into mathml</div>
3120 <p>
3121 The value <span class="attr-value">none</span> indicates that the input image is extended with pixel values
3122 of zero for R, G, B and A.</p>
3123 <p>
3124 The <a>lacuna value</a> for <a>'edgeMode'</a> is <span class="attr-value">duplicate</span>.</p>
3125 <p><span class="anim-target">Animatable: yes.</span></p>
3126 </dd>
3127 <dt id="feConvolveMatrixElementKernelUnitLengthAttribute"><span
3128 class="adef">kernelUnitLength</span> = "<span
3129 class="attr-value"><a><number-optional-number></a></span>"</dt>
3130 <dd>The first number is the <dx> value. The second number is the
3131 <dy> value. If the <dy> value is not specified, it defaults
3132 to the same value as <dx>. Indicates the intended distance in
3133 current filter units (i.e., units as determined by the value of
3134 attribute <a>'filter/primitiveUnits'</a>) between successive columns
3135 and rows, respectively, in the <a>'kernelMatrix'</a>. By specifying value(s) for
3136 <a>'kernelUnitLength'</a>, the kernel becomes defined
3137 in a scalable, abstract coordinate system. If <a>'kernelUnitLength'</a> is not specified, the default
3138 value is one pixel in the offscreen bitmap, which is a pixel-based
3139 coordinate system, and thus potentially not scalable. For some level of
3140 consistency across display media and user agents, it is necessary that
3141 a value be provided for at least one of <a>'filter/filterRes'</a> and <a>'kernelUnitLength'</a>.
3142 In some implementations, the most consistent results and the fastest performance will be achieved if
3143 the pixel grid of the temporary offscreen images aligns with the pixel
3144 grid of the kernel.<br />
3145 If a negative or zero value is specified the default value will be used
3146 instead. <br />
3147 <span class="anim-target">Animatable: yes.</span></dd>
3148 <dt id="feConvolveMatrixElementPreserveAlphaAttribute"><span
3149 class="adef">preserveAlpha</span> = "<span class="attr-value">false |
3150 true</span>"</dt>
3151 <dd>A value of <span class="attr-value">false</span> indicates that the
3152 convolution will apply to all channels, including the alpha channel.
3153 In this case the <code>ALPHA<sub>X,Y</sub></code> of the
3154 <a href="#feConvolveMatrixElementFormula">convolution formula</a> for a given pixel is:
3155 <p class="filterformula">
3156 ALPHA<sub>X,Y</sub> = ( <br />
3157 SUM
3158 <sub>I=0 to [<a href="#feConvolveMatrixElementOrderAttribute">'orderY'</a>-1]</sub> { <br />
3159 SUM
3160 <sub>J=0 to [<a href="#feConvolveMatrixElementOrderAttribute">'orderX'</a>-1]</sub> { <br />
3161 SOURCE
3162 <sub>X-<a>'targetX'</a>+J, Y-<a>'targetY'</a>+I</sub> *
3163 <a>'kernelMatrix'</a><sub><a href="#feConvolveMatrixElementOrderAttribute">'orderX'</a>-J-1,
3164 <a href="#feConvolveMatrixElementOrderAttribute">'orderY'</a>-I-1</sub> <br />
3165 } <br />
3166 } <br />
3167 ) /
3168 <a>'divisor'</a> +
3169 <a>'bias'</a>
3170 <br />
3171 </p>
3172 <br />
3173 A value of <span class="attr-value">true</span> indicates that the
3174 convolution will only apply to the color channels. In this case, the
3175 filter will temporarily unpremultiply the color component values, apply
3176 the kernel, and then re-premultiply at the end.
3177 In this case the <code>ALPHA<sub>X,Y</sub></code>
3178 of the <a href="#feConvolveMatrixElementFormula">convolution formula</a> for a given pixel is:
3179 <p class="filterformula">
3180 ALPHA<sub>X,Y</sub> = SOURCE<sub>X,Y</sub>
3181 </p>
3182 The <a>lacuna value</a> for <a>'preserveAlpha'</a> is <span class="attr-value">false</span>.<br />
3183 <span class="anim-target">Animatable: yes.</span></dd>
3184 </dl>
3185 </div>
3187 </edit:with>
3189 <h2 id="feDiffuseLightingElement">Filter primitive <span
3190 class="element-name">'feDiffuseLighting'</span></h2>
3192 <edit:elementsummary name='feDiffuseLighting'/>
3194 <p>
3195 This filter primitive lights an image using the alpha channel as a bump
3196 map. The resulting image is an RGBA opaque image based on the light color
3197 with alpha = 1.0 everywhere. The lighting calculation follows the standard
3198 diffuse component of the Phong lighting model. The resulting image depends on
3199 the light color, light position and surface geometry of the input bump
3200 map.</p>
3202 <p>
3203 The light map produced by this filter primitive can be combined with a
3204 texture image using the multiply term of the <em>arithmetic</em> <a>'feComposite'</a> compositing method. Multiple
3205 light sources can be simulated by adding several of these light maps together
3206 before applying it to the texture image.</p>
3208 <p>
3209 The formulas below make use of 3x3 filters. Because they operate on
3210 pixels, such filters are inherently resolution-dependent. To make <a>'feDiffuseLighting'</a> produce
3211 resolution-independent results, an explicit value should be provided for
3212 either the <a>'filter/filterRes'</a> attribute on the <a>'filter element'</a> element
3213 and/or attribute <a>'feDiffuseLighting/kernelUnitLength'</a>.</p>
3215 <p><a>'feDiffuseLighting/kernelUnitLength'</a>, in combination with the other
3216 attributes, defines an implicit pixel grid in the filter effects coordinate
3217 system (i.e., the coordinate system established by the <a>'filter/primitiveUnits'</a> attribute). If the pixel grid
3218 established by <a>'feDiffuseLighting/kernelUnitLength'</a> is not scaled to match the
3219 pixel grid established by attribute <a>'filter/filterRes'</a> (implicitly or explicitly), then the
3220 input image will be temporarily rescaled to match its pixels with <a>'feDiffuseLighting/kernelUnitLength'</a>. The 3x3 filters are applied to the resampled image. After applying the filter, the image is resampled back
3221 to its original resolution.</p>
3223 <p><span class="requirement" id="assert_diffuseLightingImageResampling">When the image must be resampled, it is recommended that high quality viewers make use of appropriate interpolation techniques, for example
3224 bilinear or bicubic.</span> Depending on the speed of the available interpolents,
3225 this choice may be affected by the <a>'image-rendering'</a> property setting. Note that
3226 implementations might choose approaches that minimize or eliminate resampling
3227 when not necessary to produce proper results, such as when the document is
3228 zoomed out such that <a>'feDiffuseLighting/kernelUnitLength'</a> is
3229 considerably smaller than a device pixel.</p>
3231 <p>
3232 For the formulas that follow, the
3233 <code>Norm(A<sub>x</sub>,A<sub>y</sub>,A<sub>z</sub>)</code> function is
3234 defined as:</p>
3236 <div class="note-editor">
3237 ED: Consider making the following in mathml</div>
3239 <p class="filterformula">Norm(A<sub>x</sub>,A<sub>y</sub>,A<sub>z</sub>) =
3240 sqrt(A<sub>x</sub>^2+A<sub>y</sub>^2+A<sub>z</sub>^2)</p>
3242 <p>
3243 The resulting RGBA image is computed as follows:</p>
3245 <p class="filterformula">D<sub>r</sub> = k<sub>d</sub> * N.L *
3246 L<sub>r</sub><br />
3247 D<sub>g</sub> = k<sub>d</sub> * N.L * L<sub>g</sub><br />
3248 D<sub>b</sub> = k<sub>d</sub> * N.L * L<sub>b</sub><br />
3249 D<sub>a</sub> = 1.0</p>
3251 <p>
3252 where</p>
3253 <dl>
3254 <dd>k<sub>d</sub> = diffuse lighting constant<br />
3255 N = surface normal unit vector, a function of x and y<br />
3256 L = unit vector pointing from surface to light, a function of x and y
3257 in the point and spot light cases<br />
3258 L<sub>r</sub>,L<sub>g</sub>,L<sub>b</sub> = RGB components of light, a
3259 function of x and y in the spot light case</dd>
3260 </dl>
3262 <p>
3263 N is a function of x and y and depends on the surface gradient as
3264 follows:</p>
3266 <p>
3267 The surface described by the input alpha image I(x,y) is:</p>
3269 <p class="filterformula">Z (x,y) = surfaceScale * I(x,y)</p>
3271 <p id="SurfaceNormalCalculations">Surface normal is calculated using the Sobel gradient 3x3 filter.
3272 Different filter kernels are used depending on whether the given pixel is on
3273 the interior or an edge. For each case, the formula is:</p>
3274 <p class="filterformula">N<sub>x</sub> (x,y) = - surfaceScale *
3275 FACTOR<sub>x</sub> *<br />
3276 (K<sub>x</sub>(0,0)*I(x-dx,y-dy) +
3277 K<sub>x</sub>(1,0)*I(x,y-dy) +
3278 K<sub>x</sub>(2,0)*I(x+dx,y-dy) +<br />
3279 K<sub>x</sub>(0,1)*I(x-dx,y) +
3280 K<sub>x</sub>(1,1)*I(x,y) +
3281 K<sub>x</sub>(2,1)*I(x+dx,y) +<br />
3282 K<sub>x</sub>(0,2)*I(x-dx,y+dy) +
3283 K<sub>x</sub>(1,2)*I(x,y+dy) +
3284 K<sub>x</sub>(2,2)*I(x+dx,y+dy))<br />
3285 N<sub>y</sub> (x,y) = - surfaceScale * FACTOR<sub>y</sub>
3286 *<br />
3287 (K<sub>y</sub>(0,0)*I(x-dx,y-dy) +
3288 K<sub>y</sub>(1,0)*I(x,y-dy) +
3289 K<sub>y</sub>(2,0)*I(x+dx,y-dy) +<br />
3290 K<sub>y</sub>(0,1)*I(x-dx,y) +
3291 K<sub>y</sub>(1,1)*I(x,y) +
3292 K<sub>y</sub>(2,1)*I(x+dx,y) +<br />
3293 K<sub>y</sub>(0,2)*I(x-dx,y+dy) +
3294 K<sub>y</sub>(1,2)*I(x,y+dy) +
3295 K<sub>y</sub>(2,2)*I(x+dx,y+dy))<br />
3296 N<sub>z</sub> (x,y) = 1.0<br />
3297 <br />
3298 N = (N<sub>x</sub>, N<sub>y</sub>, N<sub>z</sub>) /
3299 Norm((N<sub>x</sub>,N<sub>y</sub>,N<sub>z</sub>))</p>
3301 <p>
3302 In these formulas, the <code>dx</code> and <code>dy</code> values (e.g.,
3303 <code>I(x-dx,y-dy)</code>), represent deltas relative to a given
3304 <code>(x,y)</code> position for the purpose of estimating the slope of the
3305 surface at that point. These deltas are determined by the value (explicit or
3306 implicit) of attribute <a>'feDiffuseLighting/kernelUnitLength'</a>.</p>
3308 <table summary="feDiffuseLighting formulas" border="1">
3309 <colgroup><col width="33.3%" /><col width="33.3%" /><col width="*"
3310 /></colgroup>
3311 <tbody>
3312 <tr>
3313 <td><p>
3314 Top/left corner:</p>
3316 <p class="filterformula">FACTOR<sub>x</sub>=2/(3*dx)<br />
3317 K<sub>x</sub> =<br />
3318 | 0 0 0 |<br />
3319 | 0 -2 2 |<br />
3320 | 0 -1 1 |<br />
3321 <br />
3322 FACTOR<sub>y</sub>=2/(3*dy)<br />
3323 K<sub>y</sub> = <br />
3324 | 0 0 0 |<br />
3325 | 0 -2 -1 |<br />
3326 | 0 2 1 |</p>
3327 </td>
3328 <td><p>
3329 Top row:</p>
3331 <p class="filterformula">FACTOR<sub>x</sub>=1/(3*dx)<br />
3332 K<sub>x</sub> =<br />
3333 | 0 0 0 |<br />
3334 | -2 0 2 |<br />
3335 | -1 0 1 |<br />
3336 <br />
3337 FACTOR<sub>y</sub>=1/(2*dy)<br />
3338 K<sub>y</sub> = <br />
3339 | 0 0 0 |<br />
3340 | -1 -2 -1 |<br />
3341 | 1 2 1 |</p>
3342 </td>
3343 <td><p>
3344 Top/right corner:</p>
3346 <p class="filterformula">FACTOR<sub>x</sub>=2/(3*dx)<br />
3347 K<sub>x</sub> =<br />
3348 | 0 0 0 |<br />
3349 | -2 2 0 |<br />
3350 | -1 1 0 |<br />
3351 <br />
3352 FACTOR<sub>y</sub>=2/(3*dy)<br />
3353 K<sub>y</sub> = <br />
3354 | 0 0 0 |<br />
3355 | -1 -2 0 |<br />
3356 | 1 2 0 |</p>
3357 </td>
3358 </tr>
3359 <tr>
3360 <td><p>
3361 Left column:</p>
3363 <p class="filterformula">FACTOR<sub>x</sub>=1/(2*dx)<br />
3364 K<sub>x</sub> =<br />
3365 | 0 -1 1 |<br />
3366 | 0 -2 2 |<br />
3367 | 0 -1 1 |<br />
3368 <br />
3369 FACTOR<sub>y</sub>=1/(3*dy)<br />
3370 K<sub>y</sub> = <br />
3371 | 0 -2 -1 |<br />
3372 | 0 0 0 |<br />
3373 | 0 2 1 |</p>
3374 </td>
3375 <td><p>
3376 Interior pixels:</p>
3378 <p class="filterformula">FACTOR<sub>x</sub>=1/(4*dx)<br />
3379 K<sub>x</sub> =<br />
3380 | -1 0 1 |<br />
3381 | -2 0 2 |<br />
3382 | -1 0 1 |<br />
3383 <br />
3384 FACTOR<sub>y</sub>=1/(4*dy)<br />
3385 K<sub>y</sub> = <br />
3386 | -1 -2 -1 |<br />
3387 | 0 0 0 |<br />
3388 | 1 2 1 |</p>
3389 </td>
3390 <td><p>
3391 Right column:</p>
3393 <p class="filterformula">FACTOR<sub>x</sub>=1/(2*dx)<br />
3394 K<sub>x</sub> =<br />
3395 | -1 1 0|<br />
3396 | -2 2 0|<br />
3397 | -1 1 0|<br />
3398 <br />
3399 FACTOR<sub>y</sub>=1/(3*dy)<br />
3400 K<sub>y</sub> = <br />
3401 | -1 -2 0 |<br />
3402 | 0 0 0 |<br />
3403 | 1 2 0 |</p>
3404 </td>
3405 </tr>
3406 <tr>
3407 <td><p>
3408 Bottom/left corner:</p>
3410 <p class="filterformula">FACTOR<sub>x</sub>=2/(3*dx)<br />
3411 K<sub>x</sub> =<br />
3412 | 0 -1 1 |<br />
3413 | 0 -2 2 |<br />
3414 | 0 0 0 |<br />
3415 <br />
3416 FACTOR<sub>y</sub>=2/(3*dy)<br />
3417 K<sub>y</sub> = <br />
3418 | 0 -2 -1 |<br />
3419 | 0 2 1 |<br />
3420 | 0 0 0 |</p>
3421 </td>
3422 <td><p>
3423 Bottom row:</p>
3425 <p class="filterformula">FACTOR<sub>x</sub>=1/(3*dx)<br />
3426 K<sub>x</sub> =<br />
3427 | -1 0 1 |<br />
3428 | -2 0 2 |<br />
3429 | 0 0 0 |<br />
3430 <br />
3431 FACTOR<sub>y</sub>=1/(2*dy)<br />
3432 K<sub>y</sub> = <br />
3433 | -1 -2 -1 |<br />
3434 | 1 2 1 |<br />
3435 | 0 0 0 |</p>
3436 </td>
3437 <td><p>
3438 Bottom/right corner:</p>
3440 <p class="filterformula">FACTOR<sub>x</sub>=2/(3*dx)<br />
3441 K<sub>x</sub> =<br />
3442 | -1 1 0 |<br />
3443 | -2 2 0 |<br />
3444 | 0 0 0 |<br />
3445 <br />
3446 FACTOR<sub>y</sub>=2/(3*dy)<br />
3447 K<sub>y</sub> = <br />
3448 | -1 -2 0 |<br />
3449 | 1 2 0 |<br />
3450 | 0 0 0 |</p>
3451 </td>
3452 </tr>
3453 </tbody>
3454 </table>
3456 <p>
3457 L, the unit vector from the image sample to the light, is calculated as
3458 follows:</p>
3460 <p>
3461 For Infinite light sources it is constant:</p>
3463 <p class="filterformula">L<sub>x</sub> = cos(azimuth)*cos(elevation)<br />
3464 L<sub>y</sub> = sin(azimuth)*cos(elevation)<br />
3465 L<sub>z</sub> = sin(elevation)</p>
3467 <p>
3468 For Point and spot lights it is a function of position:</p>
3470 <p class="filterformula">L<sub>x</sub> = Light<sub>x</sub> - x<br />
3471 L<sub>y</sub> = Light<sub>y</sub> - y<br />
3472 L<sub>z</sub> = Light<sub>z</sub> - Z(x,y)<br />
3473 <br />
3474 L = (L<sub>x</sub>, L<sub>y</sub>, L<sub>z</sub>) / Norm(L<sub>x</sub>,
3475 L<sub>y</sub>, L<sub>z</sub>)</p>
3477 <p>
3478 where Light<sub>x</sub>, Light<sub>y</sub>, and Light<sub>z</sub> are the
3479 input light position.</p>
3481 <p>
3482 L<sub>r</sub>,L<sub>g</sub>,L<sub>b</sub>, the light color vector, is a
3483 function of position in the spot light case only:</p>
3485 <p class="filterformula">L<sub>r</sub> =
3486 Light<sub>r</sub>*pow((-L.S),specularExponent)<br />
3487 L<sub>g</sub> = Light<sub>g</sub>*pow((-L.S),specularExponent)<br />
3488 L<sub>b</sub> = Light<sub>b</sub>*pow((-L.S),specularExponent)</p>
3490 <p>
3491 where S is the unit vector pointing from the light to the point
3492 (pointsAtX, pointsAtY, pointsAtZ) in the x-y plane:</p>
3494 <p class="filterformula">S<sub>x</sub> = pointsAtX - Light<sub>x</sub><br />
3495 S<sub>y</sub> = pointsAtY - Light<sub>y</sub><br />
3496 S<sub>z</sub> = pointsAtZ - Light<sub>z</sub><br />
3497 <br />
3498 S = (S<sub>x</sub>, S<sub>y</sub>, S<sub>z</sub>) / Norm(S<sub>x</sub>,
3499 S<sub>y</sub>, S<sub>z</sub>)</p>
3501 <p>
3502 If L.S is positive, no light is present. (L<sub>r</sub> = L<sub>g</sub> =
3503 L<sub>b</sub> = 0). If <a>'feSpotLight/limitingConeAngle'</a> is specified, -L.S < cos(limitingConeAngle) also indicates that no light is present.</p>
3505 <div class="adef-list">
3506 <p><em>Attribute definitions:</em></p>
3507 <dl>
3508 <dt id="feDiffuseLightingSurfaceScaleAttribute"><span
3509 class="adef">surfaceScale</span> = "<em><a><number></a></em>"</dt>
3510 <dd>height of surface when A<sub>in</sub> = 1.<br />
3511 If the attribute is not specified, then the effect is as if a value of
3512 <span class="attr-value">1</span> were specified.<br />
3513 <span class="anim-target">Animatable: yes.</span></dd>
3514 <dt id="feDiffuseLightingDiffuseConstantAttribute"><span
3515 class="adef">diffuseConstant</span> = "<em><a><number></a></em>"</dt>
3516 <dd>kd in Phong lighting model. In SVG, this can be any non-negative
3517 number.<br />
3518 If the attribute is not specified, then the effect is as if a value of
3519 <span class="attr-value">1</span> were specified.<br />
3520 <span class="anim-target">Animatable: yes.</span></dd>
3521 <dt id="feDiffuseLightingKernelUnitLengthAttribute"><span
3522 class="adef">kernelUnitLength</span> = "<span
3523 class="attr-value"><a><number-optional-number></a></span>"</dt>
3524 <dd>The first number is the <dx> value. The second number is the
3525 <dy> value. If the <dy> value is not specified, it defaults
3526 to the same value as <dx>. Indicates the intended distance in
3527 current filter units (i.e., units as determined by the value of
3528 attribute <a>'filter/primitiveUnits'</a>) for <code>dx</code> and
3529 <code>dy</code>, respectively, in the <a
3530 href="#SurfaceNormalCalculations">surface normal calculation
3531 formulas</a>. By specifying value(s) for <span
3532 class="attr-name">kernelUnitLength</span>, the kernel becomes defined
3533 in a scalable, abstract coordinate system. If <span
3534 class="attr-name">kernelUnitLength</span> is not specified, the
3535 <code>dx</code> and <code>dy</code> values should represent very small
3536 deltas relative to a given <code>(x,y)</code> position, which might be
3537 implemented in some cases as one pixel in the intermediate image
3538 offscreen bitmap, which is a pixel-based coordinate system, and thus
3539 potentially not scalable. For some level of consistency across display
3540 media and user agents, it is necessary that a value be provided for at
3541 least one of <a>'filter/filterRes'</a> and <span
3542 class="attr-name">kernelUnitLength</span>. Discussion of intermediate
3543 images are in the <a href="#Introduction">Introduction</a> and in the
3544 description of attribute <a>'filter/filterRes'</a>.<br />
3545 If a negative or zero value is specified the default value will be used
3546 instead. <br />
3547 <span class="anim-target">Animatable: yes.</span></dd>
3548 </dl>
3549 </div>
3551 <p>
3552 The light source is defined by one of the child elements <a>'feDistantLight'</a>,
3553 <a>'fePointLight'</a> or <a>'feSpotLight'</a>. The light color is specified
3554 by property <a>'lighting-color'</a>.</p>
3556 <h2 id="feDisplacementMapElement">Filter primitive <span class="element-name">'feDisplacementMap'</span></h2>
3558 <edit:elementsummary name='feDisplacementMap'/>
3560 <p>
3561 This filter primitive uses the pixels values from the image from <a>'feDisplacementMap/in2'</a>
3562 to spatially displace the image from <a>'in'</a>.
3563 This is the transformation to be performed:</p>
3565 <pre> P'(x,y) ← P( x + scale * (XC(x,y) - .5), y + scale * (YC(x,y) - .5))
3566 </pre>
3568 <p>
3569 where P(x,y) is the input image, <a>'in'</a>, and
3570 P'(x,y) is the destination. XC(x,y) and YC(x,y) are the component values of
3571 the channel designated by the <a>'feDisplacementMap/xChannelSelector'</a> and
3572 <a>'feDisplacementMap/yChannelSelector'</a>. For example, to use the R component of <a>'feDisplacementMap/in2'</a>
3573 to control displacement in x and the G component of Image2 to control
3574 displacement in y, set <a>'feDisplacementMap/xChannelSelector'</a> to <span class="attr-value">"R"</span> and
3575 <a>'feDisplacementMap/yChannelSelector'</a> to <span class="attr-value">"G"</span>.</p>
3577 <p>
3578 The displacement map, <a>'feDisplacementMap/in2'</a>, defines the inverse of the mapping
3579 performed.</p>
3581 <p>
3582 The input image in is to remain premultiplied for this filter primitive. The calculations using the pixel values from <a>'feDisplacementMap/in2'</a> are performed using non-premultiplied color values. If the image from <a>'feDisplacementMap/in2'</a> consists of premultiplied color values, those values are automatically converted into non-premultiplied color values before performing this operation.</p>
3584 <p>
3585 This filter can have arbitrary non-localized effect on the input which
3586 might require substantial buffering in the processing pipeline. However with
3587 this formulation, any intermediate buffering needs can be determined by
3588 <a>'feDisplacementMap/scale'</a> which represents the maximum range of displacement in either x
3589 or y.</p>
3591 <p>
3592 When applying this filter, the source pixel location will often lie
3593 between several source pixels. In this case it is recommended that high
3594 quality viewers apply an interpolent on the surrounding pixels, for example
3595 bilinear or bicubic, rather than simply selecting the nearest source pixel.
3596 Depending on the speed of the available interpolents, this choice may be
3597 affected by the <a>'image-rendering'</a> property
3598 setting.</p>
3600 <p>
3601 The <a>'color-interpolation-filters'</a> property only applies to the
3602 <a>'feDisplacementMap/in2'</a> source image and does not apply to the <a>'in'</a> source image.
3603 The <a>'in'</a> source image must remain in its current color space.
3604 </p>
3606 <div class="adef-list">
3607 <p><em>Attribute definitions:</em></p>
3608 <dl>
3609 <dt id="feDisplacementMapScaleAttribute"><span class="adef">scale</span>
3610 = "<em><a><number></a></em>"</dt>
3611 <dd>Displacement scale factor. The amount is expressed in the coordinate
3612 system established by attribute <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
3613 element.<br />
3614 When the value of this attribute is <span class="attr-value">0</span>,
3615 this operation has no effect on the source image.<br />
3616 <p>
3617 The <a>lacuna value</a> for <a>'feDisplacementMap/scale'</a> is <span class="attr-value">0</span>.</p>
3618 <span class="anim-target">Animatable: yes.</span></dd>
3619 <dt id="feDisplacementMapXChannelSelectorAttribute"><span
3620 class="adef">xChannelSelector</span> = "<em>R | G | B | A</em>"</dt>
3621 <dd>Indicates which channel from <a>'feDisplacementMap/in2'</a> to use to displace the pixels in <a>'in'</a> along the x-axis.
3622 The <a>lacuna value</a> for <a>'feDisplacementMap/xChannelSelector'</a> is <span class="attr-value">A</span>.
3623 <br />
3624 <span class="anim-target">Animatable: yes.</span></dd>
3625 <dt id="feDisplacementMapYChannelSelectorAttribute"><span
3626 class="adef">yChannelSelector</span> = "<em>R | G | B | A</em>"</dt>
3627 <dd>Indicates which channel from <a>'feDisplacementMap/in2'</a> to use to displace the pixels in <a>'in'</a> along the y-axis.
3628 The <a>lacuna value</a> for <a>'feDisplacementMap/yChannelSelector'</a> is <span class="attr-value">A</span>.
3629 <br />
3630 <span class="anim-target">Animatable: yes.</span></dd>
3631 <dt id="feDisplacementMapIn2Attribute"><span class="adef">in2</span> =
3632 "<em>(see <a>'in'</a> attribute)</em>"</dt>
3633 <dd>The second input image, which is used to displace the pixels in the
3634 image from attribute <a>'in'</a>. This attribute can take on the same
3635 values as the <a>'in'</a> attribute.<br />
3636 <span class="anim-target">Animatable: yes.</span></dd>
3637 </dl>
3638 </div>
3640 <h2 id="feFloodElement">Filter primitive <span
3641 class="element-name">'feFlood'</span></h2>
3643 <edit:elementsummary name='feFlood'/>
3645 <p>
3646 This filter primitive creates a rectangle filled with the color and
3647 opacity values from properties <span class="prop-name">'flood-color'</span>
3648 and <span class="prop-name">'flood-opacity'</span>. The rectangle is as large
3649 as the <a href="#FilterPrimitiveSubRegion">filter primitive subregion</a>
3650 established by the <span class="element-name">'feFlood'</span> element.</p>
3652 <div class="adef-list">
3653 </div>
3655 <p>
3656 The <span class="prop-name">'flood-color'</span> property indicates what
3657 color to use to flood the current <a href="#FilterPrimitiveSubRegion">filter
3658 primitive subregion</a>. The keyword <span
3659 class="attr-value">currentColor</span> and ICC colors can be specified in the
3660 same manner as within a <paint> specification for the <span
3661 class="prop-name">'fill'</span> and <span class="prop-name">'stroke'</span>
3662 properties.</p>
3664 <div class="propdef">
3665 <dl>
3666 <dt id="FloodColorProperty"><span class="propdef-title prop-name">'flood-color'</span></dt>
3667 <dd>
3668 <table summary="flood-color property" class="propinfo" cellspacing="0"
3669 cellpadding="0">
3670 <tbody>
3671 <tr valign="baseline">
3672 <td><em>Value:</em> </td>
3673 <td>currentColor |<br />
3674 <a><color></a>
3675 [<a><icccolor></a>] |<br />
3676 <a class="noxref"
3677 href="http://www.w3.org/TR/2009/CR-CSS2-20090423/cascade.html#value-def-inherit"><span
3678 class="value-inst-inherit noxref">inherit</span></a></td>
3679 </tr>
3680 <tr valign="baseline">
3681 <td><em>Initial:</em> </td>
3682 <td>black</td>
3683 </tr>
3684 <tr valign="baseline">
3685 <td><em>Applies to:</em> </td>
3686 <td><a href="#feFloodElement"><span
3687 class="element-name">'feFlood'</span></a> and <a
3688 href="#feDropShadowElement"><span
3689 class="element-name">'feDropShadow'</span></a> elements</td>
3690 </tr>
3691 <tr valign="baseline">
3692 <td><em>Inherited:</em> </td>
3693 <td>no</td>
3694 </tr>
3695 <tr valign="baseline">
3696 <td><em>Percentages:</em> </td>
3697 <td>N/A</td>
3698 </tr>
3699 <tr valign="baseline">
3700 <td><em>Media:</em> </td>
3701 <td>visual</td>
3702 </tr>
3703 <tr valign="baseline">
3704 <td><em>Animatable:</em> </td>
3705 <td>yes</td>
3706 </tr>
3707 </tbody>
3708 </table>
3709 </dd>
3710 </dl>
3711 </div>
3713 <p>
3714 The <span class="prop-name">'flood-opacity'</span> property defines the
3715 opacity value to use across the entire <a
3716 href="#FilterPrimitiveSubRegion">filter primitive subregion</a>.</p>
3718 <div class="propdef">
3719 <dl>
3720 <dt id="OpacityFloodOpacityProperty"><span class="propdef-title prop-name">'flood-opacity'</span></dt>
3721 <dd>
3722 <table summary="flood-opacity property" class="propinfo"
3723 cellspacing="0" cellpadding="0">
3724 <tbody>
3725 <tr valign="baseline">
3726 <td><em>Value:</em> </td>
3727 <td><opacity-value> | <a class="noxref"
3728 href="http://www.w3.org/TR/2009/CR-CSS2-20090423/cascade.html#value-def-inherit"><span
3729 class="value-inst-inherit noxref">inherit</span></a></td>
3730 </tr>
3731 <tr valign="baseline">
3732 <td><em>Initial:</em> </td>
3733 <td>1</td>
3734 </tr>
3735 <tr valign="baseline">
3736 <td><em>Applies to:</em> </td>
3737 <td><a href="#feFloodElement"><span
3738 class="element-name">'feFlood'</span></a> and <a
3739 href="#feDropShadowElement"><span
3740 class="element-name">'feDropShadow'</span></a> elements</td>
3741 </tr>
3742 <tr valign="baseline">
3743 <td><em>Inherited:</em> </td>
3744 <td>no</td>
3745 </tr>
3746 <tr valign="baseline">
3747 <td><em>Percentages:</em> </td>
3748 <td>N/A</td>
3749 </tr>
3750 <tr valign="baseline">
3751 <td><em>Media:</em> </td>
3752 <td>visual</td>
3753 </tr>
3754 <tr valign="baseline">
3755 <td><em>Animatable:</em> </td>
3756 <td>yes</td>
3757 </tr>
3758 </tbody>
3759 </table>
3760 </dd>
3761 </dl>
3762 </div>
3764 <h2 id="feGaussianBlurElement">Filter primitive <span
3765 class="element-name">'feGaussianBlur'</span></h2>
3767 <edit:elementsummary name='feGaussianBlur'/>
3768 <edit:with element='feGaussianBlur'>
3770 <p>
3771 This filter primitive performs a Gaussian blur on the input image.</p>
3773 <p>
3774 The Gaussian blur kernel is an approximation of the normalized
3775 convolution:</p>
3777 <p class="filterformula">G(x,y) = H(x)I(y)</p>
3778 <p>
3779 where</p>
3780 <p class="filterformula">H(x) = exp(-x<sup>2</sup>/ (2s<sup>2</sup>)) / sqrt(2* pi*s<sup>2</sup>)</p>
3781 <p>
3782 and</p>
3783 <p class="filterformula">I(x) = exp(-y<sup>2</sup>/ (2t<sup>2</sup>)) / sqrt(2* pi*t<sup>2</sup>)</p>
3784 <p>
3785 with 's' being the standard deviation in the x direction
3786 and 't' being the standard deviation in the y direction, as specified by <a>'stdDeviation'</a>.</p>
3788 <p>
3789 The value of <a>'stdDeviation'</a> can be either one or two numbers.
3790 If two numbers are provided, the first number represents a standard deviation
3791 value along the x-axis of the current coordinate system and the second value
3792 represents a standard deviation in Y. If one number is provided, then that
3793 value is used for both X and Y.</p>
3795 <p>
3796 Even if only one value is provided for <a>'stdDeviation'</a>, this can be implemented as a
3797 separable convolution.</p>
3799 <p>
3800 For larger values of 's' (s >= 2.0), an approximation can be used:
3801 Three successive box-blurs build a piece-wise quadratic convolution kernel,
3802 which approximates the Gaussian kernel to within roughly 3%.</p>
3804 <p class="filterformula">let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)</p>
3806 <p>... if d is odd, use three box-blurs of size 'd', centered on the output
3807 pixel.</p>
3809 <p>... if d is even, two box-blurs of size 'd' (the first one centered on the
3810 pixel boundary between the output pixel and the one to the left, the second
3811 one centered on the pixel boundary between the output pixel and the one to
3812 the right) and one box blur of size 'd+1' centered on the output pixel.</p>
3814 <p>
3815 The approximation formula also applies correspondingly to 't'.</p>
3817 <p>
3818 Frequently this operation will take place on alpha-only images, such as
3819 that produced by the built-in input, <a href="#SourceAlpha"><span
3820 class="attr-value">SourceAlpha</span></a>. The implementation may notice this
3821 and optimize the single channel case. If the input has infinite extent and is
3822 constant (e.g <span class="attr-value"><a href="#FillPaint">FillPaint</a></span>,
3823 this operation has no effect. If the input has infinite extent and the filter result
3824 is the input to an <a>'feTile'</a>, the filter is evaluated with periodic boundary conditions.</p>
3826 <div class="adef-list">
3827 <p><em>Attribute definitions:</em></p>
3828 <dl>
3829 <dt id="feGaussianBlurStdDeviationAttribute"><span
3830 class="adef">stdDeviation</span> =
3831 "<em><a><number-optional-number></a></em>"</dt>
3832 <dd>The standard deviation for the blur operation. If two <a><number></a>
3833 s are provided, the first number represents a standard deviation value
3834 along the x-axis of the coordinate system established by attribute <a>'filter/primitiveUnits'</a> on the <a
3835 href="#FilterElement"><span class="element-name">'filter'</span></a>
3836 element. The second value represents a standard deviation in Y. If one
3837 number is provided, then that value is used for both X and Y.<br />
3838 A value of zero disables the effect of the given filter primitive (i.e., the result is the filter input image).<br />
3839 If <a>'stdDeviation'</a> is <span class="attr-value">0</span> in only one of X or Y,
3840 then the effect is that the blur is only applied in the direction that has a non-zero value.
3841 <br />
3842 The <a>lacuna value</a> for <a>'stdDeviation'</a> is <span class="attr-value">0</span>.<br />
3843 <span class="anim-target">Animatable: yes.</span></dd>
3844 </dl>
3845 </div>
3847 <p><a href="#AnExample">The example</a> at the start of this chapter makes
3848 use of the <a>'feGaussianBlur'</a> filter primitive
3849 to create a drop shadow effect.</p>
3850 </edit:with>
3852 <h2 id="feUnsharpMaskElement">Filter primitive <span
3853 class="element-name">'feUnsharpMask'</span></h2>
3855 <edit:elementsummary name='feUnsharpMask'/>
3857 <p>
3858 This filter primitive performs an image sharpening operation on the input image. This is traditionally known as an unsharp mask operation.</p>
3860 <p>
3861 The filter first does a <a>'feGaussianBlur'</a> operation on the input image and then subtracts the difference between the input image and the blurred image.</p>
3863 <p>
3864 For controlling the result there are three attributes that can be used:
3865 </p>
3866 <ul>
3867 <li>the <a>'feUnsharpMask/stdDeviation'</a> attribute controls how much to blur the input image</li>
3868 <li>the <a>'feUnsharpMask/threshold'</a> attribute can be used for controlling when the difference should not be subtracted</li>
3869 <li>the <a>'feUnsharpMask/amount'</a> attribute specifies an optional multiplier for the difference to subtract</li>
3870 </ul>
3872 <h2 id="feImageElement">Filter primitive <span
3873 class="element-name">'feImage'</span></h2>
3875 <edit:elementsummary name='feImage'/>
3876 <edit:with element='feImage'>
3878 <p>
3879 This filter primitive refers to a graphic external to this filter element,
3880 which is loaded or rendered into an RGBA raster and becomes the result of the
3881 filter primitive.</p>
3883 <p>
3884 This filter primitive can refer to an external image or can be a reference
3885 to another piece of SVG. It produces an image similar to the built-in image
3886 source <a href="#SourceGraphic"><span
3887 class="attr-value">SourceGraphic</span></a> except that the graphic comes
3888 from an external source.</p>
3890 <p>
3891 If the <span class="attr-name">xlink:href</span> references a stand-alone
3892 image resource such as a JPEG, PNG or SVG file, then the image resource is
3893 rendered according to the behavior of the <span
3894 class="element-name">'image'</span> element; otherwise, the referenced
3895 resource is rendered according to the behavior of the <span
3896 class="element-name">'use'</span> element. In either case, the current user
3897 coordinate system depends on the value of attribute <a>'filter/primitiveUnits'</a> on the <a
3898 href="#FilterElement"><span class="element-name">'filter'</span></a> element.
3899 The processing of the <span class="attr-name">preserveAspectRatio</span>
3900 attribute on the <span class="element-name">'feImage'</span> element is
3901 identical to that of the <a>'image'</a> element.</p>
3903 <p><span class="requirement" id="assert_hqImageResampling">When the referenced image must be resampled to match the device coordinate
3904 system, it is recommended that high quality viewers make use of appropriate
3905 interpolation techniques, for example bilinear or bicubic.</span> Depending on the
3906 speed of the available interpolents, this choice may be affected by the <span
3907 class="prop-name">'image-rendering'</span> property setting.</p>
3909 <div class="adef-list">
3910 <p><em>Attribute definitions:</em></p>
3911 <dl>
3912 <dt id="feImageHrefAttribute"><span
3913 class="adef">xlink:href</span> =
3914 "<span class="attr-value"><IRI></span>"</dt>
3915 <dd>An <a>IRI reference</a>
3916 to an image resource or to an element.
3917 <br />
3918 <span class="anim-target">Animatable: yes.</span></dd>
3919 <dt id="feImageElementPreserveAspectRatioAttribute">
3920 <span class="adef">preserveAspectRatio</span> = "<span class='attr-value'>[defer] <align> [<meetOrSlice>]</span>"
3921 </dt>
3922 <dd>
3923 <p>
3924 See <a>'preserveAspectRatio'</a>.
3925 </p>
3926 <p>
3927 The lacuna value for <a>'preserveAspectRatio'</a> is <span class="attr-value">xMidYMid meet</span>.
3928 </p>
3929 <p><span class="anim-target">Animatable: yes.</span></p>
3930 </dd>
3931 </dl>
3932 </div>
3934 <p><span class="example-ref">Example feImage</span> illustrates how images are placed relative
3935 to an object. From left to right:</p>
3936 <ul>
3937 <li>
3938 The default placement of an image. Note that the image is
3939 centered in the <a>filter region</a> and has the maximum size that will
3940 fit in the region consistent with preserving the aspect ratio.
3941 </li>
3942 <li>
3943 The image stretched to fit the bounding box of an object.
3944 </li>
3945 <li>
3946 The image placed using user coordinates. Note that the image is
3947 first centered in a box the size of the <a>filter region</a> and has the
3948 maximum size that will fit in the box consistent with preserving
3949 the aspect ratio. This box is then shifted by the given <a>'x'</a> and
3950 <a>'y'</a> values relative to the viewport the object is in.
3951 </li>
3952 </ul>
3954 <edit:example href='examples/feImage-01.svg' name='feImage' description='Examples of feImage use' image='yes' link='yes'/>
3955 </edit:with>
3957 <h2 id="feMergeElement">Filter primitive <span
3958 class="element-name">'feMerge'</span></h2>
3960 <edit:elementsummary name='feMerge'/>
3961 <edit:elementsummary name='feMergeNode'/>
3963 <p>
3964 This filter primitive composites input image layers on top of each other
3965 using the <em>over</em> operator with <em>Input1</em> (corresponding to the
3966 first <a href="#feMergeNodeElement"><span
3967 class="element-name">'feMergeNode'</span></a> child element) on the bottom
3968 and the last specified input, <em>InputN</em> (corresponding to the last <a
3969 href="#feMergeNodeElement"><span
3970 class="element-name">'feMergeNode'</span></a> child element), on top.</p>
3972 <p>
3973 Many effects produce a number of intermediate layers in order to create
3974 the final output image. This filter allows us to collapse those into a single
3975 image. Although this could be done by using n-1 Composite-filters, it is more
3976 convenient to have this common operation available in this form, and offers
3977 the implementation some additional flexibility.</p>
3979 <p>
3980 Each 'feMerge' element can have any number of 'feMergeNode' subelements,
3981 each of which has an <a href="#CommonAttributes"><span
3982 class="attr-name">in</span></a> attribute.</p>
3984 <p>
3985 The canonical implementation of feMerge is to render the entire effect
3986 into one RGBA layer, and then render the resulting layer on the output
3987 device. In certain cases (in particular if the output device itself is a
3988 continuous tone device), and since merging is associative, it might be a
3989 sufficient approximation to evaluate the effect one layer at a time and
3990 render each layer individually onto the output device bottom to top.</p>
3992 <p>
3993 If the topmost image input is <a href="#SourceGraphic"><span
3994 class="attr-value">SourceGraphic</span></a> and this <span
3995 class="element-name">'feMerge'</span> is the last filter primitive in the
3996 filter, the implementation is encouraged to render the layers up to that
3997 point, and then render the <a href="#SourceGraphic"><span
3998 class="attr-value">SourceGraphic</span></a> directly from its vector
3999 description on top.</p>
4001 <p id="feMergeNode"><a href="#AnExample">The example</a> at the start of this chapter makes
4002 use of the <span class="element-name">feMerge</span> filter primitive to
4003 composite two intermediate filter results together.</p>
4005 <h2 id="feMorphologyElement">Filter primitive <span
4006 class="element-name">'feMorphology'</span></h2>
4008 <edit:elementsummary name='feMorphology'/>
4009 <edit:with element='feMorphology'>
4011 <p>
4012 This filter primitive performs "fattening" or "thinning" of artwork. It is
4013 particularly useful for fattening or thinning an alpha channel.</p>
4015 <p>
4016 The dilation (or erosion) kernel is a rectangle with a width of
4017 2*<em>x-radius</em> and a height of 2*<em>y-radius</em>. In dilation, the
4018 output pixel is the individual component-wise maximum of the corresponding
4019 R,G,B,A values in the input image's kernel rectangle. In erosion, the output
4020 pixel is the individual component-wise minimum of the corresponding R,G,B,A
4021 values in the input image's kernel rectangle.</p>
4023 <p>
4024 Frequently this operation will take place on alpha-only images, such as
4025 that produced by the built-in input, <a href="#SourceAlpha"><span
4026 class="attr-value">SourceAlpha</span></a>. In that case, the implementation
4027 might want to optimize the single channel case.</p>
4029 <p>
4030 If the input has infinite extent and is constant (e.g <span class="attr-value"><a href="#FillPaint">FillPaint</a></span>
4031 where the fill is a solid color), this operation has no effect.
4032 If the input has infinite extent and the filter result
4033 is the input to an <a>'feTile'</a>, the filter is evaluated with
4034 periodic boundary conditions.</p>
4036 <p>
4037 Because <span class="element-name">'feMorphology'</span> operates on
4038 premultipied color values, it will always result in color values less than or
4039 equal to the alpha channel.</p>
4041 <div class="adef-list">
4042 <p><em>Attribute definitions:</em></p>
4043 <dl>
4044 <dt id="feMorphologyOperatorAttribute"><span
4045 class="adef">operator</span> = "<em>erode | dilate</em>"</dt>
4046 <dd>A keyword indicating whether to erode (i.e., thin) or dilate (fatten)
4047 the source graphic.
4048 The lacuna value for <a>'operator'</a> is <span class="attr-value">erode</span>.
4049 <br />
4050 <span class="anim-target">Animatable: yes.</span></dd>
4051 <dt id="feMorphologyRadiusAttribute"><span class="adef">radius</span> =
4052 "<em><a><number-optional-number></a></em>"</dt>
4053 <dd>The radius (or radii) for the operation. If two <a><number></a>
4054 s are provided, the first number represents a x-radius and the second
4055 value represents a y-radius. If one number is provided, then that value
4056 is used for both X and Y. The values are in the coordinate system
4057 established by attribute <a>'filter/primitiveUnits'</a> on the <a
4058 href="#FilterElement"><span class="element-name">'filter'</span></a>
4059 element.<br />
4060 A negative or zero value disables the effect of the given filter
4061 primitive (i.e., the result is a transparent black image).<br />
4062 If the attribute is not specified, then the effect is as if a value of
4063 <span class="attr-value">0</span> were specified.<br />
4064 <span class="anim-target">Animatable: yes.</span></dd>
4065 </dl>
4066 </div>
4067 </edit:with>
4069 <edit:example href="examples/feMorphology.svg" image="yes" link="yes"/>
4071 <h2 id="feOffsetElement">Filter primitive <span
4072 class="element-name">'feOffset'</span></h2>
4074 <edit:elementsummary name='feOffset'/>
4076 <p>
4077 This filter primitive offsets the input image relative to its current
4078 position in the image space by the specified vector.</p>
4080 <p>
4081 This is important for effects like drop shadows.</p>
4083 <p>
4084 When applying this filter, the destination location may be offset by a
4085 fraction of a pixel in device space. <span class="requirement" id="assert_hqFeOffsetInterpolation">In this case a high quality viewer
4086 should make use of appropriate interpolation techniques, for example bilinear
4087 or bicubic.</span> This is especially recommended for dynamic viewers where this
4088 interpolation provides visually smoother movement of images. For static
4089 viewers this is less of a concern. Close attention should be made to the
4090 <span class="prop-name">'image-rendering'</span> property setting to
4091 determine the authors intent.</p>
4093 <div class="adef-list">
4094 <p><em>Attribute definitions:</em></p>
4095 <dl>
4096 <dt id="feOffsetDxAttribute"><span
4097 class="adef">dx</span> = "<em><a><number></a></em>"</dt>
4098 <dd>The amount to offset the input graphic along the x-axis. The offset
4099 amount is expressed in the coordinate system established by attribute
4100 <a>'filter/primitiveUnits'</a> on the <a>'filter element'</a>
4101 element.<br />
4102 If the attribute is not specified, then the effect is as if a value of
4103 <span class="attr-value">0</span> were specified.<br />
4104 <span class="anim-target">Animatable: yes.</span></dd>
4105 <dt id="feOffsetDyAttribute"><span
4106 class="adef">dy</span> = "<em><a><number></a></em>"</dt>
4107 <dd>The amount to offset the input graphic along the y-axis. The offset
4108 amount is expressed in the coordinate system established by attribute
4109 <a>'filter/primitiveUnits'</a> on the <a
4110 href="#FilterElement"><span class="element-name">'filter'</span></a>
4111 element.<br />
4112 If the attribute is not specified, then the effect is as if a value of
4113 <span class="attr-value">0</span> were specified.<br />
4114 <span class="anim-target">Animatable: yes.</span></dd>
4115 </dl>
4116 </div>
4118 <p><a href="#AnExample">The example</a> at the start of this chapter makes
4119 use of the <span class="element-name">feOffset</span> filter primitive to
4120 offset the drop shadow from the original source graphic.</p>
4122 <h2 id="feSpecularLightingElement">Filter primitive <span
4123 class="element-name">'feSpecularLighting'</span></h2>
4125 <edit:elementsummary name='feSpecularLighting'/>
4127 <p>
4128 This filter primitive lights a source graphic using the alpha channel as a
4129 bump map. The resulting image is an RGBA image based on the light color. The
4130 lighting calculation follows the standard specular component of the Phong
4131 lighting model. The resulting image depends on the light color, light
4132 position and surface geometry of the input bump map. The result of the
4133 lighting calculation is added. The filter primitive assumes that the viewer
4134 is at infinity in the z direction (i.e., the unit vector in the eye direction
4135 is (0,0,1) everywhere).</p>
4137 <p>
4138 This filter primitive produces an image which contains the specular
4139 reflection part of the lighting calculation. Such a map is intended to be
4140 combined with a texture using the <em>add</em> term of the
4141 <em>arithmetic</em> <a href="#feCompositeElement"><span
4142 class="element-name">'feComposite'</span></a> method. Multiple light sources
4143 can be simulated by adding several of these light maps before applying it to
4144 the texture image.</p>
4146 <p>
4147 The resulting RGBA image is computed as follows:</p>
4149 <p class="filterformula">S<sub>r</sub> = k<sub>s</sub> * pow(N.H,
4150 specularExponent) * L<sub>r<br />
4151 </sub> S<sub>g</sub> = k<sub>s</sub> * pow(N.H, specularExponent) *
4152 L<sub>g<br />
4153 </sub> S<sub>b</sub> = k<sub>s</sub> * pow(N.H, specularExponent) *
4154 L<sub>b<br />
4155 </sub> S<sub>a</sub> = max(S<sub>r,</sub> S<sub>g,</sub> S<sub>b</sub>)</p>
4157 <p>
4158 where</p>
4159 <dl>
4160 <dd>k<sub>s</sub> = specular lighting constant<br />
4161 N = surface normal unit vector, a function of x and y<br />
4162 H = "halfway" unit vector between eye unit vector and light unit
4163 vector<br />
4164 <br />
4165 L<sub>r</sub>,L<sub>g</sub>,L<sub>b</sub> = RGB components of light</dd>
4166 </dl>
4168 <p>
4169 See <a href="#feDiffuseLighting"><span
4170 class="element-name">'feDiffuseLighting'</span></a> for definition of N and
4171 (L<sub>r</sub>, L<sub>g</sub>, L<sub>b</sub>).</p>
4173 <p>
4174 The definition of H reflects our assumption of the constant eye vector E =
4175 (0,0,1):</p>
4177 <p class="filterformula">H = (L + E) / Norm(L+E)</p>
4179 <p>
4180 where L is the light unit vector.</p>
4182 <p>
4183 Unlike the <a href="#feDiffuseLighting"><span
4184 class="element-name">'feDiffuseLighting'</span></a>, the <span
4185 class="element-name">'feSpecularLighting'</span> filter produces a non-opaque
4186 image. This is due to the fact that the specular result
4187 (S<sub>r</sub>,S<sub>g</sub>,S<sub>b</sub>,S<sub>a</sub>) is meant to be
4188 added to the textured image. The alpha channel of the result is the max of
4189 the color components, so that where the specular light is zero, no additional
4190 coverage is added to the image and a fully white highlight will add
4191 opacity.</p>
4193 <p>
4194 The <a href="#feDiffuseLighting"><span
4195 class="element-name">'feDiffuseLighting'</span></a> and <span
4196 class="element-name">'feSpecularLighting'</span> filters will often be
4197 applied together. An implementation may detect this and calculate both maps
4198 in one pass, instead of two.</p>
4200 <div class="adef-list">
4201 <p><em>Attribute definitions:</em></p>
4202 <dl>
4203 <dt id="feSpecularLightingSurfaceScaleAttribute"><span
4204 class="adef">surfaceScale</span> = "<em><a><number></a></em>"</dt>
4205 <dd>height of surface when A<sub>in</sub> = 1.<br />
4206 If the attribute is not specified, then the effect is as if a value of
4207 <span class="attr-value">1</span> were specified.<br />
4208 <span class="anim-target">Animatable: yes.</span></dd>
4209 <dt id="feSpecularLightingSpecularConstantAttribute"><span
4210 class="adef">specularConstant</span> = "<em><a><number></a></em>"</dt>
4211 <dd>ks in Phong lighting model. In SVG, this can be any non-negative
4212 number.<br />
4213 If the attribute is not specified, then the effect is as if a value of
4214 <span class="attr-value">1</span> were specified.<br />
4215 <span class="anim-target">Animatable: yes.</span></dd>
4216 <dt id="feSpecularLightingSpecularExponentAttribute"><span
4217 class="adef">specularExponent</span> = "<em><a><number></a></em>"</dt>
4218 <dd>Exponent for specular term, larger is more "shiny". Range 1.0 to
4219 128.0.<br />
4220 If the attribute is not specified, then the effect is as if a value of
4221 <span class="attr-value">1</span> were specified.<br />
4222 <span class="anim-target">Animatable: yes.</span></dd>
4223 <dt id="feSpecularLightingKernelUnitLengthAttribute"><span
4224 class="adef">kernelUnitLength</span> = "<span
4225 class="attr-value"><a><number-optional-number></a></span>"</dt>
4226 <dd>The first number is the <dx> value. The second number is the
4227 <dy> value. If the <dy> value is not specified, it defaults
4228 to the same value as <dx>. Indicates the intended distance in
4229 current filter units (i.e., units as determined by the value of
4230 attribute <a>'filter/primitiveUnits'</a>) for <code>dx</code> and
4231 <code>dy</code>, respectively, in the <a
4232 href="#SurfaceNormalCalculations">surface normal calculation
4233 formulas</a>. By specifying value(s) for <span
4234 class="attr-name">kernelUnitLength</span>, the kernel becomes defined
4235 in a scalable, abstract coordinate system. If <span
4236 class="attr-name">kernelUnitLength</span> is not specified, the
4237 <code>dx</code> and <code>dy</code> values should represent very small
4238 deltas relative to a given <code>(x,y)</code> position, which might be
4239 implemented in some cases as one pixel in the intermediate image
4240 offscreen bitmap, which is a pixel-based coordinate system, and thus
4241 potentially not scalable. For some level of consistency across display
4242 media and user agents, it is necessary that a value be provided for at
4243 least one of <span class="attr-name">filterRes</span> and <span
4244 class="attr-name">kernelUnitLength</span>. Discussion of intermediate
4245 images are in the <a href="#Introduction">Introduction</a> and in the
4246 description of attribute <a>'filter/filterRes'</a>.<br />
4247 If a negative or zero value is specified the default value will be used
4248 instead. <br />
4249 <span class="anim-target">Animatable: yes.</span></dd>
4250 </dl>
4251 </div>
4253 <p>
4254 The light source is defined by one of the child elements <a>'feDistantLight'</a>,
4255 <a>'fePointLight'</a> or <a>'feDistantLight'</a>. The light color is
4256 specified by property <a>'lighting-color'</a>.</p>
4258 <p><a href="#AnExample">The example</a> at the start of this chapter makes
4259 use of the <span class="element-name">feSpecularLighting</span> filter
4260 primitive to achieve a highly reflective, 3D glowing effect.</p>
4262 <h2 id="feTileElement">Filter primitive <span
4263 class="element-name">'feTile'</span></h2>
4265 <edit:elementsummary name='feTile'/>
4267 <p>
4268 This filter primitive fills a target rectangle with a repeated, tiled
4269 pattern of an input image.
4270 The target rectangle is as large as the <a>filter primitive subregion</a> established
4271 by the <span class="element-name">'feTile'</span> element.
4272 </p>
4274 <p>
4275 Typically, the input image has been defined with its own <a>filter primitive subregion</a> in order to
4276 define a reference tile. <span class="element-name">'feTile'</span>
4277 replicates the reference tile in both X and Y to completely fill the target
4278 rectangle. The top/left corner of each given tile is at location
4279 <code>(x+i*width,y+j*height)</code>, where <code>(x,y)</code> represents the
4280 top/left of the input image's <a>filter primitive subregion</a>, <code>width</code>
4281 and <code>height</code> represent the width and height of the input image's
4282 <a>filter primitive subregion</a>, and <code>i</code> and <code>j</code> can be any
4283 integer value. In most cases, the input image will have a smaller <a>filter
4284 primitive subregion</a> than the <span class="element-name">'feTile'</span> in
4285 order to achieve a repeated pattern effect.</p>
4287 <p class="requirement" id="assertTileArtifacts">Implementers must take appropriate measures in constructing the tiled
4288 image to avoid artifacts between tiles, particularly in situations where the
4289 user to device transform includes shear and/or rotation. Unless care is
4290 taken, interpolation can lead to edge pixels in the tile having opacity
4291 values lower or higher than expected due to the interaction of painting
4292 adjacent tiles which each have partial overlap with particular pixels.</p>
4294 <div class="adef-list">
4295 </div>
4297 <h2 id="feTurbulenceElement">Filter primitive <span
4298 class="element-name">'feTurbulence'</span></h2>
4300 <edit:with element="feTurbulence">
4302 <p class="specissue">ISSUE: Consider phasing out this C algorithm in favor of Simplex noise, which is more HW friendly.</p>
4304 <p>
4305 This filter primitive creates an image using the Perlin turbulence
4306 function. It allows the synthesis of artificial textures like clouds or
4307 marble. For a detailed description the of the Perlin turbulence function, see
4308 "Texturing and Modeling", Ebert et al, AP Professional, 1994. The resulting
4309 image will fill the entire <a>filter primitive subregion</a> for this filter primitive.</p>
4311 <p>
4312 It is possible to create bandwidth-limited noise by synthesizing only one
4313 octave.</p>
4315 <p>
4316 The C code below shows the exact algorithm used for this filter effect.
4317 The <a>filter primitive subregion</a> is to be passed as the arguments fTileX,
4318 fTileY, fTileWidth and fTileHeight.</p>
4320 <p>
4321 For fractalSum, you get a turbFunctionResult that is aimed at a range of
4322 -1 to 1 (the actual result might exceed this range in some cases). To convert
4323 to a color value, use the formula <code>colorValue = ((turbFunctionResult *
4324 255) + 255) / 2</code>, then clamp to the range 0 to 255.</p>
4326 <p>
4327 For turbulence, you get a turbFunctionResult that is aimed at a range of 0
4328 to 1 (the actual result might exceed this range in some cases). To convert to
4329 a color value, use the formula <code>colorValue = (turbFunctionResult *
4330 255)</code>, then clamp to the range 0 to 255.</p>
4332 <p>
4333 The following order is used for applying the pseudo random numbers. An
4334 initial seed value is computed based on the <a>'seed'</a> attribute.
4335 Then the implementation computes the lattice
4336 points for R, then continues getting additional pseudo random numbers
4337 relative to the last generated pseudo random number and computes the lattice
4338 points for G, and so on for B and A.</p>
4340 <p>
4341 The generated color and alpha values are in the color space determined by
4342 the <a>'color-interpolation-filters'</a> property:</p>
4343 <pre class="svgsamplecompressed">/* Produces results in the range [1, 2**31 - 2].
4344 Algorithm is: r = (a * r) mod m
4345 where a = 16807 and m = 2**31 - 1 = 2147483647
4346 See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
4347 To test: the algorithm should produce the result 1043618065
4348 as the 10,000th generated number if the original seed is 1.
4349 */
4350 #define RAND_m 2147483647 /* 2**31 - 1 */
4351 #define RAND_a 16807 /* 7**5; primitive root of m */
4352 #define RAND_q 127773 /* m / a */
4353 #define RAND_r 2836 /* m % a */
4354 long setup_seed(long lSeed)
4355 {
4356 if (lSeed <= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;
4357 if (lSeed > RAND_m - 1) lSeed = RAND_m - 1;
4358 return lSeed;
4359 }
4360 long random(long lSeed)
4361 {
4362 long result;
4363 result = RAND_a * (lSeed % RAND_q) - RAND_r * (lSeed / RAND_q);
4364 if (result <= 0) result += RAND_m;
4365 return result;
4366 }
4367 #define BSize 0x100
4368 #define BM 0xff
4369 #define PerlinN 0x1000
4370 #define NP 12 /* 2^PerlinN */
4371 #define NM 0xfff
4372 static uLatticeSelector[BSize + BSize + 2];
4373 static double fGradient[4][BSize + BSize + 2][2];
4374 struct StitchInfo
4375 {
4376 int nWidth; // How much to subtract to wrap for stitching.
4377 int nHeight;
4378 int nWrapX; // Minimum value to wrap.
4379 int nWrapY;
4380 };
4381 static void init(long lSeed)
4382 {
4383 double s;
4384 int i, j, k;
4385 lSeed = setup_seed(lSeed);
4386 for(k = 0; k < 4; k++)
4387 {
4388 for(i = 0; i < BSize; i++)
4389 {
4390 uLatticeSelector[i] = i;
4391 for (j = 0; j < 2; j++)
4392 fGradient[k][i][j] = (double)(((lSeed = random(lSeed)) % (BSize + BSize)) - BSize) / BSize;
4393 s = double(sqrt(fGradient[k][i][0] * fGradient[k][i][0] + fGradient[k][i][1] * fGradient[k][i][1]));
4394 fGradient[k][i][0] /= s;
4395 fGradient[k][i][1] /= s;
4396 }
4397 }
4398 while(--i)
4399 {
4400 k = uLatticeSelector[i];
4401 uLatticeSelector[i] = uLatticeSelector[j = (lSeed = random(lSeed)) % BSize];
4402 uLatticeSelector[j] = k;
4403 }
4404 for(i = 0; i < BSize + 2; i++)
4405 {
4406 uLatticeSelector[BSize + i] = uLatticeSelector[i];
4407 for(k = 0; k < 4; k++)
4408 for(j = 0; j < 2; j++)
4409 fGradient[k][BSize + i][j] = fGradient[k][i][j];
4410 }
4411 }
4412 #define s_curve(t) ( t * t * (3. - 2. * t) )
4413 #define lerp(t, a, b) ( a + t * (b - a) )
4414 double noise2(int nColorChannel, double vec[2], StitchInfo *pStitchInfo)
4415 {
4416 int bx0, bx1, by0, by1, b00, b10, b01, b11;
4417 double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
4418 register i, j;
4419 t = vec[0] + PerlinN;
4420 bx0 = (int)t;
4421 bx1 = bx0+1;
4422 rx0 = t - (int)t;
4423 rx1 = rx0 - 1.0f;
4424 t = vec[1] + PerlinN;
4425 by0 = (int)t;
4426 by1 = by0+1;
4427 ry0 = t - (int)t;
4428 ry1 = ry0 - 1.0f;
4429 // If stitching, adjust lattice points accordingly.
4430 if(pStitchInfo != NULL)
4431 {
4432 if(bx0 >= pStitchInfo->nWrapX)
4433 bx0 -= pStitchInfo->nWidth;
4434 if(bx1 >= pStitchInfo->nWrapX)
4435 bx1 -= pStitchInfo->nWidth;
4436 if(by0 >= pStitchInfo->nWrapY)
4437 by0 -= pStitchInfo->nHeight;
4438 if(by1 >= pStitchInfo->nWrapY)
4439 by1 -= pStitchInfo->nHeight;
4440 }
4441 bx0 &= BM;
4442 bx1 &= BM;
4443 by0 &= BM;
4444 by1 &= BM;
4445 i = uLatticeSelector[bx0];
4446 j = uLatticeSelector[bx1];
4447 b00 = uLatticeSelector[i + by0];
4448 b10 = uLatticeSelector[j + by0];
4449 b01 = uLatticeSelector[i + by1];
4450 b11 = uLatticeSelector[j + by1];
4451 sx = double(s_curve(rx0));
4452 sy = double(s_curve(ry0));
4453 q = fGradient[nColorChannel][b00]; u = rx0 * q[0] + ry0 * q[1];
4454 q = fGradient[nColorChannel][b10]; v = rx1 * q[0] + ry0 * q[1];
4455 a = lerp(sx, u, v);
4456 q = fGradient[nColorChannel][b01]; u = rx0 * q[0] + ry1 * q[1];
4457 q = fGradient[nColorChannel][b11]; v = rx1 * q[0] + ry1 * q[1];
4458 b = lerp(sx, u, v);
4459 return lerp(sy, a, b);
4460 }
4461 double turbulence(int nColorChannel, double *point, double <a href="#feTurbulenceBaseFrequencyAttribute">fBaseFreqX</a>, double <a href="#feTurbulenceBaseFrequencyAttribute">fBaseFreqY</a>,
4462 int <a href="#feTurbulenceNumOctavesAttribute">nNumOctaves</a>, bool bFractalSum, bool bDoStitching,
4463 double <a href="#FilterPrimitiveSubRegion">fTileX</a>, double <a href="#FilterPrimitiveSubRegion">fTileY</a>, double <a href="#FilterPrimitiveSubRegion">fTileWidth</a>, double <a href="#FilterPrimitiveSubRegion">fTileHeight</a>)
4464 {
4465 StitchInfo stitch;
4466 StitchInfo *pStitchInfo = NULL; // Not stitching when NULL.
4467 // Adjust the base frequencies if necessary for stitching.
4468 if(bDoStitching)
4469 {
4470 // When stitching tiled turbulence, the frequencies must be adjusted
4471 // so that the tile borders will be continuous.
4472 if(fBaseFreqX != 0.0)
4473 {
4474 double fLoFreq = double(floor(fTileWidth * fBaseFreqX)) / fTileWidth;
4475 double fHiFreq = double(ceil(fTileWidth * fBaseFreqX)) / fTileWidth;
4476 if(fBaseFreqX / fLoFreq < fHiFreq / fBaseFreqX)
4477 fBaseFreqX = fLoFreq;
4478 else
4479 fBaseFreqX = fHiFreq;
4480 }
4481 if(fBaseFreqY != 0.0)
4482 {
4483 double fLoFreq = double(floor(fTileHeight * fBaseFreqY)) / fTileHeight;
4484 double fHiFreq = double(ceil(fTileHeight * fBaseFreqY)) / fTileHeight;
4485 if(fBaseFreqY / fLoFreq < fHiFreq / fBaseFreqY)
4486 fBaseFreqY = fLoFreq;
4487 else
4488 fBaseFreqY = fHiFreq;
4489 }
4490 // Set up initial stitch values.
4491 pStitchInfo = &stitch;
4492 stitch.nWidth = int(fTileWidth * fBaseFreqX + 0.5f);
4493 stitch.nWrapX = fTileX * fBaseFreqX + PerlinN + stitch.nWidth;
4494 stitch.nHeight = int(fTileHeight * fBaseFreqY + 0.5f);
4495 stitch.nWrapY = fTileY * fBaseFreqY + PerlinN + stitch.nHeight;
4496 }
4497 double fSum = 0.0f;
4498 double vec[2];
4499 vec[0] = point[0] * fBaseFreqX;
4500 vec[1] = point[1] * fBaseFreqY;
4501 double ratio = 1;
4502 for(int nOctave = 0; nOctave < nNumOctaves; nOctave++)
4503 {
4504 if(bFractalSum)
4505 fSum += double(noise2(nColorChannel, vec, pStitchInfo) / ratio);
4506 else
4507 fSum += double(fabs(noise2(nColorChannel, vec, pStitchInfo)) / ratio);
4508 vec[0] *= 2;
4509 vec[1] *= 2;
4510 ratio *= 2;
4511 if(pStitchInfo != NULL)
4512 {
4513 // Update stitch values. Subtracting PerlinN before the multiplication and
4514 // adding it afterward simplifies to subtracting it once.
4515 stitch.nWidth *= 2;
4516 stitch.nWrapX = 2 * stitch.nWrapX - PerlinN;
4517 stitch.nHeight *= 2;
4518 stitch.nWrapY = 2 * stitch.nWrapY - PerlinN;
4519 }
4520 }
4521 return fSum;
4522 }</pre>
4524 <div class="adef-list">
4525 <p><em>Attribute definitions:</em></p>
4526 <dl>
4527 <dt id="feTurbulenceBaseFrequencyAttribute"><span
4528 class="adef">baseFrequency</span> =
4529 "<em><a><number-optional-number></a></em>"</dt>
4530 <dd>
4531 <p>
4532 The base frequency (frequencies) parameter(s) for the noise function.
4533 If two <a><number></a>s are provided, the first number represents a base frequency in the X
4534 direction and the second value represents a base frequency in the Y
4535 direction. If one number is provided, then that value is used for both
4536 X and Y.</p>
4537 <p>
4538 The <a>lacuna value</a> for <a>'baseFrequency'</a> is <span class="attr-value">0</span>.</p>
4539 <p>
4540 Negative values are <a>unsupported</a>.</p>
4541 <p><span class="anim-target">Animatable: yes.</span></p>
4542 </dd>
4543 <dt id="feTurbulenceNumOctavesAttribute"><span
4544 class="adef">numOctaves</span> = "<em><a><integer></a></em>"</dt>
4545 <dd>
4546 <p>
4547 The numOctaves parameter for the noise function.</p>
4548 <p><span class="requirement" id="assert_turbulenceNumOctavesLacunaValue">The <a>lacuna value</a> for <a>'numOctaves'</a> is <span class="attr-value">1</span>.</span></p>
4549 <p><span class="requirement" id="assert_turbulenceNumOctavesUnsupportedValue">Negative values are <a>unsupported</a>.</span></p>
4550 <p><span class="requirement" id="assert_turbulenceNumOctavesAnimatable"><span class="anim-target">Animatable: yes.</span></span></p>
4551 </dd>
4552 <dt id="feTurbulenceSeedAttribute">
4553 <span class="adef">seed</span> = "<em><a><number></a></em>"</dt>
4554 <dd>
4555 <p>
4556 The starting number for the pseudo random number generator.</p>
4557 <p><span class="requirement" id="assert_turbulenceSeedLacunaValue">The <a>lacuna value</a> for <a>'seed'</a> is <span class="attr-value">0</span>.</span></p>
4558 <p><span class="requirement" id="assert_turbulenceSeedTruncation">When the seed number is handed over to the algorithm above it must first be
4559 truncated, i.e. rounded to the closest integer value towards zero.</span></p>
4560 <p><span class="anim-target">Animatable: yes.</span></p>
4561 </dd>
4562 <dt id="feTurbulenceStitchTilesAttribute"><span
4563 class="adef">stitchTiles</span> = "<em>stitch | noStitch</em>"</dt>
4564 <dd>
4565 <p>
4566 If <span class="attr-value">stitchTiles="noStitch"</span>, no attempt
4567 it made to achieve smooth transitions at the border of tiles which
4568 contain a turbulence function. Sometimes the result will show clear
4569 discontinuities at the tile borders.<br />
4570 If <span class="attr-value">stitchTiles="stitch"</span>, then the user
4571 agent will automatically adjust baseFrequency-x and baseFrequency-y
4572 values such that the <a>'feTurbulence'</a> node's width and height (i.e., the
4573 width and height of the current subregion) contains an integral number
4574 of the Perlin tile width and height for the first octave. The
4575 baseFrequency will be adjusted up or down depending on which way has
4576 the smallest relative (not absolute) change as follows: Given the
4577 frequency, calculate <code>lowFreq=floor(width*frequency)/width</code>
4578 and <code>hiFreq=ceil(width*frequency)/width</code>. If
4579 frequency/lowFreq < hiFreq/frequency then use lowFreq, else use
4580 hiFreq. While generating turbulence values, generate lattice vectors as
4581 normal for Perlin Noise, except for those lattice points that lie on
4582 the right or bottom edges of the active area (the size of the resulting
4583 tile). In those cases, copy the lattice vector from the opposite edge
4584 of the active area.</p>
4585 <p><span class="requirement" id="assert_turbulenceStitchTilesLacunaValue">The <a>lacuna value</a> for <a>'stitchTiles'</a> is <span class="attr-value">noStitch</span>.</span></p>
4586 <p><span class="anim-target">Animatable: yes.</span></p>
4587 </dd>
4588 <dt id="feTurbulenceTypeAttribute">
4589 <span class="adef">type</span> = "<em>fractalNoise | turbulence</em>"</dt>
4590 <dd>
4591 <p>
4592 Indicates whether the filter primitive should perform a noise or
4593 turbulence function.</p>
4594 <p><span class="requirement" id="assert_turbulenceTypeLacunaValue">The <a>lacuna value</a> for <a>'type'</a> is <span class="attr-value">turbulence</span>.</span></p>
4595 <p><span class="anim-target">Animatable: yes.</span></p>
4596 </dd>
4597 </dl>
4598 </div>
4600 <edit:example href="examples/feTurbulence.svg" image="yes" link="yes"/>
4601 </edit:with>
4603 <h2 id="feDropShadowElement">Filter primitive <span
4604 class="element-name">'feDropShadow'</span></h2>
4606 <edit:elementsummary name='feDropShadow'/>
4608 <p>
4609 This filter creates a drop shadow of the input image. It is a shorthand
4610 filter, and is defined in terms of combinations of other <a>filter primitives</a>.
4611 The expectation is that it can be optimized more easily by
4612 implementations.</p>
4614 <p>
4615 The result of a <a>'feDropShadow'</a> filter
4616 primitive is equivalent to the following:
4617 </p>
4619 <pre class="examplesource">
4620 <feGaussianBlur in="<b>alpha-channel-of-feDropShadow-in</b>" stdDeviation="<b>stdDeviation-of-feDropShadow</b>"/>
4621 <feOffset dx="<b>dx-of-feDropShadow</b>" dy="<b>dy-of-feDropShadow</b>" result="offsetblur"/>
4622 <feFlood flood-color="<b>flood-color-of-feDropShadow</b>" flood-opacity="<b>flood-opacity-of-feDropShadow</b>"/>
4623 <feComposite in2="offsetblur" operator="in"/>
4624 <feMerge>
4625 <feMergeNode/>
4626 <feMergeNode in="<b>in-of-feDropShadow</b>"/>
4627 </feMerge>
4628 </pre>
4630 <p>
4631 The above divided into steps:
4632 </p>
4633 <ol>
4634 <li>Take the alpha channel of the input to the <a>'feDropShadow'</a> filter primitive and the <a>'feDropShadow/stdDeviation'</a> on the <a>'feDropShadow'</a> and do processing as if the
4635 following <a>'feGaussianBlur'</a> was applied:
4636 <pre class="examplesource"> <feGaussianBlur in="<b>alpha-channel-of-feDropShadow-in</b>" stdDeviation="<b>stdDeviation-of-feDropShadow</b>"/></pre>
4637 <br />
4638 </li>
4639 <li>Offset the result of step 1 by <a>'feDropShadow/dx'</a> and <a>'feDropShadow/dy'</a> as
4640 specified on the <a>'feDropShadow'</a>
4641 element, equivalent to applying an <a>'feOffset'</a> with these parameters:
4642 <pre class="examplesource"> <feOffset dx="<b>dx-of-feDropShadow</b>" dy="<b>dy-of-feDropShadow</b>" result="offsetblur"/></pre>
4643 <br />
4644 </li>
4645 <li>Do processing as if an <a>'feFlood'</a> element with <a>'flood-color'</a> and
4646 <a>'flood-opacity'</a> as specified on the <a>'feDropShadow'</a> was applied:
4647 <pre class="examplesource"> <feFlood flood-color="<b>flood-color-of-feDropShadow</b>" flood-opacity="<b>flood-opacity-of-feDropShadow</b>"/></pre>
4648 <br />
4649 </li>
4650 <li>Composite the result of the <a href="#feFloodElement"><span
4651 class="element-name">'feFlood'</span></a> in step 3 with the result of
4652 the <a href="#feOffsetElement"><span
4653 class="element-name">'feOffset'</span></a> in step 2 as if an <a>'feComposite'</a> filter primitive with <a
4654 href="#feCompositeOperatorAttribute"><span
4655 class="attr-name">operator</span></a>='in' was applied:
4656 <pre class="examplesource"> <feComposite in2="offsetblur" operator="in"/></pre>
4657 <br />
4658 </li>
4659 <li>Finally merge the result of the previous step, doing processing as if
4660 the following <a>'feMerge'</a> was performed:
4661 <pre class="examplesource"> <feMerge>
4662 <feMergeNode/>
4663 <feMergeNode in="<b>in-of-feDropShadow</b>"/>
4664 </feMerge></pre>
4665 </li>
4666 </ol>
4668 <p class="note implementation">Note that while the definition of the <span
4669 class="element-name">'feDropShadow'</span> filter primitive says that it can
4670 be expanded into an equivalent tree it is not required that it is implemented
4671 like that. The expectation is that user agents can optimize the handling by not having to do all the steps separately.
4672 </p>
4674 <p>
4675 Beyond the DOM interface <a
4676 href="#InterfaceSVGFEDropShadowElement">SVGFEDropShadowElement</a> there is no way
4677 of accessing the internals of the <a>'feDropShadow'</a> filter primitive, meaning <span class="requirement" id="assert_dropShadowShadowTrees">if the
4678 filter primitive is implemented as an equivalent tree then that tree must not
4679 be exposed to the DOM.</span> </p>
4681 <div class="adef-list">
4682 <p><em>Attribute definitions:</em></p>
4683 <dl>
4684 <dt id="feDropShadowDxAttribute">
4685 <span class="adef">dx</span> = "<em><a><number></a></em>"</dt>
4686 <dd>
4687 <p>
4688 The x offset of the drop shadow.</p>
4689 <p>
4690 The <a>lacuna value</a> for <a>'feDropShadow/dx'</a> is <span class="attr-value">2</span>.</p>
4691 <p>
4692 This attribute is then forwarded to the <a>'feOffset/dx'</a> attribute of the internal <a>'feOffset'</a> element.</p>
4693 <p><span class="anim-target">Animatable: yes.</span></p>
4694 </dd>
4695 <dt id="feDropShadowDyAttribute">
4696 <span class="adef">dy</span> = "<em><a><number></a></em>"</dt>
4697 <dd>
4698 <p>
4699 The y offset of the drop shadow.</p>
4700 <p>
4701 The <a>lacuna value</a> for <a>'feDropShadow/dy'</a> is <span class="attr-value">2</span>. </p>
4702 <p>
4703 This attribute is then forwarded to the <a>'feOffset/dy'</a> attribute of the internal <a>'feOffset'</a> element.</p>
4704 <p><span class="anim-target">Animatable: yes.</span></p>
4705 </dd>
4706 <dt id="feDropShadowStdDeviationAttribute"><span
4707 class="adef">stdDeviation</span> =
4708 "<em><a><number-optional-number></a></em>"</dt>
4709 <dd>
4710 <p>
4711 The standard deviation for the blur operation in the drop shadow.</p>
4712 <p>
4713 The <a>lacuna value</a> for <a>'feDropShadow/stdDeviation'</a> is <span class="attr-value">2</span>.</p>
4714 <p>
4715 This attribute is then forwarded to the <a>'feGaussianBlur/stdDeviation'</a> attribute of the internal
4716 <a>'feGaussianBlur'</a> element.</p>
4717 <p><span class="anim-target">Animatable: yes.</span></p>
4718 </dd>
4719 </dl>
4720 </div>
4722 <div class="note">
4723 <h2 id="feDiffuseSpecularElement">Filter primitive <span
4724 class="element-name">'feDiffuseSpecular'</span></h2>
4725 The WG is looking at providing a shorthand for diffuse+specular.
4726 </div>
4728 <h2 id="feCustomElement">Filter primitive <span
4729 class="element-name">'feCustom'</span></h2>
4732 <p>The <a href="https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/publish/Filters.html">Filter Effects</a>
4733 specification does not define the <code>feCustom</code> element. This document proposes the following
4734 definition.</p>
4736 <div class="element-summary">
4737 <div class="element-summary-name">
4738 <span class="element-name">‘feCustom’</span>
4739 </div>
4740 <dl>
4741 <dt>Content model:</dt>
4742 <dd>Any number of the following elements, in any order:
4743 <ul class="no-bullets">
4744 <li><a href="http://www.w3.org/TR/2003/REC-SVG11-20030114/animate.html#AnimateElement"><span class="element-name">‘animate’</span></a></li>
4745 <li><a href="http://www.w3.org/TR/2003/REC-SVG11-20030114/animate.html#SetElement"><span class="element-name">‘set’</span></a></li>
4746 </ul>
4747 </dd>
4748 <dt>Attributes:</dt>
4749 <dd>
4750 <ul class="no-bullets">
4751 <li><a href="http://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#TermCoreAttributes">core attributes</a></li>
4752 <li><a href="http://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#TermPresentationAttribute">presentation attributes</a></li>
4753 <li><a href="http://www.w3.org/TR/2003/REC-SVG11-20030114/intro.html#TermFilterPrimitiveAttributes">filter primitive attributes</a></li>
4754 <li><a href="http://www.w3.org/TR/SVG/styling.html#ClassAttribute"><span class="attr-name">‘class’</span></a></li>
4755 <li><a href="http://www.w3.org/TR/SVG/styling.html#StyleAttribute"><span class="attr-name">‘style’</span></a></li>
4756 <li><a href="#feCustomVertexShaderAttribute"><span class="attr-name">‘vertexShader’</span></a></li>
4757 <li><a href="#feCustomFragmentShaderAttribute"><span class="attr-name">‘fragmentShader’</span></a></li>
4758 <li><a href="#feCustomVertexMeshAttribute"><span class="attr-name">‘vertexMesh’</span></a></li>
4759 <li><a href="#feCustomParams"><span class="attr-name">‘params’</span></a></li>
4760 </ul>
4761 </dd>
4762 </dl>
4763 </div>
4765 <div>
4766 <dl>
4767 <dt id="feCustomVertexShaderAttribute">vertexShader: <code><uri></code></dt>
4768 <dd>The shader at <uri> provides the implementation for the <code>feCustom</code>
4769 vertex shader. If the
4770 shader cannot be retrieved, or if the shader cannot be loaded or compiled because it contains erroneous code, the shader is a <a href="#default-shaders">pass through</a>. Otherwise, the vertex shader is invoked for all the vertex mesh vertices.
4771 </dd>
4772 </dl>
4773 <dl>
4774 <dt id="feCustomFragmentShaderAttribute">fragmentShader: <code><uri></code></dt>
4775 <dd>The shader at <uri> provides the implementation for the <code>feCustom</code>
4776 fragment shader. If the
4777 shader cannot be retrieved, or if the shader cannot be loaded or compiled because it contains erroneous code, the shader is a <a href="#default-shaders">pass through</a>. Otherwise, the fragment shader
4778 is invoked for each of the pixels during the rasterization phase that follows
4779 the vertex shader processing.
4780 </dd>
4781 </dl>
4782 <dl>
4783 <dt id="feCustomVertexMeshAttribute">vertexMesh: <code>+<integer>{1,2}[wsp<box>][wsp'detached']</code></dt>
4784 <dd>See the <a href='#vertexMesh-attribute'>vertexMesh</a> attribute discussion</dd>
4785 </dl>
4786 <dl>
4787 <dt id="feCustomParamsAttribute">params: <code>[<param-def>[,<param-def>*]]</code></dt>
4788 <dd>
4789 Parameters are passed as uniforms to both the vertex and the fragment shaders.
4790 <table class="values-desc">
4791 <tr>
4792 <td id="param-def"><param-def></td>
4793 <td> <param-name>wsp<param-value></td>
4794 </tr>
4795 <tr>
4796 <td><param-name></td>
4797 <td><ident></td>
4798 </tr>
4799 <tr>
4800 <td><param-value></td>
4801 <td>true|false[wsp+true|false]{0-3} | <br />
4802 <number>[wsp+<number>]{0-3} | <br/>
4803 <array> | <br />
4804 <transform> | <br />
4805 <texture(<uri>)></td>
4806 </tr>
4807 <tr>
4808 <td><array></td>
4809 <td>'array('<number>[wsp<number>]*')'</td>
4810 </tr>
4811 <tr>
4812 <td><transform></td>
4813 <td><css-3d-transform> | <mat></td>
4814 </tr>
4815 <tr>
4816 <td><css-3d-transform></td>
4817 <td><a href="http://www.w3.org/TR/css3-3d-transforms/#transform-functions"><transform-function></a>;[<transform-function>]*
4818 </tr>
4819 <tr>
4820 <td><mat></td>
4821 <td>'mat2('<number>(,<number>){3}')' | <br/>
4822 'mat3('<number>(,<number>){8}')' | <br/>
4823 'mat4('<number>(,<number>){15}')'
4824 )</td>
4825 </tr>
4826 <tr></tr>
4827 </table>
4829 <p>There are two ways to specify a 4x4 matrix. They differ in
4830 <a href="#integration-with-css-animations-transitions">how
4831 they are interpolated.</a></p>
4833 <p>The <code><mat></code> values are in column major order.
4834 For example, <code>mat2(1, 2, 3, 4)</code> has <code>[1, 2]</code> in the
4835 first column and <code>[3, 4]</code> in the second one.</p>
4836 </dd>
4837 </dl>
4838 </div>
4840 <div class="note">There may be different ways to specify the <param-value> syntax. For example, it
4841 might be better to not have a <code>texture()</code> function and simply a <uri> for texture
4842 parameters. Or it might be better to not have a <code>mat<n></code> prefixes for matrices.</div>
4844 <div class="note">
4845 <p>The following <a href="https://developer.mozilla.org/en/WebGL/Adding_2D_content_to_a_WebGL_context">document</a> from Mozilla
4846 describes how WebGL vertex and fragment shaders can be defined in <code><script></code> elements.</p>
4848 <p>CSS shaders can reference shaders defined in <code><script></code> elements, as shown in the
4849 following code snippet.</p>
4851 <div><code class="xml"><pre>
4852 <script id="warp" type="x-shader/x-vertex" >
4853 <-- source code here -->
4854 </script>
4856 ..
4857 <style>
4858 .shaded {
4859 filter: custom(url(#warp));
4860 }</pre></code>
4861 </div>
4862 </div>
4863 <h4 id="vertexMesh-attribute">The 'vertexMesh' attribute</h4>
4865 <p>The <code><feCustom></code>'s 'vertexMesh' attribute defines the granularity of vertices in
4866 the <a href="#vertex-mesh">shader mesh</a>. By default,
4867 the vertex mesh is made of two triangles that encompass the <a href="#filter-region">filter region</a> area.</p>
4869 <dl>
4870 <dt><code>+<integer>{1,2}[wsp<box>][wsp'detached']</code></dt>
4871 <dd>
4872 One or two positive integers (zero is invalid) indicating the additional number
4873 of vertex lines and columns that will make the vertex
4874 mesh. With the initial value of '1 1' there is a single line and a single column, resulting in
4875 a four-vertices mesh (top-left, top-right, bottom-right, bottom-left). If only one value is specified, the
4876 second (columns) value computes to the first value. In other words, a value of 'n' is equivalent to a
4877 value of 'n n'.<br />
4878 A value of 'n m' results in a vertex mesh that has 'n' lines and 'm' column and a total of
4879 'n + 1'.'m + 1' vertices as illustrated in the following figure.
4881 <p>The optional <box> parameter defines the box on which the vertex mesh is stretched to.
4882 It defaults to the 'filter-box' value which is 'border-box' with the added filter margins.
4883 For elements that do not have padding or borders (e.g., SVG elements), the values 'padding-box'
4884 and 'border-box' are equivalent to 'content-box'. For SVG elements, the 'content-box' is
4885 the object bounding box.</p>
4887 <p>The optional 'detached' string specifies whether the mesh triangles are attached or detached.
4888 If the value is not specified, the triangles are attached. If 'detached' is specified, the
4889 triangles are detached. When triangles are attached, the geometry provided to the vertex shader
4890 is made of a triangles which share adjacent edges' vertices. In the 'detached'
4891 mode, the triangles do not share edges.</p>
4893 <p>In the following figure, let us consider the top-left 'tile' in the shader mesh.
4894 In the detached mode, the vertex shader will receive the bottom right and top left
4895 vertices multiple time, one of each of the two triangles which make up the tile.
4896 Otherwise, the shader will receive these vertices only once, because they are
4897 shared by the 'connected' triangles.</p>
4899 <p>See the discussion on uniforms passed to shaders to
4900 understand how the shader programs can leverage that feature.</p>
4901 </dd>
4902 </dl>
4904 <div class="figure">
4905 <img src="images/shader-mesh-property.png" width="300" />
4906 <p class="caption">vertexMesh: 6 5</p>
4907 </div>
4909 <p>The above figure illustrates how a 'vertexMesh' value of '5 4' adds vertices passed to the vertex shader.
4910 The red vertices are the default ones and the gray vertices are resulting from the 'vertexMesh' value.</p>
4912 <div class="example">
4913 <p>The following example applies a vertex shader ('distort.vs') to elements with class 'distorted'.
4914 The vertex shader will operate on a mesh that has 5 lines and 4 columns (because there are 4 additional
4915 lines and 3 additional columns).</p>
4917 <code class="idl"><pre>
4918 <style>
4919 .distorted {
4920 filter: custom(url(distort.vs), 4 3);
4921 }
4922 </style>
4924 ...
4925 <div class="distorted">
4926 ..
4927 </div></pre></code>
4929 which could also be written as:
4931 <code class="idl"><pre>
4932 <style>
4933 .distorted {
4934 filter: url(#distort);
4935 }
4936 </style>
4938 ...
4940 <filter id="distort">
4941 <feCustom vertexShader="url(distort.vs)" vertexMesh="4 3" />
4942 </filter>
4944 <div class="distorted">
4945 ..
4946 </div></pre></code>
4947 </div>
4949 <h3 id="shader-inputs">Shader inputs in filter graph</h3>
4951 <p>When an <code>feCustom</code> filter primitive is used in a filter graph, a 'texture' parameter
4952 can take a value of 'result(<name>)' where 'name' is the output of another filter primitive.</p>
4954 <code class="idl"><pre>
4955 <filter>
4956 <feGaussianBlur stdDeviation="8" result="blur" />
4957 <feTurbulence type="fractalNoise" baseFrequency="0.4" numOctaves="4" result="turbulence"/>
4958 <feCustom fragmentShader="url(complex.fs)" params="tex1 result(blur), tex2 result(turbulence)" />
4959 </filter></pre></code>
4962 <h2 id="FilterCSSImageValue">The filter CSS <image> value</h2>
4964 <p>
4965 The filter() function produces a CSS <image> value. It has the following syntax:
4966 </p>
4968 <h4 class='no-toc' id='filter-syntax'>
4969 filter() syntax</h4>
4971 <pre class='prod'><code><dfn><filter></dfn> = filter(
4972 <image>,
4973 none | <filter-function> [ <filter-function> ]*
4974 )
4975 </code></pre>
4977 <p>
4978 The function takes two parameters. The first is a CSS <image> value. The second
4979 is the value of a <span class="prop-name">filter</span> property. The function take the
4980 input image parameter and apply the filter rules, returning a processing image.
4981 </p>
4983 <h2 id="RelaxNG">RelaxNG Schema for Filter Effects 1.0</h2>
4985 <p>
4986 The schema for Filter Effects 1.0 is written in <a
4987 href="http://www.y12.doe.gov/sgml/sc34/document/0362_files/relaxng-is.pdf">RelaxNG</a>
4988 [<a href="#ref-RNG">RelaxNG</a>], a namespace-aware schema language that uses
4989 the datatypes from <a
4990 href="http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/">XML Schema Part
4991 2</a> [<a href="#ref-Schema2">Schema2</a>]. This allows namespaces and
4992 modularity to be much more naturally expressed than using DTD syntax. The
4993 RelaxNG schema for Filter Effects 1.0 may be imported by other RelaxNG schemas,
4994 or combined with other schemas in other languages into a multi-namespace,
4995 multi-grammar schema using <a
4996 href="http://www.asahi-net.or.jp/~eb2m-mrt/dsdl/">Namespace-based Validation
4997 Dispatching Language</a> [<a href="#ref-NVDL">NVDL</a>].</p>
4999 <p>
5000 Unlike a DTD, the schema used for validation is not hardcoded into the
5001 document instance. There is no equivalent to the DOCTYPE declaration. Simply
5002 point your editor or other validation tool to the IRI of the schema (or your
5003 local cached copy, as you prefer).</p>
5005 <p>
5006 The RNG is under construction, and only the individual RNG snippets are available at this time. They have not yet been integrated into a functional schema. The individual RNG files are available <a href="rng">here</a>.
5007 </p>
5010 <h2 id="ShorthandEquivalents">Shorthands defined in terms of the <span class="element-name">'filter'</span> element</h2>
5012 <p>
5013 Below are the equivalents for each of the filter functions expressed in terms of
5014 the 'filter element' element. The parameters from the function are labelled with
5015 brackets in the following style: [amount]. In the case of parameters that are
5016 percentage values, they are converted to real numbers.
5017 </p>
5019 <h3 id="grayscaleEquivalent">grayscale</h3>
5021 <pre class="examplesource"> <filter id="grayscale">
5022 <feColorMatrix type="matrix"
5023 values="(0.2126 + 0.7874 * [1 - amount]) (0.7152 - 0.7152 * [1 - amount]) (0.0722 - 0.0722 * [1 - amount]) 0 0
5024 (0.2126 - 0.2126 * [1 - amount]) (0.7152 + 0.2848 * [1 - amount]) (0.0722 - 0.0722 * [1 - amount]) 0 0
5025 (0.2126 - 0.2126 * [1 - amount]) (0.7152 - 0.7152 * [1 - amount]) (0.0722 + 0.9278 * [1 - amount]) 0 0
5026 0 0 0 1 0"/>
5027 </filter> </pre>
5029 <h3 id="sepiaEquivalent">sepia</h3>
5031 <pre class="examplesource"> <filter id="sepia">
5032 <feColorMatrix type="matrix"
5033 values="(0.393 + 0.607 * [1 - amount]) (0.769 - 0.769 * [1 - amount]) (0.189 - 0.189 * [1 - amount]) 0 0
5034 (0.349 - 0.349 * [1 - amount]) (0.686 + 0.314 * [1 - amount]) (0.168 - 0.168 * [1 - amount]) 0 0
5035 (0.272 - 0.272 * [1 - amount]) (0.534 - 0.534 * [1 - amount]) (0.131 + 0.869 * [1 - amount]) 0 0
5036 0 0 0 1 0"/>
5037 </filter> </pre>
5039 <h3 id="saturateEquivalent">saturate</h3>
5041 <pre class="examplesource"> <filter id="saturate">
5042 <feColorMatrix type="saturate"
5043 values="(1 - [amount])"/>
5044 </filter> </pre>
5046 <h3 id="huerotateEquivalent">hue-rotate</h3>
5048 <pre class="examplesource"> <filter id="hue-rotate">
5049 <feColorMatrix type="hueRotate"
5050 values="[angle]"/>
5051 </filter> </pre>
5053 <h3 id="invertEquivalent">invert</h3>
5055 <pre class="examplesource"> <filter id="invert">
5056 <feComponentTransfer>
5057 <feFuncR type="table" tableValues="[amount] (1 - [amount])"/>
5058 <feFuncG type="table" tableValues="[amount] (1 - [amount])"/>
5059 <feFuncB type="table" tableValues="[amount] (1 - [amount])"/>
5060 </feComponentTransfer>
5061 </filter> </pre>
5063 <h3 id="opacityEquivalent">opacity</h3>
5065 <pre class="examplesource"> <filter id="opacity">
5066 <feComponentTransfer>
5067 <feFuncA type="table" tableValues="0 [amount]"/>
5068 </feComponentTransfer>
5069 </filter> </pre>
5071 <h3 id="brightnessEquivalent">brightness</h3>
5073 <pre class="examplesource"> <filter id="brightness">
5074 <feComponentTransfer>
5075 <feFuncR type="linear" slope="[amount]"/>
5076 <feFuncG type="linear" slope="[amount]"/>
5077 <feFuncB type="linear" slope="[amount]"/>
5078 </feComponentTransfer>
5079 </filter> </pre>
5081 <h3 id="contrastEquivalent">contrast</h3>
5083 <pre class="examplesource"> <filter id="contrast">
5084 <feComponentTransfer>
5085 <feFuncR type="linear" slope="[amount]" intercept="-(0.5 * [amount] + 0.5)"/>
5086 <feFuncG type="linear" slope="[amount]" intercept="-(0.5 * [amount] + 0.5)"/>
5087 <feFuncB type="linear" slope="[amount]" intercept="-(0.5 * [amount] + 0.5)"/>
5088 </feComponentTransfer>
5089 </filter> </pre>
5091 <h3 id="blurEquivalent">blur</h3>
5093 <pre class="examplesource"> <filter id="blur">
5094 <feGaussianBlur stdDeviation="[radius radius]">
5095 </filter> </pre>
5097 <h3 id="dropshadowEquivalent">drop-shadow</h3>
5099 <pre class="examplesource"> <filter id="drop-shadow">
5100 <feGaussianBlur in="[alpha-channel-of-input]" stdDeviation="[radius]"/>
5101 <feOffset dx="[offset-x]" dy="[offset-y]" result="offsetblur"/>
5102 <feFlood flood-color="[color]"/>
5103 <feComposite in2="offsetblur" operator="in"/>
5104 <feMerge>
5105 <feMergeNode/>
5106 <feMergeNode in="input-image"/>
5107 </feMerge>
5108 </filter> </pre>
5110 <h3 id="customEquivalent">custom</h3>
5112 <p>The <code>custom()</code> function has the following syntax:</p>
5114 <dl>
5115 <dt><code>custom(<span class="highlight"><vertex-shader></span><span class="highlight2">[</span><span class="fade">wsp</span><span class="highlight"><fragment-shader></span><span class="highlight2">][,</span><span class="highlight"><vertex-mesh></span><span class="highlight2">][,</span><span class="highlight"><params></span><span class="highlight2">]</span>)</code></dt>
5116 <dd><table class="values-desc">
5117 <tr>
5118 <td><code><vertex-shader></code></td>
5119 <td><code><uri> | none</code></td>
5120 </tr>
5121 <tr>
5122 <td><code><fragment-shader></code></td>
5123 <td><code><uri> | none</code></td>
5124 </tr>
5125 <tr>
5126 <td><code><vertex-mesh></code></td>
5127 <td><code>+<integer>{1,2}[wsp<box>][wsp'detached']</code><br />
5128 where: <code><box> = filter-box | border-box | padding-box | content-box</code></td>
5129 </tr>
5130 <tr>
5131 <td id='#shader-params'><code><params></code></td>
5132 <td>See the <code><feCustom></code>'s <a href='#feCustomParamsAttribute'><code>params</code></a> attribute.</td>
5133 </tr>
5134 </table>
5135 </dd>
5136 </dl>
5137 <p>The <code>custom()</code> function is a shorthand for the following filter effect:</p>
5139 <code class="idl"><pre>
5140 <filter>
5141 <feCustom vertexShader="<strong>vertex-shader</strong>"
5142 fragmentShader="<strong>fragment-shader</strong>"
5143 vertexMesh="<strong>vertex-mesh</strong>"
5144 params="<strong>params</strong>"/>
5145 </filter>
5146 </pre></code>
5148 <p>It can be used in combination with other filter shorthands, for example:</p>
5150 <code>filter: sepia(0.5) custom(none url(add.fs), amount 0.2 0.2 0.2);</code>
5152 <div class="note">It might be clearer to name the <code>custom()</code> function
5153 the <code>shader()</code> function instead and introduce an <code>feCustomShader</code>
5154 filter primitive instead of <code>feCustom</code>.</div>
5157 <h2 id="shading-language">Shading language</h2>
5159 <h3 id="precedents">Precedents</h3>
5161 <p>There are many precedents for shading languages, for example:</p>
5162 <ul>
5163 <li><a href="http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf">OpenGL ES Shading Language</a> (also known as GLSL ES) from <a href="http://www.khronos.org/registry/webgl/specs/latest/#refsGLES20GLSL">WebGL</a></li>
5164 <li><a href="http://msdn.microsoft.com/en-us/library/bb509635(v=VS.85).aspx">HLSL Shading Language</a></li>
5165 <li><a href="http://www.adobe.com/content/dam/Adobe/en/devnet/pixelbender/pdfs/pixelbender_reference.pdf">Adobe's Pixel Bender language</a></li>
5166 <li><a href="http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/CoreImaging/ci_custom_filters/ci_custom_filters.html%23//apple_ref/doc/uid/TP30001185-CH207-TPXREF101">Apple's CoreImage Filters</a></li>
5167 </ul>
5169 <h3 id="recommendation">Recommended shading language</h3>
5171 <p>This document recommends the adoption of the subset of <a href="http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf">GLSL ES</a> defined in the <a href="http://www.khronos.org/registry/webgl/specs/1.0/">WebGL 1.0</a> specification.</p>
5173 <p>In particular, the same restrictions as defined in WebGL should apply to CSS shaders:</p>
5175 <ul>
5176 <li><a href="http://www.khronos.org/registry/webgl/specs/latest/#SUPPORTED_GLSL_CONSTRUCTS">supported GLSL constructs.</a></li>
5177 <li><a href="http://www.khronos.org/registry/webgl/specs/latest/#6">differences between WebGL and OpenGL ES 2.0</a> as it applies to shaders.</li>
5178 </ul>
5180 <p>All the parameters specified in the <code><shader-params></code> values (e.g., the <code>feCustom's param</code> attribute or the <code>custom(<uri>, <shader-params>)</code> filter function or the <code>shader</code> property value) will be available as uniforms to the shader(s) referenced by the 'shader' property.</p>
5182 <p>The group may consider applying further restrictions to the GLSL ES language to make it easier to
5183 write vertex and fragment shaders.</p>
5185 <p>The OpenGL ES shading language provides a number of variables that can be passed to shaders,
5186 exchanged between shaders or set by shaders. In particular, a vertex shader can provide specific
5187 data to the fragment shader in the form of 'varying' parameters (parameters that vary per pixel).
5188 The following sections describe particular variables that are assumed for the
5189 vertex and fragment shaders in CSS shaders.</p>
5191 <div class="note">
5192 Even though this document recommends the GLSL ES shading language, there are other possible options to
5193 consider, for example:
5194 <ul>
5195 <li>Allow multiple shading languages, present or future (similar to how the <script> tag
5196 allows different scripting languages).</li>
5197 <li>Define a shading language specific to custom filter effects.</li>
5198 </ul>
5200 The implementation could use the mime type of the url or <script> element
5201 to determine the the shading language.
5202 </div>
5204 <h4>Vertex attribute variables</h4>
5206 The following attribute variables are available to the vertex shader.
5208 <table class="values-desc">
5209 <tr>
5210 <td><code>attribute vec4 a_position</code></td>
5211 <td>The vertex coordinates in the <a href="#filter-region">filter region</a> box.
5212 Coordinates are normalized to the [-0.5, 0.5] range along the x, y and z axis.</td>
5213 </tr>
5214 <tr>
5215 <td><code>attribute vec2 a_texCoord;</code></td>
5216 <td>The vertex's texture coordinate. Coordinates are in the [0, 1] range on both axis</td>
5217 </tr>
5218 <tr>
5219 <td><code>attribute vec2 a_meshCoord;</code></td>
5220 <td>The vertex's coordinate in the <a href="#mesh-box">mesh box</a>.
5221 Coordinates are in the [0, 1] range on both axis.</td>
5222 </tr>
5223 <tr>
5224 <td><code>attribute vec3 a_triangleCoord;</code></td>
5225 <td><p>The x and y values provide the coordinate of the current 'tile' in the shader mesh.
5226 For example, (0, 0) for the
5227 top right tile in the mesh. The x and y values are in the [0, mesh columns] and [0, mesh rows]
5228 range, respectively.</p>
5229 <p>The z coordinate is computed according to the following figure. The z coordinate value
5230 is provided for each vertex and corresponding triangle. For example, for the bottom
5231 right vertex of the top triangle, the z coordinate will be 2. For the bottom
5232 right vertex of the bottom triangle, the z coordinate will be 4.</p>
5233 </tr>
5234 </tr>
5236 </table>
5239 <div class="figure">
5240 <img src="images/a_triangleCoord.z.png" width="50%"/>
5241 <p class="caption">The a_triangleCoord.z value</p>
5242 </div>
5243 </td>
5245 <h4>Shader uniform variables</h4>
5247 The following uniform variables are set to specific values by the user agent:
5249 <table class="values-desc">
5250 <tr>
5251 <td><code>uniform mat4 u_projectionMatrix</code></td>
5252 <td>The current projection matrix to the
5253 destination texture's coordinate space). <em>Note that the 'model matrix' which
5254 the 'transform' property sets, is not passed to the shaders. It is applied to the
5255 filtered element's rendering.</em></td>
5256 </tr>
5257 <tr>
5258 <td><code>uniform sampler2D u_texture</code></td>
5259 <td>The input texture. Includes transparent margins for the filter margins.</td>
5260 </tr>
5261 <tr>
5262 <td><code>uniform sampler2D u_contentTexture</code></td>
5263 <td>A texture with the rendering of the filtered element. If the filter is the first
5264 in the filter chain, then, this texture is the same as the u_texture uniform. However,
5265 if there are preceding filters, this provides the rendering of the original filtered element,
5266 whereas u_texture provides the output of the preceding filter in the filter chain (or graph).</td>
5267 </tr>
5268 <tr>
5269 <td><code>uniform vec2 u_textureSize</code></td>
5270 <td>The input texture's size. Includes the filter margins.</td>
5271 </tr>
5272 <tr>
5273 <td><code>uniform vec4 u_meshBox</code></td>
5274 <td>The mesh box position and size in the <a href="#filter-box">filter box</a> coordinate
5275 system. For example, if the mesh box is the filter box, the value will be (-0.5, -0.5, 1, 1).</td>
5276 </tr>
5277 <tr>
5278 <td><code>uniform vec2 u_tileSize</code></td>
5279 <td>The size of the current mesh tile, in the same coordinate space as the vertices.</td>
5280 </tr>
5281 <tr>
5282 <td><code>uniform vec2 u_meshSize</code></td>
5283 <td>The size of the current mesh in terms of tiles. The x coordinate provides the number of
5284 columns and the y coordinate provides the number of rows.</td>
5285 </tr>
5286 </table>
5288 <h4>Varyings</h4>
5290 <p>When the author provides both a vertex and a fragment shader, there is no requirement on the
5291 varyings passed from the vertex shader to the fragment shader. If no vertex shader is provided,
5292 the fragment shader can expect the <code>v_texCoord</code> varying. If no fragment shader is
5293 provided, the vertex shader must compute a v_texCoord varying for the default shaders.</p>
5295 <table class="values-desc">
5296 <tr>
5297 <td>varying vec2 v_texCoord;</td>
5298 <td>The current pixel's texture coordinates (in u_texture).</td>
5299 </tr>
5300 </table>
5302 <h4>Other uniform variables: the CSS shaders parameters</h4>
5304 <p>When there parameters are passed to the <code>custom()</code> filter function or the
5305 <code>feCustom</code> filter primitive, the user agent pass uniforms of the corresponding name and
5306 type to the shaders.</p>
5308 <p>The following table shows the mapping between CSS shader parameters and uniform types.</p>
5310 <div class="table">
5311 <table class="values-desc">
5312 <tr>
5313 <th>CSS param type</th>
5314 <th>GLSL uniform type</th>
5315 </tr>
5316 <tr>
5317 <td>true|false[wsp+true|false]{0-3}</td>
5318 <td>bool, bvec2, bvec3 or bvec4</td>
5319 </tr>
5320 <tr>
5321 <td><number>[wsp+<number>]{0-3}
5322 <td>float, vec2, vec3 or vec4</td>
5323 </tr>
5324 <tr>
5325 <td>
5326 <array>
5327 </td>
5328 <td>
5329 float[n]
5330 </td>
5331 </tr>
5332 <tr>
5333 <td>
5334 <css-3d-transform>
5335 </td>
5336 <td>
5337 mat4
5338 </td>
5339 </tr>
5340 <tr>
5341 <td>'mat2('<number>(,<number>){3}')' | <br />
5342 'mat3('<number>(,<number>){8}')' | <br />
5343 'mat4('<number>(,<number>){15}')'</td>
5344 <td>
5345 mat2, mat3 or mat4
5346 </td>
5347 </tr>
5348 <tr>
5349 <td>texture(<uri>)</td>
5350 <td>sampler2D</td>
5351 </tr>
5352 </table>
5353 </div>
5355 <p>The following code sample illustrates that mechanism.</p>
5357 <div class="example">
5358 <code><pre>
5359 <strong>CSS</strong>
5361 .shaded {
5362 filter: custom(
5363 url(distort.vs) url(tint.fs),
5364 distortAmount 0.5, lightVector 1.0 1.0 0.0,
5365 disp texture(disp.png)
5366 );
5367 }
5369 <strong>Shader (vertex or fragment)</strong>
5370 ...
5372 uniform float distortAmount;
5373 uniform vec3 lightVector;
5374 uniform sampler2D disp;
5375 uniform vec2 dispSize;
5376 ...</pre></code>
5377 </div>
5379 <p>As illustrated in the example, for each <code><textureName> texture()</code> parameter, an additional <code>vec2</code> uniform is passed
5380 to the shaders with the size of the corresponding texture.
5383 <h4>Default shaders</h4>
5385 <p>If no vertex shader is provided, the default one is as shown below.</p>
5387 <div id="default-vertex-shader" class="shader example">
5388 <code class="idl"><pre>
5389 attribute vec4 a_position;
5390 attribute vec2 a_texCoord;
5392 uniform mat4 u_projectionMatrix;
5394 varying vec2 v_texCoord;
5396 void main()
5397 {
5398 v_texCoord = a_texCoord;
5399 gl_Position = u_projectionMatrix * a_position;
5400 }
5402 </pre></code>
5403 </div>
5405 <p>If no fragment shader is provided, the default one is shown below.</p>
5407 <div id="default-fragment-shader" class="shader example">
5408 <code class="idl"><pre>
5409 varying vec2 v_texCoord;
5410 uniform sampler2D u_texture;
5412 void main()
5413 {
5414 gl_FragColor = texture2D(u_texture, v_texCoord);
5415 } </pre></code>
5416 </div>
5418 <h4>Texture access</h4>
5420 <p>If shaders access texture values outside the <code>[0, 1]</code> range on both axis, the
5421 returned value is a fully transluscent black pixel.</p>
5423 <h2 id="integration-with-css-animations-transitions">Integration with CSS Animations and CSS Transitions</h2>
5425 <p>The CSS 'filter' property is animatable. Interpolation happens between the filter functions
5426 only if the 'filter' values have the same number of filter functions, and the same functions appearing in the same order.</p>
5428 <h3 id="filter-params-interpolation">Interpolating filter functions parameters</h3>
5430 <p class="todo">This section has to be written.</p>
5432 <h3 id="shader-params-interpolation">Interpolating the shader-params component in the custom() function.</h3>
5434 <p>To interpolate between <a href="#shader-params"><code>params</code></a> values in a
5435 <code>custom()</code> filter function or between
5436 <code><feCustom></code>
5437 <a href="#feCustomParamsAttribute">'params'</a> attribute values, the user
5438 agent should interpolate between each of the <strong><a href="#param-def">[param-def]</a></strong> values
5439 according to its type. List of values need to be of the same length. Matrices need to be of the same
5440 dimension. Arrays need to be of the same size.</p>
5442 <p class="note">
5443 Interpolation between shader params only happens if all the other shader properties are identical:
5444 vertex shader, fragment shader, filter margins and vertex mesh.
5445 </p>
5447 <table class="values-desc">
5448 <tr>
5449 <td><code><number>[wsp<number>{0-3}]</code></td>
5450 <td>Interpolate between each of the values.</td>
5451 </tr>
5452 <tr>
5453 <td><code><true|false>[wsp<true|fals>{0-3}]</code></td>
5454 <td>Interpolate between each of the values using a step function.</td>
5455 </tr>
5456 <tr>
5457 <td><code><array></code></td>
5458 <td>Interpolate between the array elements.</td>
5459 </tr>
5460 <tr>
5461 <td><code><css-3d-transform></code></td>
5462 <td>Follows the <a href="http://www.w3.org/TR/css3-3d-transforms/#animation">CSS 3D transform interpolation rules</a>.</td>
5463 </tr>
5464 <tr>
5465 <td><code><mat></code></td>
5466 <td>Interpolate between the matrix components (applies to mat2, mat3 and mat4).</td>
5467 </tr>
5468 </table>
5470 <div class="note">
5471 As with the 'transform' property, it is not possible to animate the different components of the
5472 'shader-params' property on different timelines or with different keyframes. This is a generic
5473 issue of animating properties that have multiple components to them.
5474 </div>
5476 <h2 id="DOMInterfaces">DOM interfaces</h2>
5478 <div class="note">
5479 The interfaces below will be made available in a IDL file for an upcoming draft.
5480 </div>
5482 <h3 id="InterfaceImageData">Interface ImageData</h3>
5484 <edit:interface name='::svg::ImageData'/>
5486 <h3 id="InterfaceSVGFilterElement">Interface SVGFilterElement</h3>
5488 <edit:with element='filter'>
5489 <edit:interface name='::svg::SVGFilterElement'/>
5490 </edit:with>
5492 <h3 id="InterfaceSVGFilterPrimitiveStandardAttributes">Interface SVGFilterPrimitiveStandardAttributes</h3>
5494 <edit:with element='feTile'>
5495 <edit:interface name='::svg::SVGFilterPrimitiveStandardAttributes'/>
5496 </edit:with>
5498 <h3 id="InterfaceSVGFEBlendElement">Interface SVGFEBlendElement</h3>
5500 <edit:with element='feBlend'>
5501 <edit:interface name='::svg::SVGFEBlendElement'/>
5502 </edit:with>
5504 <h3 id="InterfaceSVGFEColorMatrixElement">Interface SVGFEColorMatrixElement</h3>
5506 <edit:with element='feColorMatrix'>
5507 <edit:interface name='::svg::SVGFEColorMatrixElement'/>
5508 </edit:with>
5510 <h3 id="InterfaceSVGFEComponentTransferElement">Interface SVGFEComponentTransferElement</h3>
5512 <edit:with element='feComponentTransfer'>
5513 <edit:interface name='::svg::SVGFEComponentTransferElement'/>
5514 </edit:with>
5516 <h3 id="InterfaceSVGComponentTransferFunctionElement">Interface SVGComponentTransferFunctionElement</h3>
5518 <edit:with element='feFuncR'>
5519 <edit:interface name='::svg::SVGComponentTransferFunctionElement'/>
5520 </edit:with>
5522 <h3 id="InterfaceSVGFEFuncRElement">Interface SVGFEFuncRElement</h3>
5524 <edit:with element='feFuncR'>
5525 <edit:interface name='::svg::SVGFEFuncRElement'/>
5526 </edit:with>
5528 <h3 id="InterfaceSVGFEFuncGElement">Interface SVGFEFuncGElement</h3>
5530 <edit:with element='feFuncG'>
5531 <edit:interface name='::svg::SVGFEFuncGElement'/>
5532 </edit:with>
5534 <h3 id="InterfaceSVGFEFuncBElement">Interface SVGFEFuncBElement</h3>
5536 <edit:with element='feFuncB'>
5537 <edit:interface name='::svg::SVGFEFuncBElement'/>
5538 </edit:with>
5540 <h3 id="InterfaceSVGFEFuncAElement">Interface SVGFEFuncAElement</h3>
5542 <edit:with element='feFuncA'>
5543 <edit:interface name='::svg::SVGFEFuncAElement'/>
5544 </edit:with>
5546 <h3 id="InterfaceSVGFECompositeElement">Interface SVGFECompositeElement</h3>
5548 <edit:with element='feComposite'>
5549 <edit:interface name='::svg::SVGFECompositeElement'/>
5550 </edit:with>
5552 <h3 id="InterfaceSVGFEConvolveMatrixElement">Interface SVGFEConvolveMatrixElement</h3>
5554 <edit:with element='feConvolveMatrix'>
5555 <edit:interface name='::svg::SVGFEConvolveMatrixElement'/>
5556 </edit:with>
5558 <h3 id="InterfaceSVGFEDiffuseLightingElement">Interface SVGFEDiffuseLightingElement</h3>
5560 <edit:with element='feDiffuseLighting'>
5561 <edit:interface name='::svg::SVGFEDiffuseLightingElement'/>
5562 </edit:with>
5564 <h3 id="InterfaceSVGFEDistantLightElement">Interface SVGFEDistantLightElement</h3>
5566 <edit:with element='feDistantLight'>
5567 <edit:interface name='::svg::SVGFEDistantLightElement'/>
5568 </edit:with>
5570 <h3 id="InterfaceSVGFEPointLightElement">Interface SVGFEPointLightElement</h3>
5572 <edit:with element='fePointLight'>
5573 <edit:interface name='::svg::SVGFEPointLightElement'/>
5574 </edit:with>
5576 <h3 id="InterfaceSVGFESpotLightElement">Interface SVGFESpotLightElement</h3>
5578 <edit:with element='feSpotLight'>
5579 <edit:interface name='::svg::SVGFESpotLightElement'/>
5580 </edit:with>
5582 <h3 id="InterfaceSVGFEDisplacementMapElement">Interface SVGFEDisplacementMapElement</h3>
5584 <edit:with element='feDisplacementMap'>
5585 <edit:interface name='::svg::SVGFEDisplacementMapElement'/>
5586 </edit:with>
5588 <h3 id="InterfaceSVGFEFloodElement">Interface SVGFEFloodElement</h3>
5590 <edit:with element='feFlood'>
5591 <edit:interface name='::svg::SVGFEFloodElement'/>
5592 </edit:with>
5594 <h3 id="InterfaceSVGFEGaussianBlurElement">Interface SVGFEGaussianBlurElement</h3>
5596 <edit:with element='feGaussianBlur'>
5597 <edit:interface name='::svg::SVGFEGaussianBlurElement'/>
5598 </edit:with>
5600 <h3 id="InterfaceSVGFEImageElement">Interface SVGFEImageElement</h3>
5602 <edit:with element='feImage'>
5603 <edit:interface name='::svg::SVGFEImageElement'/>
5604 </edit:with>
5606 <h3 id="InterfaceSVGFEMergeElement">Interface SVGFEMergeElement</h3>
5608 <edit:with element='feMerge'>
5609 <edit:interface name='::svg::SVGFEMergeElement'/>
5610 </edit:with>
5612 <h3 id="InterfaceSVGFEMergeNodeElement">Interface SVGFEMergeNodeElement</h3>
5614 <edit:with element='feMergeNode'>
5615 <edit:interface name='::svg::SVGFEMergeNodeElement'/>
5616 </edit:with>
5618 <h3 id="InterfaceSVGFEMorphologyElement">Interface SVGFEMorphologyElement</h3>
5620 <edit:with element='feMorphology'>
5621 <edit:interface name='::svg::SVGFEMorphologyElement'/>
5622 </edit:with>
5624 <h3 id="InterfaceSVGFEOffsetElement">Interface SVGFEOffsetElement</h3>
5626 <edit:with element='feOffset'>
5627 <edit:interface name='::svg::SVGFEOffsetElement'/>
5628 </edit:with>
5630 <h3 id="InterfaceSVGFESpecularLightingElement">Interface SVGFESpecularLightingElement</h3>
5632 <edit:with element='feSpecularLighting'>
5633 <edit:interface name='::svg::SVGFESpecularLightingElement'/>
5634 </edit:with>
5636 <h3 id="InterfaceSVGFETileElement">Interface SVGFETileElement</h3>
5638 <edit:with element='feTile'>
5639 <edit:interface name='::svg::SVGFETileElement'/>
5640 </edit:with>
5642 <h3 id="InterfaceSVGFETurbulenceElement">Interface SVGFETurbulenceElement</h3>
5644 <edit:with element='feTurbulence'>
5645 <edit:interface name='::svg::SVGFETurbulenceElement'/>
5646 </edit:with>
5648 <h3 id="InterfaceSVGFEDropShadowElement">Interface SVGFEDropShadowElement</h3>
5650 <edit:with element='feDropShadow'>
5651 <edit:interface name='::svg::SVGFEDropShadowElement'/>
5652 </edit:with>
5654 <h2 id="references1">References</h2>
5655 <h3 id="normref">Normative References</h3>
5656 <dl>
5657 <dt id="ref-CSS21"><strong class="normref">[CSS21]</strong></dt>
5658 <dd><strong>Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification</strong>,
5659 Bert Bos, Tantek Çelik, Ian Hickson, Håkon Wium Lie, eds.,
5660 W3C, 23 April 2009, (Candidate Recommendation) </dd>
5662 <dt id="ref-NVDL"><strong class="normref">[NVDL]</strong></dt>
5663 <dd><strong>Document Schema Definition Languages (DSDL) — Part 4:
5664 Namespace-based Validation Dispatching Language — NVDL. ISO/IEC FCD
5665 19757-4</strong>, See <a
5666 href="http://www.asahi-net.or.jp/~eb2m-mrt/dsdl/">http://www.asahi-net.or.jp/~eb2m-mrt/dsdl/</a>
5667 </dd>
5669 <dt id="ref-PORTERDUFF"><strong class="normref">[PORTERDUFF]</strong></dt>
5670 <dd><strong>Compositing Digital Images</strong>, T. Porter, T. Duff,
5671 SIGGRAPH '84 Conference Proceedings, Association for Computing
5672 Machinery, Volume 18, Number 3, July 1984. </dd>
5673 <dt id="ref-SVG-COMPOSITING"><strong class="normref">[SVG-COMPOSITING]</strong></dt>
5674 <dd>
5675 <cite class="w3cwd"><a href="http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/">SVG Compositing Specification</a></cite>,
5676 A. Grasso, ed.
5677 World Wide Web Consortium, 30 April 2009.
5678 <br/>This edition of SVG Compositing is http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/.
5679 <br/>The <a href="http://www.w3.org/TR/SVGCompositing/">latest edition of SVG Compositing</a> is available at
5680 http://www.w3.org/TR/SVGCompositing/.
5681 </dd>
5682 <dt id="ref-RNG"><strong class="normref">[RelaxNG]</strong></dt>
5683 <dd><strong>Document Schema Definition Languages (DSDL) — Part 2:
5684 Regular grammar- based validation — RELAX NG. ISO/IEC FDIS
5685 19757-2:2002(E)</strong>, J. Clark, <span class="ruby"><span
5686 xml:lang="ja" lang="ja" class="rb">村田 真</span> <span
5687 class="rp">(</span><span class="rt"><span
5688 class="familyname">Murata</span> M.</span><span
5689 class="rp">)</span></span>, eds., 12 December 2002. See <a
5690 href="http://www.y12.doe.gov/sgml/sc34/document/0362_files/relaxng-is.pdf">http://www.y12.doe.gov/sgml/sc34/document/0362_files/relaxng-is.pdf</a>
5691 </dd>
5692 <dt id="ref-Schema2"><strong class="normref">[Schema2]</strong></dt>
5693 <dd><strong>XML Schema Part 2: Datatypes Second Edition</strong>, P.
5694 Biron, A. Malhotra, eds. W3C, 28 October 2004 (Recommendation). Latest
5695 version available at <a
5696 href="http://www.w3.org/TR/xmlschema-2/">http://www.w3.org/TR/xmlschema-2/</a>.
5697 See also <a
5698 href="http://www.w3.org/TR/2005/NOTE-xml11schema10-20050511/">Processing
5699 XML 1.1 documents with XML Schema 1.0 processors</a>. </dd>
5700 <dt id="ref-svg11"><strong class="normref">[SVG11]</strong></dt>
5701 <dd><strong>Scalable Vector Graphics (SVG) 1.1 Specification</strong>,
5702 Dean Jackson editor, W3C, 14 January 2003 (Recommendation). See <a
5703 href="http://www.w3.org/TR/2003/REC-SVG11-20030114/">http://www.w3.org/TR/2003/REC-SVG11-20030114/</a>
5704 </dd>
5705 <dt id="ref-svgt12"><strong class="normref">[SVGT12]</strong></dt>
5706 <dd><strong>Scalable Vector Graphics (SVG) Tiny 1.2 Specification</strong>,
5707 Dean Jackson editor, W3C, 22 December 2008 (Recommendation). See <a
5708 href="http://www.w3.org/TR/2008/REC-SVGTiny12-20081222/">http://www.w3.org/TR/2008/REC-SVGTiny12-20081222/</a>
5709 </dd>
5710 </dl>
5712 <h3 id="informref">Informative References</h3>
5713 <dl>
5714 <dt id="ref-html5"><strong class="informref">[HTML5]</strong></dt>
5715 <dd><strong>HTML5</strong>, Ian Hickson editor, Google,
5716 10 June 2008 (Working Draft). See <a
5717 href="http://www.w3.org/TR/2008/WD-html5-20080610/">http://www.w3.org/TR/2008/WD-html5-20080610/</a>
5718 </dd>
5719 </dl>
5721 </body>
5722 </html>