OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> | 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> |
5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
7 * Copyright (C) 2013 Google Inc. All rights reserved. | 7 * Copyright (C) 2013 Google Inc. All rights reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 } | 106 } |
107 | 107 |
108 bool FEComposite::setK4(float k4) | 108 bool FEComposite::setK4(float k4) |
109 { | 109 { |
110 if (m_k4 == k4) | 110 if (m_k4 == k4) |
111 return false; | 111 return false; |
112 m_k4 = k4; | 112 m_k4 = k4; |
113 return true; | 113 return true; |
114 } | 114 } |
115 | 115 |
116 FloatRect FEComposite::determineAbsolutePaintRect(const FloatRect& originalReque stedRect) const | 116 bool FEComposite::affectsTransparentPixels() const |
117 { | 117 { |
118 FloatRect requestedRect = originalRequestedRect; | 118 // When k4 is non-zero (greater than zero with clamping factored in), the |
119 if (clipsToBounds()) | 119 // arithmetic operation will produce non-transparent output for transparent |
120 requestedRect.intersect(absoluteBounds()); | 120 // output. |
121 return m_type == FECOMPOSITE_OPERATOR_ARITHMETIC && k4() > 0; | |
Stephen White
2016/09/20 15:36:19
Could you add some repaint tests for the different
fs
2016/09/20 19:14:14
Added a few tests.
| |
122 } | |
121 | 123 |
122 // No mapPaintRect required for FEComposite. | 124 FloatRect FEComposite::mapInputs(const FloatRect& rect) const |
123 FloatRect input1Rect = inputEffect(1)->determineAbsolutePaintRect(requestedR ect); | 125 { |
124 FloatRect affectedRect; | 126 FloatRect input1Rect = inputEffect(1)->mapRect(rect); |
125 switch (m_type) { | 127 switch (m_type) { |
126 case FECOMPOSITE_OPERATOR_IN: | 128 case FECOMPOSITE_OPERATOR_IN: |
127 // 'in' has output only in the intersection of both inputs. | 129 // 'in' has output only in the intersection of both inputs. |
128 affectedRect = intersection(input1Rect, inputEffect(0)->determineAbsolut ePaintRect(input1Rect)); | 130 return intersection(input1Rect, inputEffect(0)->mapRect(input1Rect)); |
129 break; | |
130 case FECOMPOSITE_OPERATOR_ATOP: | 131 case FECOMPOSITE_OPERATOR_ATOP: |
131 // 'atop' has output only in the extents of the second input. | 132 // 'atop' has output only in the extents of the second input. |
132 // Make sure first input knows where it needs to produce output. | 133 return input1Rect; |
133 inputEffect(0)->determineAbsolutePaintRect(input1Rect); | |
134 affectedRect = input1Rect; | |
135 break; | |
136 case FECOMPOSITE_OPERATOR_ARITHMETIC: | 134 case FECOMPOSITE_OPERATOR_ARITHMETIC: |
137 if (k4() > 0) { | 135 // result(i1,i2) = k1*i1*i2 + k2*i1 + k3*i2 + k4 |
138 // Make sure first input knows where it needs to produce output. | 136 // |
139 inputEffect(0)->determineAbsolutePaintRect(requestedRect); | 137 // (The below is not a complete breakdown of cases.) |
140 // Arithmetic with non-zero k4 may influnce the complete filter prim itive | 138 // |
141 // region. So we can't optimize the paint region here. | 139 // Arithmetic with non-zero k4 may influence the complete filter primiti ve |
142 affectedRect = requestedRect; | 140 // region. [k4 > 0 => result(0,0) = k4 => result(a,b) >= k4] |
143 break; | 141 if (k4() > 0) |
144 } | 142 return rect; |
143 // Additionally, if k2 = 0, input 0 can only appear where input 1 also | |
144 // appears. [k2 = k4 = 0 => result(a,b) = k1*a*b + k3*b = (k1*a + k3)*b] | |
145 // Hence for k2 > 0, both inputs can still appear. (Except if k3 = 0.) | |
145 if (k2() <= 0) { | 146 if (k2() <= 0) { |
146 // Input 0 does not appear where input 1 is not present. | 147 // If k3 > 0, output can be produced wherever input 1 is |
147 FloatRect input0Rect = inputEffect(0)->determineAbsolutePaintRect(in put1Rect); | 148 // non-transparent. |
148 if (k3() > 0) { | 149 if (k3() > 0) |
149 affectedRect = input1Rect; | 150 return input1Rect; |
150 } else { | 151 // If just k1 is positive, output will only be produce where both |
151 // Just k1 is positive. Use intersection. | 152 // inputs are non-transparent. Use intersection. |
152 affectedRect = intersection(input1Rect, input0Rect); | 153 // [k1 >= 0 and k2 = k3 = k4 = 0 => result(a,b) = k1 * a * b] |
153 } | 154 return intersection(input1Rect, inputEffect(0)->mapRect(input1Rect)) ; |
154 break; | |
155 } | 155 } |
156 // else fall through to use union | 156 // else fall through to use union |
157 default: | 157 default: |
158 // Take the union of both input effects. | |
159 affectedRect = unionRect(input1Rect, inputEffect(0)->determineAbsolutePa intRect(requestedRect)); | |
160 break; | 158 break; |
161 } | 159 } |
162 | 160 // Take the union of both input effects. |
163 affectedRect.intersect(requestedRect); | 161 return unionRect(input1Rect, inputEffect(0)->mapRect(rect)); |
164 return affectedRect; | |
165 } | 162 } |
166 | 163 |
167 SkXfermode::Mode toXfermode(CompositeOperationType mode) | 164 SkXfermode::Mode toXfermode(CompositeOperationType mode) |
168 { | 165 { |
169 switch (mode) { | 166 switch (mode) { |
170 case FECOMPOSITE_OPERATOR_OVER: | 167 case FECOMPOSITE_OPERATOR_OVER: |
171 return SkXfermode::kSrcOver_Mode; | 168 return SkXfermode::kSrcOver_Mode; |
172 case FECOMPOSITE_OPERATOR_IN: | 169 case FECOMPOSITE_OPERATOR_IN: |
173 return SkXfermode::kSrcIn_Mode; | 170 return SkXfermode::kSrcIn_Mode; |
174 case FECOMPOSITE_OPERATOR_OUT: | 171 case FECOMPOSITE_OPERATOR_OUT: |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 ts << " operation=\"" << m_type << "\""; | 244 ts << " operation=\"" << m_type << "\""; |
248 if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) | 245 if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) |
249 ts << " k1=\"" << m_k1 << "\" k2=\"" << m_k2 << "\" k3=\"" << m_k3 << "\ " k4=\"" << m_k4 << "\""; | 246 ts << " k1=\"" << m_k1 << "\" k2=\"" << m_k2 << "\" k3=\"" << m_k3 << "\ " k4=\"" << m_k4 << "\""; |
250 ts << "]\n"; | 247 ts << "]\n"; |
251 inputEffect(0)->externalRepresentation(ts, indent + 1); | 248 inputEffect(0)->externalRepresentation(ts, indent + 1); |
252 inputEffect(1)->externalRepresentation(ts, indent + 1); | 249 inputEffect(1)->externalRepresentation(ts, indent + 1); |
253 return ts; | 250 return ts; |
254 } | 251 } |
255 | 252 |
256 } // namespace blink | 253 } // namespace blink |
OLD | NEW |