-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfilter-Overview.Rmd
More file actions
executable file
·231 lines (182 loc) · 9.1 KB
/
filter-Overview.Rmd
File metadata and controls
executable file
·231 lines (182 loc) · 9.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
---
title: "Filter Attribute"
output:
html_document:
toc: true
theme: united
---
```{r, echo=FALSE}
stopifnot(require(svgR, quietly=TRUE))
```
##Overview of Filters
###Introduction
In the previous section we explored how the *fill* attribute can be applied to text and shapes.
Another
attribute for text and shapes, is the *filter* attribute.
*Filter *attributes may take as values a **filter element** or a *reference*
to a **filter element**.
A **Filter element** is a container for **filter effect elements**,
also called **filter primitives** or **fe-elements**
. The **fe-elements** feed into each other to
form a directed graph with a root. Typically, the fe elements are linked together using the
*in1*, *in2* attributes. One might visualize a filter to look something like
```{r, echo=FALSE, results="asis"}
WH<-c(650,680)
#Defined by mouse: edit with care!
ptR<-list(
arrows=matrix(
c(c( 150.5,205 ),c( 150.5,150 ),c( 265.5,152 ),c( 276.5,108 ),c( 13.5,12 ),c( 451.5,204 ),c( 443.5,153 ),c( 347.5,154 ),c( 329.5,112 ),c( 26.5,9 ),c( 452.5,302 ),c( 452.5,272 ),c( 453.5,245 ),c( 21.5,22 ),c( 300.5,448 ),c( 298.5,396 ),c( 452.5,397 ),c( 453.5,344 ),c( 33.5,20 ),c( 150.5,601 ),c( 151.5,551 ),c( 279.5,549 ),c( 279.5,494 ),c( 33.5,33 ),c( 450.5,601 ),c( 451.5,549 ),c( 332.5,553 ),c( 327.5,494 )),
2,),
labels=matrix(
c(c( 201.5,138 ),c( 400.5,139 ),c( 438.5,279 ),c( 372.5,385 ),c( 219.5,539 ),c( 400.5,537 )),
2,),
uniboxes=matrix(
c(c( 301.5,62 ),c( 151.5,204 ),c( 452.5,203 ),c( 452.5,303 ),c( 300.5,450 ),c( 147.5,601 ),c( 453.5,603 )),
2,)
)
unifboxes%<c-%function(x=c(), txt="", wh=c(100,30), rxy=c(20,20), ...){
if(length(x)==0){
return(NULL)
}
n<-ncol(x)
if(length(txt)<n){
txt<-c(txt, paste0(length(txt):c))
}
lapply(1:n, function(i){
xy<-x[,i]-c(.5,0)*wh
cxy<-xy+wh/2
g(
rect(xy=xy, wh= wh, rxy=rxy, ...),
if(nchar(txt[i])>0){
text(cxy=cxy, txt[i], ...)
} else {
NULL
}
)
})
}
roundedPolyLine%<c-%function(x, r=5, ...){
nx<-length(x)
if(nx<=4){
return(nx)
}
n<-ncol(x)
if(n==2){
return(path(d=c("M", x[,1], "L", x[,n]), ...))
}
dv<-x[,-n]-x[,-1]
d<-apply( dv ,2, function(x)sqrt(sum(x)^2) )
lambda<-sapply(r/d, function(x)min(x,.5))
m<- n-1
if(m==2){
mA<-matrix(c(lambda[1],1-lambda[1]),2,1)
mB<-matrix(c(1-lambda[2],lambda[2]),2,1)
} else {
mA<- rbind(diag(lambda[-m]),0) + rbind(0,diag(1-lambda[-m]))
mB<- rbind(0,diag(lambda[-1])) + rbind(diag(1-lambda[-1]),0)
}
a<-x[,-n]%*%mA
b<-x[,-1]%*%mB
rL<-rep("L", n-2)
rQ<-rep("Q", n-2)
if(m==2){
rr<-c(rL,a,rQ,x[,2],b)
} else {
rr<-rbind(rL, a, rQ, x[,-c(1,n)], b)
}
path(d=c("M", x[,1], rr, "L", x[,n]), ...)
}
roundedPolyLineArrays%<c-%function(p, ...){
if(length(p)<4){
return(NULL)
}
n<-ncol(p)
brks<-apply(p,2, function(x){ max(x)<50})
brkss<-(1+cumsum(brks))*(!brks)
if(max(brkss)==0){
return(NULL)
}
lapply(1:max(brkss),function(i){
p_i<-p[,brkss==i]
roundedPolyLine(p_i, ...)
})
}
arrowHeadId<-autoId()
arrowHeadUrl<-paste0("url(#",arrowHeadId,")")
btxt<-c("feBlend", "SourceGraphic", "feGaussianBlur",
"feOffset", "feComposite", "feFlood", "SourceGraphic" )
labels<-c("in1","in2","in1", "in1", "in1","in2")
svgR(wh=WH,
#your custom code goes here
defs(
marker(id=arrowHeadId, viewBox=c(0, 0, 10, 10), refXY=c(9,5),
markerWidth=6, markerHeight=6, orient="auto",
path( d=c("M", 0, 0, "L", 10, 5, "L", 0, 10, "z"),
fill='darkgreen'
)
)
),
# boxes(ptR$boxes, txt=btxt, stroke="black",
# fill='lightblue', rxy=c(20,20)
# ),
#rect(xy=c(50,25), wh=c(500,650), stroke='black',
#fill='lightblue'),
#text(cxy=c(100,50),'filter',stroke='black',
#font.size=50),
unifboxes(ptR$uniboxes, txt=btxt, wh=c(150,40),
stroke="darkgreen",
fill="white"),
roundedPolyLineArrays(ptR$arrows, r=30,
stroke.width=3, stroke='darkgreen',
fill="none",
marker.end=arrowHeadUrl
),
lapply(1:ncol(ptR$labels), function(i){
text(cxy=ptR$labels[,i], labels[i], stroke='darkgreen')
})
)
```
One distinct difference between fills and filters, is that a fill
is restricted to the interior, while filters are not.
**Note** Technically this is not a tree, since the *SourceGraphics* label appears muliple places.
**Note** Pure *SVG* allows only references, but *svgR* allows to use
the **filter element** directly as the value of a *filter attribute*.
### The In Attributes of Filter components
Most **fe-element** (filter primitive) require an input specification, which
is preformed by assigning
values to their *in* attributes: *in1* and *in2*.
(Two notable exceptions to this are the fe-elements: **feImage** and **feFlood**.)
Values for the in *attributes* are given by the following table
Value | Description
----------------------|------------------------------------------------------------
*SourceGraphic* |represents the original element to which the filter is applied (as full RGBA image data)
*SourceAlpha* | represents just the alpha channel of the original element to which the filter is applied
*BackgroundImage* | represents the area directly underneath the filter region
*BackgroundAlpha* | represents just the alpha channel of the area underneath the filter region
*FillPaint* | represents whatever fill was applied to the element in question
*StrokePaint* | represents whatever stroke was applied to the element
a reference | Any other value should be a reference equal to the result attribute for any preceding filter primitive. In this case, the output of the referenced primitive will be used as the specified input.
### The fe-Elements (Filter primitives)
Element | Attributes
----------------------|------------------------------------------------------------
feBlend | in2="***second source***" <br> mode="normal" "multiply" "screen" "darken" "lighten"
feColorMatrix | type="matrix" "saturate" "hueRotate" "luminanceToAlpha" <br> values="***matrix values***" "***saturation value (0-1)***" "***rotate degrees***"
feComponentTransfer | container for <br>feFuncR, <br>feFuncG, <br>feFuncB, and <br>feFuncA elements.
feFunc***X*** | type="identity" "table" "discrete" "linear" "gamma" <br> tableValues="***intervals for table, steps for discrete***" <br> slope="***linear slope***" <br> intercept="***linear intercept***" <br> amplitude="***gamma amplitude***" <br> exponent="***gamma exponent***" <br> offset="***gamma offset***"
feComposite | in2="***second source***" <br> operator="over" "in" "out" "atop" "xor" "arithmetic" <br> The following attributes are used with arithmetic: <br> k1="***factor for in1,in2***" <br> k2="***factor for in1***" <br> k3="***factor for in2***" <br> k4="***additive offset***"
feConvolveMatrix | order="***columns rows***" (default 3 by 3) <br> kernel="***values***" <br> bias="***offset value***"
feDiffuseLighting | Container for a light source element. <br> surfaceScale="***height***" (default 1) <br> diffuseConstant="***factor***" (must be non-negative; default 1)
feDisplacementMap | scale="***displacement factor***" (default 0) <br> xChannelSelector="R" "G" "B" "A" <br> yChannelSelector="R" "G" "B" "A" <br> in2="***second input***"
feFlood | flood.color="***color specification***" <br> flood.opacity="***value (0-1)***"
feGaussianBlur | stdDeviation="***blur spread***" (larger is blurrier; default 0)
feImage | xlink:href="***image source***"
feMerge | container for feMergeNode elements
feMergeNode | ***in1*** = "***intermediate result***"
feMorphology | operator="erode" "dilate" <br> radius="***x-radius** **y-radius***" <br> radius="***radius***"
feOffset | dx="***x offset***" (default 0)<br>dy="***y offset***" (default 0)
feSpecularLighting | Container for a light source element.<br>surfaceScale="***height***" (default 1)<br>specularConstant="***factor***" (must be non-negative; default 1)<br>specularExponent="***exponent***" (range 1-128; default 1)
feTile | tiles the ***in1*** layer
feTurbulence | type="turbulence" "fractalNoise" <br> baseFrequency="***x-frequency y-frequency***" <br> baseFrequency="***frequency***" <br> numOctaves="***integer***" <br> seed="***number***"
feDistantLight | azimuth="***degrees***" (default 0)<br>elevation="***degrees***" (default 0)
fePointLight | x="***coordinate***" (default 0)<br>y="***coordinate***" (default 0)<br>z="***coordinate***" (default 0)
feSpotLight | x="***coordinate***" (default 0)<br>y="***coordinate***" (default 0)<br>z="***coordinate***" (default 0)<br>pointsAtX="***coordinate***" (default 0)<br>pointsAtY="***coordinate***" (default 0)<br>pointsAtZ="***coordinate***" (default 0)<br>specularConstant="***focus control***" (default 1)<br>limitingConeAngle="***degrees***"