| 152 | } |
| 153 | |
| 154 | std::shared_ptr<ImageFilter> SVGFilter::buildInnerShadowFilter( |
| 155 | const SVGRenderContext& context, const SVGFilterContext& filterContext) const { |
| 156 | if (children.size() < 4) { |
| 157 | return nullptr; |
| 158 | } |
| 159 | size_t compositeIndex = 0; |
| 160 | for (size_t i = 0; i < children.size(); i++) { |
| 161 | if (children[i]->tag() == SVGTag::FeComposite) { |
| 162 | auto compositeFe = std::static_pointer_cast<SVGFeComposite>(children[i]); |
| 163 | if (compositeFe->getOperator() == SVGFeCompositeOperator::Arithmetic) { |
| 164 | compositeIndex = i; |
| 165 | break; |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | if (compositeIndex < 2 || compositeIndex + 1 >= children.size()) { |
| 170 | return nullptr; |
| 171 | } |
| 172 | if (children[compositeIndex + 1]->tag() == SVGTag::FeColorMatrix) { |
| 173 | std::shared_ptr<SVGFeGaussianBlur> blurFe; |
| 174 | std::shared_ptr<SVGFeOffset> offsetFe; |
| 175 | |
| 176 | if (children[compositeIndex - 2]->tag() == SVGTag::FeGaussianBlur && |
| 177 | children[compositeIndex - 1]->tag() == SVGTag::FeOffset) { |
| 178 | blurFe = std::static_pointer_cast<SVGFeGaussianBlur>(children[compositeIndex - 2]); |
| 179 | offsetFe = std::static_pointer_cast<SVGFeOffset>(children[compositeIndex - 1]); |
| 180 | } else if (children[compositeIndex - 2]->tag() == SVGTag::FeOffset && |
| 181 | children[compositeIndex - 1]->tag() == SVGTag::FeGaussianBlur) { |
| 182 | offsetFe = std::static_pointer_cast<SVGFeOffset>(children[compositeIndex - 2]); |
| 183 | blurFe = std::static_pointer_cast<SVGFeGaussianBlur>(children[compositeIndex - 1]); |
| 184 | } else { |
| 185 | return nullptr; |
| 186 | } |
| 187 | |
| 188 | auto scale = context.transformForCurrentBoundBox(filterContext.primitiveUnits()).scale; |
| 189 | auto dx = offsetFe->getDx() * scale.x * context.matrix().getScaleX(); |
| 190 | auto dy = offsetFe->getDy() * scale.y * context.matrix().getScaleY(); |
| 191 | auto blurrinessX = blurFe->getstdDeviation().X * scale.x * context.matrix().getScaleX(); |
| 192 | auto blurrinessY = blurFe->getstdDeviation().Y * scale.y * context.matrix().getScaleY(); |
| 193 | auto colorMatrixFe = std::static_pointer_cast<SVGFeColorMatrix>(children[compositeIndex + 1]); |
| 194 | auto colorMatrix = colorMatrixFe->getValues(); |
| 195 | Color color{colorMatrix[4], colorMatrix[9], colorMatrix[14], colorMatrix[18]}; |
| 196 | |
| 197 | if (compositeIndex + 2 < children.size() && |
| 198 | children[compositeIndex + 2]->tag() == SVGTag::FeBlend) { |
| 199 | return ImageFilter::InnerShadow(dx, dy, blurrinessX, blurrinessY, color); |
| 200 | } |
| 201 | return ImageFilter::InnerShadowOnly(dx, dy, blurrinessX, blurrinessY, color); |
| 202 | } |
| 203 | return nullptr; |
| 204 | } |
| 205 | |
| 206 | } // namespace tgfx |