FilterOutsets FilterOperations::outsets() const
{
    FilterOutsets totalOutsets;
    for (size_t i = 0; i < m_operations.size(); ++i) {
        FilterOperation* filterOperation = m_operations.at(i).get();
        switch (filterOperation->type()) {
        case FilterOperation::BLUR: {
            BlurFilterOperation* blurOperation = toBlurFilterOperation(filterOperation);
            float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
            IntSize outsetSize = outsetSizeForBlur(stdDeviation);
            FilterOutsets outsets(outsetSize.height(), outsetSize.width(), outsetSize.height(), outsetSize.width());
            totalOutsets += outsets;
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation);
            IntSize outsetSize = outsetSizeForBlur(dropShadowOperation->stdDeviation());
            FilterOutsets outsets(
                std::max(0, outsetSize.height() - dropShadowOperation->y()),
                std::max(0, outsetSize.width() + dropShadowOperation->x()),
                std::max(0, outsetSize.height() + dropShadowOperation->y()),
                std::max(0, outsetSize.width() - dropShadowOperation->x())
            );
            totalOutsets += outsets;
            break;
        }
        default:
            break;
        }
    }
    return totalOutsets;
}
FilterOutsets FilterOperations::outsets() const
{
    FilterOutsets totalOutsets;
    for (size_t i = 0; i < m_operations.size(); ++i) {
        FilterOperation* filterOperation = m_operations.at(i).get();
        switch (filterOperation->type()) {
        case FilterOperation::BLUR: {
            BlurFilterOperation* blurOperation = toBlurFilterOperation(filterOperation);
            float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
            IntSize outsetSize = outsetSizeForBlur(stdDeviation);
            FilterOutsets outsets(outsetSize.height(), outsetSize.width(), outsetSize.height(), outsetSize.width());
            totalOutsets += outsets;
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation);
            IntSize outsetSize = outsetSizeForBlur(dropShadowOperation->stdDeviation());
            FilterOutsets outsets(
                std::max(0, outsetSize.height() - dropShadowOperation->y()),
                std::max(0, outsetSize.width() + dropShadowOperation->x()),
                std::max(0, outsetSize.height() + dropShadowOperation->y()),
                std::max(0, outsetSize.width() - dropShadowOperation->x())
            );
            totalOutsets += outsets;
            break;
        }
        case FilterOperation::REFERENCE: {
            ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
            if (referenceOperation->filter() && referenceOperation->filter()->lastEffect()) {
                FloatRect outsetRect(0, 0, 1, 1);
                outsetRect = referenceOperation->filter()->lastEffect()->mapRectRecursive(outsetRect);
                FilterOutsets outsets(
                    std::max(0.0f, -outsetRect.y()),
                    std::max(0.0f, outsetRect.x() + outsetRect.width() - 1),
                    std::max(0.0f, outsetRect.y() + outsetRect.height() - 1),
                    std::max(0.0f, -outsetRect.x())
                );
                totalOutsets += outsets;
            }
            break;
        }
        default:
            break;
        }
    }
    return totalOutsets;
}