Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/SVG/SVGFilterElement.cpp (C++)

Code before:
                    }
                    return Gfx::CompositingAndBlendingOperator::SourceOver;
                };

                root_filter = Gfx::Filter::blend(background, foreground, to_compositing_and_blending_operator(operator_));
            }

            update_result_map(*composite_primitive);
        } else if (auto* blur_primitive = as_if<SVGFEGaussianBlurElement>(node)) {
            auto input = resolve_input_filter(blur_primitive->in1()->base_val());

            auto radius_x = blur_primitive->std_deviation_x()->base_val();
            auto radius_y = blur_primitive->std_deviation_y()->base_val();

            root_filter = Gfx::Filter::blur(radius_x, radius_y, input);
            update_result_map(*blur_primitive);
        } else if (auto* colormatrix_primitive = as_if<SVGFEColorMatrixElement>(node)) {
            auto in_attr = colormatrix_primitive->in1()->base_val();
            auto input = resolve_input_filter(in_attr);

            auto type_value = colormatrix_primitive->attribute(AttributeNames::type).value_or(String {});
            auto values_value = colormatrix_primitive->attribute(AttributeNames::values).value_or(String {});

            auto equals_ci = [](StringView a, StringView b) {
                return AK::StringUtils::equals_ignoring_ascii_case(a, b);
            };

            // Default type is "matrix" per spec.
            if (type_value.is_empty() || equals_ci(type_value, "matrix"sv)) {
                // Parse up to 20 numbers; if we don't get a full 4x5, skip applying.
                float matrix[20] = { 0 };
                size_t count = 0;

                StringView sv = values_value;
                auto skip_leading_whitespace = [&] {
                    sv = sv.trim_whitespace(AK::TrimMode::Left);
                };
                auto consume_comma_and_whitespace = [&] {
                    if (!sv.is_empty() && sv[0] == ',')
                        sv = sv.substring_view(1);
                    skip_leading_whitespace();
                };

                skip_leading_whitespace();
                while (!sv.is_empty() && count < 20) {
                    // Parse the next number without trimming (we already trimmed on the left).
                    auto result = AK::parse_first_number<float>(sv, AK::TrimWhitespace::No);
                    if (!result.has_value())
                        break;
                    matrix[count++] = result->value;
                    // Advance exactly past the number just parsed, then consume optional comma + whitespace.

Review comment (refactor):
This helper seems a bit useless, you can just call `type_value.equals_ignoring_ascii_case(StringView)`?

Code after:
                    sv = sv.trim_whitespace(AK::TrimMode::Left);
                };
                auto consume_comma_and_whitespace = [&] {
                    if (!sv.is_empty() && sv[0] == ',')
                        sv = sv.substring_view(1);
                    skip_leading_whitespace();
                };

                skip_leading_whitespace();
                while (!sv.is_empty() && count < 20) {
                    // Parse the next number without trimming (we already trimmed on the left).
                    auto result = AK::parse_first_number<float>(sv, AK::TrimWhitespace::No);
                    if (!result.has_value())
                        break;
                    matrix[count++] = result->value;
                    // Advance exactly past the number just parsed, then consume optional comma + whitespace.
                    sv = sv.substring_view(result->characters_parsed);
                    consume_comma_and_whitespace();
                }

                if (count == 20) {
                    root_filter = Gfx::Filter::color_matrix(matrix, input);
                    update_result_map(*colormatrix_primitive);
                } else {
                    // If invalid or missing, treat as identity (no-op) if we already have an input.
                    if (input.has_value()) {
                        root_filter = input;
                        update_result_map(*colormatrix_primitive);
                    }
                }
            } else if (type_value.equals_ignoring_ascii_case("saturate"sv)) {
                // values: single number s (1 = original)
                float s = 1.0f;
                if (!values_value.is_empty()) {
                    if (auto parsed = AK::parse_number<float>(values_value, AK::TrimWhitespace::Yes); parsed.has_value())
                        s = *parsed;
                }
                root_filter = Gfx::Filter::saturate(s, input);
                update_result_map(*colormatrix_primitive);
            } else if (type_value.equals_ignoring_ascii_case("hueRotate"sv)) {
                // values: angle in degrees
                float angle_degrees = 0.0f;
                if (!values_value.is_empty()) {
                    if (auto parsed = AK::parse_number<float>(values_value, AK::TrimWhitespace::Yes); parsed.has_value())
                        angle_degrees = *parsed;
                }
                root_filter = Gfx::Filter::hue_rotate(angle_degrees, input);
                update_result_map(*colormatrix_primitive);
            } else if (type_value.equals_ignoring_ascii_case("luminanceToAlpha"sv)) {
                // values ignored; convert luminance to alpha and zero RGB.
                float matrix[20] = {