/*
 * Copyright 2006-2012 The Android Open Source Project
 * Copyright 2012 Mozilla Foundation
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkOpenTypeSVGDecoder.h"
#include "include/core/SkPath.h"
#include "include/effects/SkGradientShader.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/SkColorData.h"
#include "include/private/SkTo.h"
#include "src/core/SkFDot6.h"
#include "src/ports/SkFontHost_FreeType_common.h"

#include <algorithm>
#include <utility>

#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftbitmap.h>
#ifdef FT_COLOR_H
#   include <freetype/ftcolor.h>
#endif
#include <freetype/ftimage.h>
#include <freetype/ftoutln.h>
#include <freetype/ftsizes.h>
// In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file.
#include <freetype/ftsynth.h>

namespace {
[[maybe_unused]] static inline const constexpr bool kSkShowTextBlitCoverage = false;
}

#if defined(FT_CONFIG_OPTION_SVG)
#   include <freetype/otsvg.h>
#endif

#ifdef TT_SUPPORT_COLRV1
// FT_ClipBox and FT_Get_Color_Glyph_ClipBox introduced VER-2-11-0-18-g47cf8ebf4
// FT_COLR_COMPOSITE_PLUS and renumbering introduced VER-2-11-0-21-ge40ae7569
// FT_SIZEOF_LONG_LONG introduced VER-2-11-0-31-gffdac8d67
// FT_PaintRadialGradient changed size and layout at VER-2-11-0-147-gd3d3ff76d
// FT_STATIC_CAST introduced VER-2-11-0-172-g9079c5d91
// So undefine TT_SUPPORT_COLRV1 before 2.11.1 but not if FT_STATIC_CAST is defined.
#if (((FREETYPE_MAJOR)  < 2) || \
     ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR)  < 11) || \
     ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) == 11 && (FREETYPE_PATCH) < 1)) && \
    !defined(FT_STATIC_CAST)
#    undef TT_SUPPORT_COLRV1
#else
#    include "src/core/SkScopeExit.h"
#endif
#endif

// FT_OUTLINE_OVERLAP was added in FreeType 2.10.3
#ifndef FT_OUTLINE_OVERLAP
#    define FT_OUTLINE_OVERLAP 0x40
#endif

// FT_LOAD_COLOR and the corresponding FT_Pixel_Mode::FT_PIXEL_MODE_BGRA
// were introduced in FreeType 2.5.0.
// The following may be removed once FreeType 2.5.0 is required to build.
#ifndef FT_LOAD_COLOR
#    define FT_LOAD_COLOR ( 1L << 20 )
#    define FT_PIXEL_MODE_BGRA 7
#endif

#ifdef SK_DEBUG
const char* SkTraceFtrGetError(int e) {
    switch ((FT_Error)e) {
        #undef FTERRORS_H_
        #define FT_ERRORDEF( e, v, s ) case v: return s;
        #define FT_ERROR_START_LIST
        #define FT_ERROR_END_LIST
        #include FT_ERRORS_H
        #undef FT_ERRORDEF
        #undef FT_ERROR_START_LIST
        #undef FT_ERROR_END_LIST
        default: return "";
    }
}
#endif  // SK_DEBUG

#ifdef TT_SUPPORT_COLRV1
bool operator==(const FT_OpaquePaint& a, const FT_OpaquePaint& b) {
    return a.p == b.p && a.insert_root_transform == b.insert_root_transform;
}

// The stop_offset field is being upgraded to a larger representation in FreeType, and changed from
// 2.14 to 16.16. Adjust the shift factor depending on size type.
static_assert(sizeof(FT_Fixed) != sizeof(FT_F2Dot14));
constexpr float kColorStopShift =
    sizeof(FT_ColorStop::stop_offset) == sizeof(FT_F2Dot14) ? 1 << 14 : 1 << 16;
#endif

namespace {

FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
    switch (format) {
        case SkMask::kBW_Format:
            return FT_PIXEL_MODE_MONO;
        case SkMask::kA8_Format:
        default:
            return FT_PIXEL_MODE_GRAY;
    }
}

///////////////////////////////////////////////////////////////////////////////

uint16_t packTriple(U8CPU r, U8CPU g, U8CPU b) {
    if constexpr (kSkShowTextBlitCoverage) {
        r = std::max(r, (U8CPU)0x40);
        g = std::max(g, (U8CPU)0x40);
        b = std::max(b, (U8CPU)0x40);
    }
    return SkPack888ToRGB16(r, g, b);
}

uint16_t grayToRGB16(U8CPU gray) {
    if constexpr (kSkShowTextBlitCoverage) {
        gray = std::max(gray, (U8CPU)0x40);
    }
    return SkPack888ToRGB16(gray, gray, gray);
}

int bittst(const uint8_t data[], int bitOffset) {
    SkASSERT(bitOffset >= 0);
    int lowBit = data[bitOffset >> 3] >> (~bitOffset & 7);
    return lowBit & 1;
}

/**
 *  Copies a FT_Bitmap into an SkMask with the same dimensions.
 *
 *  FT_PIXEL_MODE_MONO
 *  FT_PIXEL_MODE_GRAY
 *  FT_PIXEL_MODE_LCD
 *  FT_PIXEL_MODE_LCD_V
 */
template<bool APPLY_PREBLEND>
void copyFT2LCD16(const FT_Bitmap& bitmap, const SkMask& mask, int lcdIsBGR,
                  const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB)
{
    SkASSERT(SkMask::kLCD16_Format == mask.fFormat);
    if (FT_PIXEL_MODE_LCD != bitmap.pixel_mode) {
        SkASSERT(mask.fBounds.width() == static_cast<int>(bitmap.width));
    }
    if (FT_PIXEL_MODE_LCD_V != bitmap.pixel_mode) {
        SkASSERT(mask.fBounds.height() == static_cast<int>(bitmap.rows));
    }

    const uint8_t* src = bitmap.buffer;
    uint16_t* dst = reinterpret_cast<uint16_t*>(mask.fImage);
    const size_t dstRB = mask.fRowBytes;

    const int width = mask.fBounds.width();
    const int height = mask.fBounds.height();

    switch (bitmap.pixel_mode) {
        case FT_PIXEL_MODE_MONO:
            for (int y = height; y --> 0;) {
                for (int x = 0; x < width; ++x) {
                    dst[x] = -bittst(src, x);
                }
                dst = (uint16_t*)((char*)dst + dstRB);
                src += bitmap.pitch;
            }
            break;
        case FT_PIXEL_MODE_GRAY:
            for (int y = height; y --> 0;) {
                for (int x = 0; x < width; ++x) {
                    dst[x] = grayToRGB16(src[x]);
                }
                dst = (uint16_t*)((char*)dst + dstRB);
                src += bitmap.pitch;
            }
            break;
        case FT_PIXEL_MODE_LCD:
            SkASSERT(3 * mask.fBounds.width() == static_cast<int>(bitmap.width));
            for (int y = height; y --> 0;) {
                const uint8_t* triple = src;
                if (lcdIsBGR) {
                    for (int x = 0; x < width; x++) {
                        dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>(triple[2], tableR),
                                            sk_apply_lut_if<APPLY_PREBLEND>(triple[1], tableG),
                                            sk_apply_lut_if<APPLY_PREBLEND>(triple[0], tableB));
                        triple += 3;
                    }
                } else {
                    for (int x = 0; x < width; x++) {
                        dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>(triple[0], tableR),
                                            sk_apply_lut_if<APPLY_PREBLEND>(triple[1], tableG),
                                            sk_apply_lut_if<APPLY_PREBLEND>(triple[2], tableB));
                        triple += 3;
                    }
                }
                src += bitmap.pitch;
                dst = (uint16_t*)((char*)dst + dstRB);
            }
            break;
        case FT_PIXEL_MODE_LCD_V:
            SkASSERT(3 * mask.fBounds.height() == static_cast<int>(bitmap.rows));
            for (int y = height; y --> 0;) {
                const uint8_t* srcR = src;
                const uint8_t* srcG = srcR + bitmap.pitch;
                const uint8_t* srcB = srcG + bitmap.pitch;
                if (lcdIsBGR) {
                    using std::swap;
                    swap(srcR, srcB);
                }
                for (int x = 0; x < width; x++) {
                    dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>(*srcR++, tableR),
                                        sk_apply_lut_if<APPLY_PREBLEND>(*srcG++, tableG),
                                        sk_apply_lut_if<APPLY_PREBLEND>(*srcB++, tableB));
                }
                src += 3 * bitmap.pitch;
                dst = (uint16_t*)((char*)dst + dstRB);
            }
            break;
        default:
            SkDEBUGF("FT_Pixel_Mode %d", bitmap.pixel_mode);
            SkDEBUGFAIL("unsupported FT_Pixel_Mode for LCD16");
            break;
    }
}

/**
 *  Copies a FT_Bitmap into an SkMask with the same dimensions.
 *
 *  Yes, No, Never Requested, Never Produced
 *
 *                        kBW kA8 k3D kARGB32 kLCD16
 *  FT_PIXEL_MODE_MONO     Y   Y  NR     N       Y
 *  FT_PIXEL_MODE_GRAY     N   Y  NR     N       Y
 *  FT_PIXEL_MODE_GRAY2   NP  NP  NR    NP      NP
 *  FT_PIXEL_MODE_GRAY4   NP  NP  NR    NP      NP
 *  FT_PIXEL_MODE_LCD     NP  NP  NR    NP      NP
 *  FT_PIXEL_MODE_LCD_V   NP  NP  NR    NP      NP
 *  FT_PIXEL_MODE_BGRA     N   N  NR     Y       N
 *
 *  TODO: All of these N need to be Y or otherwise ruled out.
 */
void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
    SkASSERTF(dstMask.fBounds.width() == static_cast<int>(srcFTBitmap.width),
              "dstMask.fBounds.width() = %d\n"
              "static_cast<int>(srcFTBitmap.width) = %d",
              dstMask.fBounds.width(),
              static_cast<int>(srcFTBitmap.width)
    );
    SkASSERTF(dstMask.fBounds.height() == static_cast<int>(srcFTBitmap.rows),
              "dstMask.fBounds.height() = %d\n"
              "static_cast<int>(srcFTBitmap.rows) = %d",
              dstMask.fBounds.height(),
              static_cast<int>(srcFTBitmap.rows)
    );

    const uint8_t* src = reinterpret_cast<const uint8_t*>(srcFTBitmap.buffer);
    const FT_Pixel_Mode srcFormat = static_cast<FT_Pixel_Mode>(srcFTBitmap.pixel_mode);
    // FT_Bitmap::pitch is an int and allowed to be negative.
    const int srcPitch = srcFTBitmap.pitch;
    const size_t srcRowBytes = SkTAbs(srcPitch);

    uint8_t* dst = dstMask.fImage;
    const SkMask::Format dstFormat = static_cast<SkMask::Format>(dstMask.fFormat);
    const size_t dstRowBytes = dstMask.fRowBytes;

    const size_t width = srcFTBitmap.width;
    const size_t height = srcFTBitmap.rows;

    if (SkMask::kLCD16_Format == dstFormat) {
        copyFT2LCD16<false>(srcFTBitmap, dstMask, false, nullptr, nullptr, nullptr);
        return;
    }

    if ((FT_PIXEL_MODE_MONO == srcFormat && SkMask::kBW_Format == dstFormat) ||
        (FT_PIXEL_MODE_GRAY == srcFormat && SkMask::kA8_Format == dstFormat))
    {
        size_t commonRowBytes = std::min(srcRowBytes, dstRowBytes);
        for (size_t y = height; y --> 0;) {
            memcpy(dst, src, commonRowBytes);
            src += srcPitch;
            dst += dstRowBytes;
        }
    } else if (FT_PIXEL_MODE_MONO == srcFormat && SkMask::kA8_Format == dstFormat) {
        for (size_t y = height; y --> 0;) {
            uint8_t byte = 0;
            int bits = 0;
            const uint8_t* src_row = src;
            uint8_t* dst_row = dst;
            for (size_t x = width; x --> 0;) {
                if (0 == bits) {
                    byte = *src_row++;
                    bits = 8;
                }
                *dst_row++ = byte & 0x80 ? 0xff : 0x00;
                bits--;
                byte <<= 1;
            }
            src += srcPitch;
            dst += dstRowBytes;
        }
    } else if (FT_PIXEL_MODE_BGRA == srcFormat && SkMask::kARGB32_Format == dstFormat) {
        // FT_PIXEL_MODE_BGRA is pre-multiplied.
        for (size_t y = height; y --> 0;) {
            const uint8_t* src_row = src;
            SkPMColor* dst_row = reinterpret_cast<SkPMColor*>(dst);
            for (size_t x = 0; x < width; ++x) {
                uint8_t b = *src_row++;
                uint8_t g = *src_row++;
                uint8_t r = *src_row++;
                uint8_t a = *src_row++;
                *dst_row++ = SkPackARGB32(a, r, g, b);
                if constexpr (kSkShowTextBlitCoverage) {
                    *(dst_row-1) = SkFourByteInterp256(*(dst_row-1), SK_ColorWHITE, 0x40);
                }
            }
            src += srcPitch;
            dst += dstRowBytes;
        }
    } else {
        SkDEBUGF("FT_Pixel_Mode %d, SkMask::Format %d\n", srcFormat, dstFormat);
        SkDEBUGFAIL("unsupported combination of FT_Pixel_Mode and SkMask::Format");
    }
}

inline int convert_8_to_1(unsigned byte) {
    SkASSERT(byte <= 0xFF);
    // Arbitrary decision that making the cutoff at 1/4 instead of 1/2 in general looks better.
    return (byte >> 6) != 0;
}

uint8_t pack_8_to_1(const uint8_t alpha[8]) {
    unsigned bits = 0;
    for (int i = 0; i < 8; ++i) {
        bits <<= 1;
        bits |= convert_8_to_1(alpha[i]);
    }
    return SkToU8(bits);
}

void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
    const int height = mask.fBounds.height();
    const int width = mask.fBounds.width();
    const int octs = width >> 3;
    const int leftOverBits = width & 7;

    uint8_t* dst = mask.fImage;
    const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
    SkASSERT(dstPad >= 0);

    const int srcPad = srcRB - width;
    SkASSERT(srcPad >= 0);

    for (int y = 0; y < height; ++y) {
        for (int i = 0; i < octs; ++i) {
            *dst++ = pack_8_to_1(src);
            src += 8;
        }
        if (leftOverBits > 0) {
            unsigned bits = 0;
            int shift = 7;
            for (int i = 0; i < leftOverBits; ++i, --shift) {
                bits |= convert_8_to_1(*src++) << shift;
            }
            *dst++ = bits;
        }
        src += srcPad;
        dst += dstPad;
    }
}

inline SkMask::Format SkMaskFormat_for_SkColorType(SkColorType colorType) {
    switch (colorType) {
        case kAlpha_8_SkColorType:
            return SkMask::kA8_Format;
        case kN32_SkColorType:
            return SkMask::kARGB32_Format;
        default:
            SkDEBUGFAIL("unsupported SkBitmap::Config");
            return SkMask::kA8_Format;
    }
}

inline SkColorType SkColorType_for_FTPixelMode(FT_Pixel_Mode pixel_mode) {
    switch (pixel_mode) {
        case FT_PIXEL_MODE_MONO:
        case FT_PIXEL_MODE_GRAY:
            return kAlpha_8_SkColorType;
        case FT_PIXEL_MODE_BGRA:
            return kN32_SkColorType;
        default:
            SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
            return kAlpha_8_SkColorType;
    }
}

inline SkColorType SkColorType_for_SkMaskFormat(SkMask::Format format) {
    switch (format) {
        case SkMask::kBW_Format:
        case SkMask::kA8_Format:
        case SkMask::kLCD16_Format:
            return kAlpha_8_SkColorType;
        case SkMask::kARGB32_Format:
            return kN32_SkColorType;
        default:
            SkDEBUGFAIL("unsupported destination SkBitmap::Config");
            return kAlpha_8_SkColorType;
    }
}

// Only build COLRv1 rendering code if FreeType is new enough to have COLRv1
// additions. FreeType defines a macro in the ftoption header to tell us whether
// it does support these features.
#ifdef TT_SUPPORT_COLRV1

const uint16_t kForegroundColorPaletteIndex = 0xFFFF;

struct OpaquePaintHasher {
  size_t operator()(const FT_OpaquePaint& opaquePaint) {
      return SkGoodHash()(opaquePaint.p) ^
             SkGoodHash()(opaquePaint.insert_root_transform);
  }
};

using VisitedSet = SkTHashSet<FT_OpaquePaint, OpaquePaintHasher>;

bool generateFacePathCOLRv1(FT_Face face, SkGlyphID glyphID, SkPath* path);

inline float SkColrV1AlphaToFloat(uint16_t alpha) { return (alpha / float(1 << 14)); }


inline SkTileMode ToSkTileMode(FT_PaintExtend extendMode) {
    switch (extendMode) {
        case FT_COLR_PAINT_EXTEND_REPEAT:
            return SkTileMode::kRepeat;
        case FT_COLR_PAINT_EXTEND_REFLECT:
            return SkTileMode::kMirror;
        default:
            return SkTileMode::kClamp;
    }
}

inline SkBlendMode ToSkBlendMode(FT_Composite_Mode compositeMode) {
    switch (compositeMode) {
        case FT_COLR_COMPOSITE_CLEAR:
            return SkBlendMode::kClear;
        case FT_COLR_COMPOSITE_SRC:
            return SkBlendMode::kSrc;
        case FT_COLR_COMPOSITE_DEST:
            return SkBlendMode::kDst;
        case FT_COLR_COMPOSITE_SRC_OVER:
            return SkBlendMode::kSrcOver;
        case FT_COLR_COMPOSITE_DEST_OVER:
            return SkBlendMode::kDstOver;
        case FT_COLR_COMPOSITE_SRC_IN:
            return SkBlendMode::kSrcIn;
        case FT_COLR_COMPOSITE_DEST_IN:
            return SkBlendMode::kDstIn;
        case FT_COLR_COMPOSITE_SRC_OUT:
            return SkBlendMode::kSrcOut;
        case FT_COLR_COMPOSITE_DEST_OUT:
            return SkBlendMode::kDstOut;
        case FT_COLR_COMPOSITE_SRC_ATOP:
            return SkBlendMode::kSrcATop;
        case FT_COLR_COMPOSITE_DEST_ATOP:
            return SkBlendMode::kDstATop;
        case FT_COLR_COMPOSITE_XOR:
            return SkBlendMode::kXor;
        case FT_COLR_COMPOSITE_PLUS:
            return SkBlendMode::kPlus;
        case FT_COLR_COMPOSITE_SCREEN:
            return SkBlendMode::kScreen;
        case FT_COLR_COMPOSITE_OVERLAY:
            return SkBlendMode::kOverlay;
        case FT_COLR_COMPOSITE_DARKEN:
            return SkBlendMode::kDarken;
        case FT_COLR_COMPOSITE_LIGHTEN:
            return SkBlendMode::kLighten;
        case FT_COLR_COMPOSITE_COLOR_DODGE:
            return SkBlendMode::kColorDodge;
        case FT_COLR_COMPOSITE_COLOR_BURN:
            return SkBlendMode::kColorBurn;
        case FT_COLR_COMPOSITE_HARD_LIGHT:
            return SkBlendMode::kHardLight;
        case FT_COLR_COMPOSITE_SOFT_LIGHT:
            return SkBlendMode::kSoftLight;
        case FT_COLR_COMPOSITE_DIFFERENCE:
            return SkBlendMode::kDifference;
        case FT_COLR_COMPOSITE_EXCLUSION:
            return SkBlendMode::kExclusion;
        case FT_COLR_COMPOSITE_MULTIPLY:
            return SkBlendMode::kMultiply;
        case FT_COLR_COMPOSITE_HSL_HUE:
            return SkBlendMode::kHue;
        case FT_COLR_COMPOSITE_HSL_SATURATION:
            return SkBlendMode::kSaturation;
        case FT_COLR_COMPOSITE_HSL_COLOR:
            return SkBlendMode::kColor;
        case FT_COLR_COMPOSITE_HSL_LUMINOSITY:
            return SkBlendMode::kLuminosity;
        default:
            return SkBlendMode::kDst;
    }
}

inline SkMatrix ToSkMatrix(FT_Affine23 affine23) {
    // Convert from FreeType's FT_Affine23 column major order to SkMatrix row-major order.
    return SkMatrix::MakeAll(
         SkFixedToScalar(affine23.xx), -SkFixedToScalar(affine23.xy),  SkFixedToScalar(affine23.dx),
        -SkFixedToScalar(affine23.yx),  SkFixedToScalar(affine23.yy), -SkFixedToScalar(affine23.dy),
         0,                             0,                             1);
}

inline SkPoint SkVectorProjection(SkPoint a, SkPoint b) {
    SkScalar length = b.length();
    if (!length) {
        return SkPoint();
    }
    SkPoint bNormalized = b;
    bNormalized.normalize();
    bNormalized.scale(SkPoint::DotProduct(a, b) / length);
    return bNormalized;
}

bool colrv1_configure_skpaint(FT_Face face,
                              const SkSpan<SkColor>& palette,
                              const SkColor foregroundColor,
                              const FT_COLR_Paint& colrPaint,
                              SkPaint* paint) {
    auto fetchColorStops = [&face, &palette, &foregroundColor](
                                               const FT_ColorStopIterator& colorStopIterator,
                                               std::vector<SkScalar>& stops,
                                               std::vector<SkColor>& colors) -> bool {
        const FT_UInt colorStopCount = colorStopIterator.num_color_stops;
        if (colorStopCount == 0) {
            return false;
        }

        // 5.7.11.2.4 ColorIndex, ColorStop and ColorLine
        // "Applications shall apply the colorStops in increasing stopOffset order."
        struct ColorStop {
            SkScalar pos;
            SkColor color;
        };
        std::vector<ColorStop> colorStopsSorted;
        colorStopsSorted.resize(colorStopCount);

        FT_ColorStop color_stop;
        FT_ColorStopIterator mutable_color_stop_iterator = colorStopIterator;
        while (FT_Get_Colorline_Stops(face, &color_stop, &mutable_color_stop_iterator)) {
            FT_UInt index = mutable_color_stop_iterator.current_color_stop - 1;
            colorStopsSorted[index].pos = color_stop.stop_offset / kColorStopShift;
            FT_UInt16& palette_index = color_stop.color.palette_index;
            if (palette_index == kForegroundColorPaletteIndex) {
                U8CPU newAlpha = SkColorGetA(foregroundColor) *
                                 SkColrV1AlphaToFloat(color_stop.color.alpha);
                colorStopsSorted[index].color = SkColorSetA(foregroundColor, newAlpha);
            } else if (palette_index >= palette.size()) {
                return false;
            } else {
                U8CPU newAlpha = SkColorGetA(palette[palette_index]) *
                                 SkColrV1AlphaToFloat(color_stop.color.alpha);
                colorStopsSorted[index].color = SkColorSetA(palette[palette_index], newAlpha);
            }
        }

        std::stable_sort(colorStopsSorted.begin(), colorStopsSorted.end(),
                         [](const ColorStop& a, const ColorStop& b) { return a.pos < b.pos; });

        stops.resize(colorStopCount);
        colors.resize(colorStopCount);
        for (size_t i = 0; i < colorStopCount; ++i) {
            stops[i] = colorStopsSorted[i].pos;
            colors[i] = colorStopsSorted[i].color;
        }
        return true;
    };

    switch (colrPaint.format) {
        case FT_COLR_PAINTFORMAT_SOLID: {
            FT_PaintSolid solid = colrPaint.u.solid;

            // Dont' draw anything with this color if the palette index is out of bounds.
            SkColor color = SK_ColorTRANSPARENT;
            if (solid.color.palette_index == kForegroundColorPaletteIndex) {
                U8CPU newAlpha = SkColorGetA(foregroundColor) *
                                 SkColrV1AlphaToFloat(solid.color.alpha);
                color = SkColorSetA(foregroundColor, newAlpha);
            } else if (solid.color.palette_index >= palette.size()) {
                return false;
            } else {
                U8CPU newAlpha = SkColorGetA(palette[solid.color.palette_index]) *
                                 SkColrV1AlphaToFloat(solid.color.alpha);
                color = SkColorSetA(palette[solid.color.palette_index], newAlpha);
            }
            paint->setShader(nullptr);
            paint->setColor(color);
            return true;
        }
        case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT: {
            const FT_PaintLinearGradient& linearGradient = colrPaint.u.linear_gradient;
            std::vector<SkScalar> stops;
            std::vector<SkColor> colors;

            if (!fetchColorStops(linearGradient.colorline.color_stop_iterator, stops, colors)) {
                return false;
            }

            if (stops.size() == 1) {
                paint->setColor(colors[0]);
                return true;
            }

            SkPoint linePositions[2] = {SkPoint::Make( SkFixedToScalar(linearGradient.p0.x),
                                                      -SkFixedToScalar(linearGradient.p0.y)),
                                        SkPoint::Make( SkFixedToScalar(linearGradient.p1.x),
                                                      -SkFixedToScalar(linearGradient.p1.y))};
            SkPoint p0 = linePositions[0];
            SkPoint p1 = linePositions[1];
            SkPoint p2 = SkPoint::Make( SkFixedToScalar(linearGradient.p2.x),
                                       -SkFixedToScalar(linearGradient.p2.y));

            // If p0p1 or p0p2 are degenerate probably nothing should be drawn.
            // If p0p1 and p0p2 are parallel then one side is the first color and the other side is
            // the last color, depending on the direction.
            // For now, just use the first color.
            if (p1 == p0 || p2 == p0 || !SkPoint::CrossProduct(p1 - p0, p2 - p0)) {
                paint->setColor(colors[0]);
                return true;
            }

            // Follow implementation note in nanoemoji:
            // https://github.com/googlefonts/nanoemoji/blob/0ac6e7bb4d8202db692574d8530a9b643f1b3b3c/src/nanoemoji/svg.py#L188
            // to compute a new gradient end point P3 as the orthogonal
            // projection of the vector from p0 to p1 onto a line perpendicular
            // to line p0p2 and passing through p0.
            SkVector perpendicularToP2P0 = (p2 - p0);
            perpendicularToP2P0 = SkPoint::Make( perpendicularToP2P0.y(),
                                                -perpendicularToP2P0.x());
            SkVector p3 = p0 + SkVectorProjection((p1 - p0), perpendicularToP2P0);
            linePositions[1] = p3;

            // Project/scale points according to stop extrema along p0p3 line,
            // p3 being the result of the projection above, then scale stops to
            // to [0, 1] range so that repeat modes work.  The Skia linear
            // gradient shader performs the repeat modes over the 0 to 1 range,
            // that's why we need to scale the stops to within that range.
            SkTileMode tileMode = ToSkTileMode(linearGradient.colorline.extend);
            SkScalar colorStopRange = stops.back() - stops.front();
            // If the color stops are all at the same offset position, repeat and reflect modes
            // become meaningless.
            if (colorStopRange == 0.f && tileMode != SkTileMode::kClamp) {
                paint->setColor(SK_ColorTRANSPARENT);
                return true;
            }

            // If the colorStopRange is 0 at this point, the default behavior of the shader is to
            // clamp to 1 color stops that are above 1, clamp to 0 for color stops that are below 0,
            // and repeat the outer color stops at 0 and 1 if the color stops are inside the
            // range. That will result in the correct rendering.
            if ((colorStopRange != 1 || stops.front() != 0.f) && colorStopRange != 0.f) {
                SkVector p0p3 = p3 - p0;
                SkVector p0Offset = p0p3;
                p0Offset.scale(stops.front());
                SkVector p1Offset = p0p3;
                p1Offset.scale(stops.back());

                linePositions[0] = p0 + p0Offset;
                linePositions[1] = p0 + p1Offset;

                SkScalar scaleFactor = 1 / colorStopRange;
                SkScalar startOffset = stops.front();
                for (SkScalar& stop : stops) {
                    stop = (stop - startOffset) * scaleFactor;
                }
            }

            sk_sp<SkShader> shader(SkGradientShader::MakeLinear(
                                   linePositions,
                                   colors.data(), stops.data(), stops.size(),
                                   tileMode));
            SkASSERT(shader);
            // An opaque color is needed to ensure the gradient is not modulated by alpha.
            paint->setColor(SK_ColorBLACK);
            paint->setShader(shader);
            return true;
        }
        case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT: {
            const FT_PaintRadialGradient& radialGradient = colrPaint.u.radial_gradient;
            SkPoint start = SkPoint::Make( SkFixedToScalar(radialGradient.c0.x),
                                          -SkFixedToScalar(radialGradient.c0.y));
            SkScalar startRadius = SkFixedToScalar(radialGradient.r0);
            SkPoint end = SkPoint::Make( SkFixedToScalar(radialGradient.c1.x),
                                        -SkFixedToScalar(radialGradient.c1.y));
            SkScalar endRadius = SkFixedToScalar(radialGradient.r1);


            std::vector<SkScalar> stops;
            std::vector<SkColor> colors;
            if (!fetchColorStops(radialGradient.colorline.color_stop_iterator, stops, colors)) {
                return false;
            }

            if (stops.size() == 1) {
                paint->setColor(colors[0]);
                return true;
            }

            SkScalar colorStopRange = stops.back() - stops.front();
            SkTileMode tileMode = ToSkTileMode(radialGradient.colorline.extend);

            if (colorStopRange == 0.f && tileMode != SkTileMode::kClamp) {
                paint->setColor(SK_ColorTRANSPARENT);
                return true;
            }

            // If the colorStopRange is 0 at this point, the default behavior of the shader is to
            // clamp to 1 color stops that are above 1, clamp to 0 for color stops that are below 0,
            // and repeat the outer color stops at 0 and 1 if the color stops are inside the
            // range. That will result in the correct rendering.
            if ((colorStopRange != 1 || stops.front() != 0.f) && colorStopRange != 0.f) {
                // For the Skia two-point caonical shader to understand the
                // COLRv1 color stops we need to scale stops to 0 to 1 range and
                // interpolate new centers and radii. Otherwise the shader
                // clamps stops outside the range to 0 and 1 (larger interval)
                // or repeats the outer stops at 0 and 1 if the (smaller
                // interval).
                SkVector startToEnd = end - start;
                SkScalar radiusDiff = endRadius - startRadius;
                SkScalar scaleFactor = 1 / colorStopRange;
                SkScalar stopsStartOffset = stops.front();

                SkVector startOffset = startToEnd;
                startOffset.scale(stops.front());
                SkVector endOffset = startToEnd;
                endOffset.scale(stops.back());

                // The order of the following computations is important in order to avoid
                // overwriting start or startRadius before the second reassignment.
                end = start + endOffset;
                start = start + startOffset;
                endRadius = startRadius + radiusDiff * stops.back();
                startRadius = startRadius + radiusDiff * stops.front();

                for (auto& stop : stops) {
                    stop = (stop - stopsStartOffset) * scaleFactor;
                }
            }

            if (SkGraphics::GetVariableColrV1Enabled()) {
                // When radii become negative through variations or interpolation, convert them to
                // their absolute value. Resolution as discussed in
                // https://github.com/googlefonts/colr-gradients-spec/issues/367.
                startRadius = std::abs(startRadius);
                endRadius = std::abs(endRadius);
            } else if (startRadius < 0 || endRadius < 0) {
                // TODO(drott): Remove else part when variable COLRv1 becomes the default.
                paint->setColor(SK_ColorTRANSPARENT);
                return true;
            }

            // An opaque color is needed to ensure the gradient is not modulated by alpha.
            paint->setColor(SK_ColorBLACK);

            paint->setShader(SkGradientShader::MakeTwoPointConical(
                    start, startRadius, end, endRadius, colors.data(), stops.data(), stops.size(),
                    tileMode));
            return true;
        }
        case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: {
            const FT_PaintSweepGradient& sweepGradient = colrPaint.u.sweep_gradient;
            SkPoint center = SkPoint::Make( SkFixedToScalar(sweepGradient.center.x),
                                           -SkFixedToScalar(sweepGradient.center.y));


            SkScalar startAngle = SkFixedToScalar(sweepGradient.start_angle * 180.0f);
            SkScalar endAngle = SkFixedToScalar(sweepGradient.end_angle * 180.0f);
            if (SkGraphics::GetVariableColrV1Enabled()) {
                // OpenType 1.9.1 adds a shift to the angle to ease specification of a 0 to 360
                // degree sweep. We want to release that in sync with releasing variable COLRv1.
                startAngle += 180.0f;
                endAngle += 180.0f;
            }

            std::vector<SkScalar> stops;
            std::vector<SkColor> colors;
            if (!fetchColorStops(sweepGradient.colorline.color_stop_iterator, stops, colors)) {
                return false;
            }

            if (stops.size() == 1) {
                paint->setColor(colors[0]);
                return true;
            }

            // An opaque color is needed to ensure the gradient is not modulated by alpha.
            paint->setColor(SK_ColorBLACK);

            if (SkGraphics::GetVariableColrV1Enabled()) {
                // New (Var)SweepGradient implementation compliant with OpenType 1.9.1 from here.
                // The plan is to release this in sync with variable COLRv1 support.

                // The shader expects stops from 0 to 1, so we need to account for
                // minimum and maximum stop positions being different from 0 and
                // 1. We do that by scaling minimum and maximum stop positions to
                // the 0 to 1 interval and scaling the angles inverse proportionally.

                // 1) Scale angles to their equivalent positions if stops were from 0 to 1.

                SkScalar sectorAngle = endAngle - startAngle;
                SkTileMode tileMode = ToSkTileMode(sweepGradient.colorline.extend);
                if (sectorAngle == 0 && tileMode != SkTileMode::kClamp) {
                    // "If the ColorLine's extend mode is reflect or repeat and start and end angle
                    // are equal, nothing is drawn.".
                    paint->setColor(SK_ColorTRANSPARENT);
                    return true;
                }


                SkScalar startAngleScaled = startAngle + sectorAngle * stops.front();
                SkScalar endAngleScaled = startAngle + sectorAngle * stops.back();

                // 2) Scale stops accordingly to 0 to 1 range.
                SkScalar scaleFactor = 1 / (stops.back() - stops.front());
                SkScalar startOffset = stops.front();

                for (SkScalar& stop : stops) {
                    stop = (stop - startOffset) * scaleFactor;
                }

                /* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#sweep-gradients
                 * "The angles are expressed in counter-clockwise degrees from
                 * the direction of the positive x-axis on the design
                 * grid. [...]  The color line progresses from the start angle
                 * to the end angle in the counter-clockwise direction;" -
                 * convert angles and stops from counter-clockwise to clockwise
                 * for the shader if the gradient is not already reversed due to
                 * start angle being larger than end angle. */
                startAngleScaled = 360.f - startAngleScaled;
                endAngleScaled = 360.f - endAngleScaled;
                if (startAngleScaled > endAngleScaled) {
                    std::swap(startAngleScaled, endAngleScaled);
                    std::reverse(stops.begin(), stops.end());
                    std::reverse(colors.begin(), colors.end());
                    for (auto& stop : stops) {
                        stop = 1.0f - stop;
                    }
                }

                paint->setShader(SkGradientShader::MakeSweep(center.x(), center.y(),
                                                             colors.data(),
                                                             stops.data(), stops.size(),
                                                             tileMode,
                                                             startAngleScaled,
                                                             endAngleScaled,
                                                             0, nullptr));

            } else {
                // Old (Var)SweepGradient implementation, which is aiming to be compliant with
                // OpenType 1.9. but ambiguities and issues were found in the spec resolved in
                // 1.9.1. see above. TODO(drott): This else block is to be removed when the new
                // implementation has shipped in Chrome.

                // Prepare angles to be within range for the shader.
                auto clampAngleToRange = [](SkScalar angle) {
                    SkScalar clampedAngle = SkScalarMod(angle, 360.f);
                    if (clampedAngle < 0) {
                        return clampedAngle + 360.f;
                    }
                    return clampedAngle;
                };
                startAngle = clampAngleToRange(startAngle);
                endAngle = clampAngleToRange(endAngle);
                SkScalar sectorAngle = endAngle > startAngle ? endAngle - startAngle
                                                             : endAngle + 360.0f - startAngle;

                /* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#sweep-gradients
                 * "The angles are expressed in counter-clockwise degrees from the
                 * direction of the positive x-axis on the design grid. [...]  The
                 * color line progresses from the start angle to the end angle in
                 * the counter-clockwise direction;"
                 */

                SkMatrix localMatrix;
                localMatrix.postRotate(startAngle, center.x(), center.y());
                /* Mirror along x-axis to change angle direction. */
                localMatrix.postScale(1, -1, center.x(), center.y());
                SkTileMode tileMode = ToSkTileMode(sweepGradient.colorline.extend);

                paint->setShader(SkGradientShader::MakeSweep(center.x(), center.y(),
                                                             colors.data(),
                                                             stops.data(), stops.size(),
                                                             tileMode,
                                                             0,
                                                             sectorAngle,
                                                             0, &localMatrix));
            }
            return true;
        }
        default: {
            SkASSERT(false);
            return false;
        }
    }
    SkUNREACHABLE;
}

bool colrv1_draw_paint(SkCanvas* canvas,
                       const SkSpan<SkColor>& palette,
                       const SkColor foregroundColor,
                       FT_Face face,
                       const FT_COLR_Paint& colrPaint) {
    switch (colrPaint.format) {
        case FT_COLR_PAINTFORMAT_GLYPH: {
            FT_UInt glyphID = colrPaint.u.glyph.glyphID;
            SkPath path;
            /* TODO: Currently this call retrieves the path at units_per_em size. If we want to get
             * correct hinting for the scaled size under the transforms at this point in the color
             * glyph graph, we need to extract at least the requested glyph width and height and
             * pass that to the path generation. */
            if (!generateFacePathCOLRv1(face, glyphID, &path)) {
                return false;
            }
            if constexpr (kSkShowTextBlitCoverage) {
                SkPaint highlight_paint;
                highlight_paint.setColor(0x33FF0000);
                canvas->drawRect(path.getBounds(), highlight_paint);
            }
            canvas->clipPath(path, true /* doAntiAlias */);
            return true;
        }
        case FT_COLR_PAINTFORMAT_SOLID:
        case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT:
        case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT:
        case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: {
            SkPaint skPaint;
            if (!colrv1_configure_skpaint(face, palette, foregroundColor, colrPaint, &skPaint)) {
                return false;
            }
            canvas->drawPaint(skPaint);
            return true;
        }
        case FT_COLR_PAINTFORMAT_TRANSFORM:
        case FT_COLR_PAINTFORMAT_TRANSLATE:
        case FT_COLR_PAINTFORMAT_SCALE:
        case FT_COLR_PAINTFORMAT_ROTATE:
        case FT_COLR_PAINTFORMAT_SKEW:
            [[fallthrough]];  // Transforms handled in colrv1_transform.
        default:
            SkASSERT(false);
            return false;
    }
    SkUNREACHABLE;
}

bool colrv1_draw_glyph_with_path(SkCanvas* canvas,
                                 const SkSpan<SkColor>& palette, SkColor foregroundColor,
                                 FT_Face face,
                                 const FT_COLR_Paint& glyphPaint, const FT_COLR_Paint& fillPaint) {
    SkASSERT(glyphPaint.format == FT_COLR_PAINTFORMAT_GLYPH);
    SkASSERT(fillPaint.format == FT_COLR_PAINTFORMAT_SOLID ||
             fillPaint.format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ||
             fillPaint.format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ||
             fillPaint.format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT);

    SkPaint skiaFillPaint;
    skiaFillPaint.setAntiAlias(true);
    if (!colrv1_configure_skpaint(face, palette, foregroundColor, fillPaint, &skiaFillPaint)) {
        return false;
    }

    FT_UInt glyphID = glyphPaint.u.glyph.glyphID;
    SkPath path;
    /* TODO: Currently this call retrieves the path at units_per_em size. If we want to get
     * correct hinting for the scaled size under the transforms at this point in the color
     * glyph graph, we need to extract at least the requested glyph width and height and
     * pass that to the path generation. */
    if (!generateFacePathCOLRv1(face, glyphID, &path)) {
        return false;
    }
    if constexpr (kSkShowTextBlitCoverage) {
        SkPaint highlightPaint;
        highlightPaint.setColor(0x33FF0000);
        canvas->drawRect(path.getBounds(), highlightPaint);
    }
    canvas->drawPath(path, skiaFillPaint);
    return true;
}


/* In drawing mode, concatenates the transforms directly on SkCanvas. In
 * bounding box calculation mode, no SkCanvas is specified, but we only want to
 * retrieve the transform from the FreeType paint object. */
void colrv1_transform(FT_Face face,
                      const FT_COLR_Paint& colrPaint,
                      SkCanvas* canvas,
                      SkMatrix* outTransform = nullptr) {
    SkMatrix transform;

    SkASSERT(canvas || outTransform);

    switch (colrPaint.format) {
        case FT_COLR_PAINTFORMAT_TRANSFORM: {
            transform = ToSkMatrix(colrPaint.u.transform.affine);
            break;
        }
        case FT_COLR_PAINTFORMAT_TRANSLATE: {
            transform = SkMatrix::Translate( SkFixedToScalar(colrPaint.u.translate.dx),
                                            -SkFixedToScalar(colrPaint.u.translate.dy));
            break;
        }
        case FT_COLR_PAINTFORMAT_SCALE: {
            transform.setScale( SkFixedToScalar(colrPaint.u.scale.scale_x),
                                SkFixedToScalar(colrPaint.u.scale.scale_y),
                                SkFixedToScalar(colrPaint.u.scale.center_x),
                               -SkFixedToScalar(colrPaint.u.scale.center_y));
            break;
        }
        case FT_COLR_PAINTFORMAT_ROTATE: {
            // COLRv1 angles are counter-clockwise, compare
            // https://docs.microsoft.com/en-us/typography/opentype/spec/colr#formats-24-to-27-paintrotate-paintvarrotate-paintrotatearoundcenter-paintvarrotatearoundcenter
            transform = SkMatrix::RotateDeg(
                    -SkFixedToScalar(colrPaint.u.rotate.angle) * 180.0f,
                    SkPoint::Make( SkFixedToScalar(colrPaint.u.rotate.center_x),
                                  -SkFixedToScalar(colrPaint.u.rotate.center_y)));
            break;
        }
        case FT_COLR_PAINTFORMAT_SKEW: {
            // In the PAINTFORMAT_ROTATE implementation, SkMatrix setRotate
            // snaps to 0 for values very close to 0. Do the same here.

            SkScalar xDeg = SkFixedToScalar(colrPaint.u.skew.x_skew_angle) * 180.0f;
            SkScalar xRad = SkDegreesToRadians(xDeg);
            SkScalar xTan = SkScalarTan(xRad);
            xTan = SkScalarNearlyZero(xTan) ? 0.0f : xTan;

            SkScalar yDeg = SkFixedToScalar(colrPaint.u.skew.y_skew_angle) * 180.0f;
            // Negate y_skew_angle due to Skia's y-down coordinate system to achieve
            // counter-clockwise skew along the y-axis.
            SkScalar yRad = SkDegreesToRadians(-yDeg);
            SkScalar yTan = SkScalarTan(yRad);
            yTan = SkScalarNearlyZero(yTan) ? 0.0f : yTan;

            transform.setSkew(xTan, yTan,
                              SkFixedToScalar(colrPaint.u.skew.center_x),
                             -SkFixedToScalar(colrPaint.u.skew.center_y));
            break;
        }
        default: {
            SkASSERT(false);  // Only transforms are handled in this function.
        }
    }
    if (canvas) {
        canvas->concat(transform);
    }
    if (outTransform) {
        *outTransform = transform;
    }
}

bool colrv1_start_glyph(SkCanvas* canvas,
                        const SkSpan<SkColor>& palette,
                        const SkColor foregroundColor,
                        FT_Face face,
                        uint16_t glyphId,
                        FT_Color_Root_Transform rootTransform,
                        VisitedSet* activePaints);

bool colrv1_traverse_paint(SkCanvas* canvas,
                           const SkSpan<SkColor>& palette,
                           const SkColor foregroundColor,
                           FT_Face face,
                           FT_OpaquePaint opaquePaint,
                           VisitedSet* activePaints) {
    // Cycle detection, see section "5.7.11.1.9 Color glyphs as a directed acyclic graph".
    if (activePaints->contains(opaquePaint)) {
        return false;
    }

    activePaints->add(opaquePaint);
    SK_AT_SCOPE_EXIT(activePaints->remove(opaquePaint));

    FT_COLR_Paint paint;
    if (!FT_Get_Paint(face, opaquePaint, &paint)) {
        return false;
    }

    SkAutoCanvasRestore autoRestore(canvas, true /* doSave */);
    switch (paint.format) {
        case FT_COLR_PAINTFORMAT_COLR_LAYERS: {
            FT_LayerIterator& layerIterator = paint.u.colr_layers.layer_iterator;
            FT_OpaquePaint layerPaint{nullptr, 1};
            while (FT_Get_Paint_Layers(face, &layerIterator, &layerPaint)) {
                if (!colrv1_traverse_paint(canvas, palette, foregroundColor, face,
                                           layerPaint, activePaints)) {
                    return false;
                }
            }
            return true;
        }
        case FT_COLR_PAINTFORMAT_GLYPH:
            // Special case paint graph leaf situations to improve
            // performance. These are situations in the graph where a GlyphPaint
            // is followed by either a solid or a gradient fill. Here we can use
            // drawPath() + SkPaint directly which is faster than setting a
            // clipPath() followed by a drawPaint().
            FT_COLR_Paint fillPaint;
            if (!FT_Get_Paint(face, paint.u.glyph.paint, &fillPaint)) {
                return false;
            }
            if (fillPaint.format == FT_COLR_PAINTFORMAT_SOLID ||
                fillPaint.format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT ||
                fillPaint.format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT ||
                fillPaint.format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT)
            {
                return colrv1_draw_glyph_with_path(canvas, palette, foregroundColor,
                                                   face, paint, fillPaint);
            }
            if (!colrv1_draw_paint(canvas, palette, foregroundColor, face, paint)) {
                return false;
            }
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.glyph.paint, activePaints);
        case FT_COLR_PAINTFORMAT_COLR_GLYPH:
            return colrv1_start_glyph(canvas, palette, foregroundColor,
                                      face, paint.u.colr_glyph.glyphID, FT_COLOR_NO_ROOT_TRANSFORM,
                                      activePaints);
        case FT_COLR_PAINTFORMAT_TRANSFORM:
            colrv1_transform(face, paint, canvas);
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.transform.paint, activePaints);
        case FT_COLR_PAINTFORMAT_TRANSLATE:
            colrv1_transform(face, paint, canvas);
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.translate.paint, activePaints);
        case FT_COLR_PAINTFORMAT_SCALE:
            colrv1_transform(face, paint, canvas);
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.scale.paint, activePaints);
        case FT_COLR_PAINTFORMAT_ROTATE:
            colrv1_transform(face, paint, canvas);
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.rotate.paint, activePaints);
        case FT_COLR_PAINTFORMAT_SKEW:
            colrv1_transform(face, paint, canvas);
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.skew.paint, activePaints);
        case FT_COLR_PAINTFORMAT_COMPOSITE: {
            SkAutoCanvasRestore acr(canvas, false);
            canvas->saveLayer(nullptr, nullptr);
            if (!colrv1_traverse_paint(canvas, palette, foregroundColor,
                                       face, paint.u.composite.backdrop_paint, activePaints)) {
                return false;
            }
            SkPaint blendModePaint;
            blendModePaint.setBlendMode(ToSkBlendMode(paint.u.composite.composite_mode));
            canvas->saveLayer(nullptr, &blendModePaint);
            return colrv1_traverse_paint(canvas, palette, foregroundColor,
                                         face, paint.u.composite.source_paint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_SOLID:
        case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT:
        case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT:
        case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: {
            return colrv1_draw_paint(canvas, palette, foregroundColor, face, paint);
        }
        default:
            SkASSERT(false);
            return false;
    }
    SkUNREACHABLE;
}

SkPath GetClipBoxPath(FT_Face face, uint16_t glyphId, bool untransformed) {
    SkPath resultPath;

    using DoneFTSize = SkFunctionWrapper<decltype(FT_Done_Size), FT_Done_Size>;
    std::unique_ptr<std::remove_pointer_t<FT_Size>, DoneFTSize> unscaledFtSize = nullptr;

    FT_Size oldSize = face->size;
    FT_Matrix oldTransform;
    FT_Vector oldDelta;
    FT_Error err = 0;

    if (untransformed) {
        unscaledFtSize.reset(
                [face]() -> FT_Size {
                    FT_Size size;
                    FT_Error err = FT_New_Size(face, &size);
                    if (err != 0) {
                        SK_TRACEFTR(err,
                                    "FT_New_Size(%s) failed in generateFacePathStaticCOLRv1.",
                                    face->family_name);
                        return nullptr;
                    }
                    return size;
                }());
        if (!unscaledFtSize) {
            return resultPath;
        }

        err = FT_Activate_Size(unscaledFtSize.get());
        if (err != 0) {
            return resultPath;
        }

        err = FT_Set_Char_Size(face, SkIntToFDot6(face->units_per_EM), 0, 0, 0);
        if (err != 0) {
            return resultPath;
        }

        FT_Get_Transform(face, &oldTransform, &oldDelta);
        FT_Set_Transform(face, nullptr, nullptr);
    }

    FT_ClipBox colrGlyphClipBox;
    if (FT_Get_Color_Glyph_ClipBox(face, glyphId, &colrGlyphClipBox)) {
        resultPath = SkPath::Polygon({{ SkFDot6ToScalar(colrGlyphClipBox.bottom_left.x),
                                       -SkFDot6ToScalar(colrGlyphClipBox.bottom_left.y)},
                                      { SkFDot6ToScalar(colrGlyphClipBox.top_left.x),
                                       -SkFDot6ToScalar(colrGlyphClipBox.top_left.y)},
                                      { SkFDot6ToScalar(colrGlyphClipBox.top_right.x),
                                       -SkFDot6ToScalar(colrGlyphClipBox.top_right.y)},
                                      { SkFDot6ToScalar(colrGlyphClipBox.bottom_right.x),
                                       -SkFDot6ToScalar(colrGlyphClipBox.bottom_right.y)}},
                                     true);
    }

    if (untransformed) {
        err = FT_Activate_Size(oldSize);
        if (err != 0) {
          return resultPath;
        }
        FT_Set_Transform(face, &oldTransform, &oldDelta);
    }

    return resultPath;
}

bool colrv1_start_glyph(SkCanvas* canvas,
                        const SkSpan<SkColor>& palette,
                        const SkColor foregroundColor,
                        FT_Face face,
                        uint16_t glyphId,
                        FT_Color_Root_Transform rootTransform,
                        VisitedSet* activePaints) {
    FT_OpaquePaint opaquePaint{nullptr, 1};
    if (!FT_Get_Color_Glyph_Paint(face, glyphId, rootTransform, &opaquePaint)) {
        return false;
    }

    bool untransformed = rootTransform == FT_COLOR_NO_ROOT_TRANSFORM;
    SkPath clipBoxPath = GetClipBoxPath(face, glyphId, untransformed);
    if (!clipBoxPath.isEmpty()) {
        canvas->clipPath(clipBoxPath, true);
    }

    if (!colrv1_traverse_paint(canvas, palette, foregroundColor,
                               face, opaquePaint, activePaints)) {
        return false;
    }

    return true;
}

bool colrv1_start_glyph_bounds(SkMatrix *ctm,
                               SkRect* bounds,
                               FT_Face face,
                               uint16_t glyphId,
                               FT_Color_Root_Transform rootTransform,
                               VisitedSet* activePaints);

bool colrv1_traverse_paint_bounds(SkMatrix* ctm,
                                  SkRect* bounds,
                                  FT_Face face,
                                  FT_OpaquePaint opaquePaint,
                                  VisitedSet* activePaints) {
    // Cycle detection, see section "5.7.11.1.9 Color glyphs as a directed acyclic graph".
    if (activePaints->contains(opaquePaint)) {
        return false;
    }

    activePaints->add(opaquePaint);
    SK_AT_SCOPE_EXIT(activePaints->remove(opaquePaint));

    FT_COLR_Paint paint;
    if (!FT_Get_Paint(face, opaquePaint, &paint)) {
        return false;
    }

    SkMatrix restoreMatrix = *ctm;
    SK_AT_SCOPE_EXIT(*ctm = restoreMatrix);

    switch (paint.format) {
        case FT_COLR_PAINTFORMAT_COLR_LAYERS: {
            FT_LayerIterator& layerIterator = paint.u.colr_layers.layer_iterator;
            FT_OpaquePaint layerPaint{nullptr, 1};
            while (FT_Get_Paint_Layers(face, &layerIterator, &layerPaint)) {
                if (!colrv1_traverse_paint_bounds(ctm, bounds, face, layerPaint, activePaints)) {
                    return false;
                }
            }
            return true;
        }
        case FT_COLR_PAINTFORMAT_GLYPH: {
            FT_UInt glyphID = paint.u.glyph.glyphID;
            SkPath path;
            if (!generateFacePathCOLRv1(face, glyphID, &path)) {
                return false;
            }
            path.transform(*ctm);
            bounds->join(path.getBounds());
            return true;
        }
        case FT_COLR_PAINTFORMAT_COLR_GLYPH: {
            FT_UInt glyphID = paint.u.colr_glyph.glyphID;
            return colrv1_start_glyph_bounds(ctm, bounds, face, glyphID, FT_COLOR_NO_ROOT_TRANSFORM,
                                             activePaints);
        }
        case FT_COLR_PAINTFORMAT_TRANSFORM: {
            SkMatrix transformMatrix;
            colrv1_transform(face, paint, nullptr, &transformMatrix);
            ctm->preConcat(transformMatrix);
            FT_OpaquePaint& transformPaint = paint.u.transform.paint;
            return colrv1_traverse_paint_bounds(ctm, bounds, face, transformPaint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_TRANSLATE: {
            SkMatrix transformMatrix;
            colrv1_transform(face, paint, nullptr, &transformMatrix);
            ctm->preConcat(transformMatrix);
            FT_OpaquePaint& translatePaint = paint.u.translate.paint;
            return colrv1_traverse_paint_bounds(ctm, bounds, face, translatePaint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_SCALE: {
            SkMatrix transformMatrix;
            colrv1_transform(face, paint, nullptr, &transformMatrix);
            ctm->preConcat(transformMatrix);
            FT_OpaquePaint& scalePaint = paint.u.scale.paint;
            return colrv1_traverse_paint_bounds(ctm, bounds, face, scalePaint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_ROTATE: {
            SkMatrix transformMatrix;
            colrv1_transform(face, paint, nullptr, &transformMatrix);
            ctm->preConcat(transformMatrix);
            FT_OpaquePaint& rotatePaint = paint.u.rotate.paint;
            return colrv1_traverse_paint_bounds(ctm, bounds, face, rotatePaint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_SKEW: {
            SkMatrix transformMatrix;
            colrv1_transform(face, paint, nullptr, &transformMatrix);
            ctm->preConcat(transformMatrix);
            FT_OpaquePaint& skewPaint = paint.u.skew.paint;
            return colrv1_traverse_paint_bounds(ctm, bounds, face, skewPaint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_COMPOSITE: {
            FT_OpaquePaint& backdropPaint = paint.u.composite.backdrop_paint;
            FT_OpaquePaint&   sourcePaint = paint.u.composite.  source_paint;
            return colrv1_traverse_paint_bounds(ctm, bounds, face, backdropPaint, activePaints) &&
                   colrv1_traverse_paint_bounds(ctm, bounds, face,   sourcePaint, activePaints);
        }
        case FT_COLR_PAINTFORMAT_SOLID:
        case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT:
        case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT:
        case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT: {
            return true;
        }
        default:
            SkASSERT(false);
            return false;
    }
    SkUNREACHABLE;
}


bool colrv1_start_glyph_bounds(SkMatrix *ctm,
                               SkRect* bounds,
                               FT_Face face,
                               uint16_t glyphId,
                               FT_Color_Root_Transform rootTransform,
                               VisitedSet* activePaints) {
    FT_OpaquePaint opaquePaint{nullptr, 1};
    return FT_Get_Color_Glyph_Paint(face, glyphId, rootTransform, &opaquePaint) &&
           colrv1_traverse_paint_bounds(ctm, bounds, face, opaquePaint, activePaints);
}
#endif // TT_SUPPORT_COLRV1

}  // namespace


#ifdef TT_SUPPORT_COLRV1
bool SkScalerContext_FreeType_Base::drawCOLRv1Glyph(FT_Face face,
                                                    const SkGlyph& glyph,
                                                    uint32_t loadGlyphFlags,
                                                    SkSpan<SkColor> palette,
                                                    SkCanvas* canvas) {
    if (this->isSubpixel()) {
        canvas->translate(SkFixedToScalar(glyph.getSubXFixed()),
                          SkFixedToScalar(glyph.getSubYFixed()));
    }

    VisitedSet activePaints;
    bool haveLayers =  colrv1_start_glyph(canvas, palette,
                                          fRec.fForegroundColor,
                                          face, glyph.getGlyphID(),
                                          FT_COLOR_INCLUDE_ROOT_TRANSFORM,
                                          &activePaints);
    SkASSERTF(haveLayers, "Could not get COLRv1 layers from '%s'.", face->family_name);
    return haveLayers;
}
#endif  // TT_SUPPORT_COLRV1

#ifdef FT_COLOR_H
bool SkScalerContext_FreeType_Base::drawCOLRv0Glyph(FT_Face face,
                                                    const SkGlyph& glyph,
                                                    uint32_t loadGlyphFlags,
                                                    SkSpan<SkColor> palette,
                                                    SkCanvas* canvas) {
    if (this->isSubpixel()) {
        canvas->translate(SkFixedToScalar(glyph.getSubXFixed()),
                          SkFixedToScalar(glyph.getSubYFixed()));
    }

    bool haveLayers = false;
    FT_LayerIterator layerIterator;
    layerIterator.p = nullptr;
    FT_UInt layerGlyphIndex = 0;
    FT_UInt layerColorIndex = 0;
    SkPaint paint;
    paint.setAntiAlias(!(loadGlyphFlags & FT_LOAD_TARGET_MONO));
    while (FT_Get_Color_Glyph_Layer(face, glyph.getGlyphID(), &layerGlyphIndex,
                                    &layerColorIndex, &layerIterator)) {
        haveLayers = true;
        if (layerColorIndex == 0xFFFF) {
            paint.setColor(fRec.fForegroundColor);
        } else {
            paint.setColor(palette[layerColorIndex]);
        }
        SkPath path;
        if (this->generateFacePath(face, layerGlyphIndex, loadGlyphFlags, &path)) {
            canvas->drawPath(path, paint);
        }
    }
    SkASSERTF(haveLayers, "Could not get COLRv0 layers from '%s'.", face->family_name);
    return haveLayers;
}
#endif  // FT_COLOR_H

#if defined(FT_CONFIG_OPTION_SVG)
bool SkScalerContext_FreeType_Base::drawSVGGlyph(FT_Face face,
                                                 const SkGlyph& glyph,
                                                 uint32_t loadGlyphFlags,
                                                 SkSpan<SkColor> palette,
                                                 SkCanvas* canvas) {
    SkASSERT(face->glyph->format == FT_GLYPH_FORMAT_SVG);

    FT_SVG_Document ftSvg = (FT_SVG_Document)face->glyph->other;
    SkMatrix m;
    FT_Matrix ftMatrix = ftSvg->transform;
    FT_Vector ftOffset = ftSvg->delta;
    m.setAll(
        SkFixedToFloat(ftMatrix.xx), -SkFixedToFloat(ftMatrix.xy),  SkFixedToFloat(ftOffset.x),
       -SkFixedToFloat(ftMatrix.yx),  SkFixedToFloat(ftMatrix.yy), -SkFixedToFloat(ftOffset.y),
        0                          ,  0                          ,  1                        );
    m.postScale(SkFixedToFloat(ftSvg->metrics.x_scale) / 64.0f,
                SkFixedToFloat(ftSvg->metrics.y_scale) / 64.0f);
    if (this->isSubpixel()) {
        m.postTranslate(SkFixedToScalar(glyph.getSubXFixed()),
                        SkFixedToScalar(glyph.getSubYFixed()));
    }
    canvas->concat(m);

    SkGraphics::OpenTypeSVGDecoderFactory svgFactory = SkGraphics::GetOpenTypeSVGDecoderFactory();
    if (!svgFactory) {
        return false;
    }
    auto svgDecoder = svgFactory(ftSvg->svg_document, ftSvg->svg_document_length);
    if (!svgDecoder) {
        return false;
    }
    return svgDecoder->render(*canvas, ftSvg->units_per_EM, glyph.getGlyphID(),
                              fRec.fForegroundColor, palette);
}
#endif  // FT_CONFIG_OPTION_SVG

void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face,
                                                       const SkGlyph& glyph,
                                                       const SkMatrix& bitmapTransform)
{
    switch ( face->glyph->format ) {
        case FT_GLYPH_FORMAT_OUTLINE: {
            FT_Outline* outline = &face->glyph->outline;

            int dx = 0, dy = 0;
            if (this->isSubpixel()) {
                dx = SkFixedToFDot6(glyph.getSubXFixed());
                dy = SkFixedToFDot6(glyph.getSubYFixed());
                // negate dy since freetype-y-goes-up and skia-y-goes-down
                dy = -dy;
            }

            memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);

            if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
                const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag);
                const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);

                FT_Outline_Translate(outline, dx, dy);
                FT_Error err = FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V :
                                                                     FT_RENDER_MODE_LCD);
                if (err) {
                    SK_TRACEFTR(err, "Could not render glyph %p.", face->glyph);
                    return;
                }

                SkMask mask = glyph.mask();
                if constexpr (kSkShowTextBlitCoverage) {
                    memset(mask.fImage, 0x80, mask.fBounds.height() * mask.fRowBytes);
                }
                FT_GlyphSlotRec& ftGlyph = *face->glyph;

                if (!SkIRect::Intersects(mask.fBounds,
                                         SkIRect::MakeXYWH( ftGlyph.bitmap_left,
                                                           -ftGlyph.bitmap_top,
                                                            ftGlyph.bitmap.width,
                                                            ftGlyph.bitmap.rows)))
                {
                    return;
                }

                // If the FT_Bitmap extent is larger, discard bits of the bitmap outside the mask.
                // If the SkMask extent is larger, shrink mask to fit bitmap (clearing discarded).
                unsigned char* origBuffer = ftGlyph.bitmap.buffer;
                // First align the top left (origin).
                if (-ftGlyph.bitmap_top < mask.fBounds.fTop) {
                    int32_t topDiff = mask.fBounds.fTop - (-ftGlyph.bitmap_top);
                    ftGlyph.bitmap.buffer += ftGlyph.bitmap.pitch * topDiff;
                    ftGlyph.bitmap.rows -= topDiff;
                    ftGlyph.bitmap_top = -mask.fBounds.fTop;
                }
                if (ftGlyph.bitmap_left < mask.fBounds.fLeft) {
                    int32_t leftDiff = mask.fBounds.fLeft - ftGlyph.bitmap_left;
                    ftGlyph.bitmap.buffer += leftDiff;
                    ftGlyph.bitmap.width -= leftDiff;
                    ftGlyph.bitmap_left = mask.fBounds.fLeft;
                }
                if (mask.fBounds.fTop < -ftGlyph.bitmap_top) {
                    mask.fImage += mask.fRowBytes * (-ftGlyph.bitmap_top - mask.fBounds.fTop);
                    mask.fBounds.fTop = -ftGlyph.bitmap_top;
                }
                if (mask.fBounds.fLeft < ftGlyph.bitmap_left) {
                    mask.fImage += sizeof(uint16_t) * (ftGlyph.bitmap_left - mask.fBounds.fLeft);
                    mask.fBounds.fLeft = ftGlyph.bitmap_left;
                }
                // Origins aligned, clean up the width and height.
                int ftVertScale = (doVert ? 3 : 1);
                int ftHoriScale = (doVert ? 1 : 3);
                if (mask.fBounds.height() * ftVertScale < SkToInt(ftGlyph.bitmap.rows)) {
                    ftGlyph.bitmap.rows = mask.fBounds.height() * ftVertScale;
                }
                if (mask.fBounds.width() * ftHoriScale < SkToInt(ftGlyph.bitmap.width)) {
                    ftGlyph.bitmap.width = mask.fBounds.width() * ftHoriScale;
                }
                if (SkToInt(ftGlyph.bitmap.rows) < mask.fBounds.height() * ftVertScale) {
                    mask.fBounds.fBottom = mask.fBounds.fTop + ftGlyph.bitmap.rows / ftVertScale;
                }
                if (SkToInt(ftGlyph.bitmap.width) < mask.fBounds.width() * ftHoriScale) {
                    mask.fBounds.fRight = mask.fBounds.fLeft + ftGlyph.bitmap.width / ftHoriScale;
                }
                if (fPreBlend.isApplicable()) {
                    copyFT2LCD16<true>(ftGlyph.bitmap, mask, doBGR,
                                       fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
                } else {
                    copyFT2LCD16<false>(ftGlyph.bitmap, mask, doBGR,
                                        fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
                }
                // Restore the buffer pointer so FreeType can properly free it.
                ftGlyph.bitmap.buffer = origBuffer;
            } else {
                FT_BBox     bbox;
                FT_Bitmap   target;
                FT_Outline_Get_CBox(outline, &bbox);
                /*
                    what we really want to do for subpixel is
                        offset(dx, dy)
                        compute_bounds
                        offset(bbox & !63)
                    but that is two calls to offset, so we do the following, which
                    achieves the same thing with only one offset call.
                */
                FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
                                              dy - ((bbox.yMin + dy) & ~63));

                target.width = glyph.fWidth;
                target.rows = glyph.fHeight;
                target.pitch = glyph.rowBytes();
                target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
                target.pixel_mode = compute_pixel_mode(glyph.fMaskFormat);
                target.num_grays = 256;

                FT_Outline_Get_Bitmap(face->glyph->library, outline, &target);
                if constexpr (kSkShowTextBlitCoverage) {
                    if (glyph.fMaskFormat == SkMask::kBW_Format) {
                        for (unsigned y = 0; y < target.rows; y += 2) {
                            for (unsigned x = (y & 0x2); x < target.width; x+=4) {
                                uint8_t& b = target.buffer[(target.pitch * y) + (x >> 3)];
                                b = b ^ (1 << (0x7 - (x & 0x7)));
                            }
                        }
                    } else {
                        for (unsigned y = 0; y < target.rows; ++y) {
                            for (unsigned x = 0; x < target.width; ++x) {
                                uint8_t& a = target.buffer[(target.pitch * y) + x];
                                a = std::max<uint8_t>(a, 0x20);
                            }
                        }
                    }
                }
            }
        } break;

        case FT_GLYPH_FORMAT_BITMAP: {
            FT_Pixel_Mode pixel_mode = static_cast<FT_Pixel_Mode>(face->glyph->bitmap.pixel_mode);
            SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);

            // Assume that the other formats do not exist.
            SkASSERT(FT_PIXEL_MODE_MONO == pixel_mode ||
                     FT_PIXEL_MODE_GRAY == pixel_mode ||
                     FT_PIXEL_MODE_BGRA == pixel_mode);

            // These are the only formats this ScalerContext should request.
            SkASSERT(SkMask::kBW_Format == maskFormat ||
                     SkMask::kA8_Format == maskFormat ||
                     SkMask::kARGB32_Format == maskFormat ||
                     SkMask::kLCD16_Format == maskFormat);

            // If no scaling needed, directly copy glyph bitmap.
            if (bitmapTransform.isIdentity()) {
                SkMask dstMask = glyph.mask();
                copyFTBitmap(face->glyph->bitmap, dstMask);
                break;
            }

            // Otherwise, scale the bitmap.

            // Copy the FT_Bitmap into an SkBitmap (either A8 or ARGB)
            SkBitmap unscaledBitmap;
            // TODO: mark this as sRGB when the blits will be sRGB.
            unscaledBitmap.allocPixels(SkImageInfo::Make(face->glyph->bitmap.width,
                                                         face->glyph->bitmap.rows,
                                                         SkColorType_for_FTPixelMode(pixel_mode),
                                                         kPremul_SkAlphaType));

            SkMask unscaledBitmapAlias;
            unscaledBitmapAlias.fImage = reinterpret_cast<uint8_t*>(unscaledBitmap.getPixels());
            unscaledBitmapAlias.fBounds.setWH(unscaledBitmap.width(), unscaledBitmap.height());
            unscaledBitmapAlias.fRowBytes = unscaledBitmap.rowBytes();
            unscaledBitmapAlias.fFormat = SkMaskFormat_for_SkColorType(unscaledBitmap.colorType());
            copyFTBitmap(face->glyph->bitmap, unscaledBitmapAlias);

            // Wrap the glyph's mask in a bitmap, unless the glyph's mask is BW or LCD.
            // BW requires an A8 target for resizing, which can then be down sampled.
            // LCD should use a 4x A8 target, which will then be down sampled.
            // For simplicity, LCD uses A8 and is replicated.
            int bitmapRowBytes = 0;
            if (SkMask::kBW_Format != maskFormat && SkMask::kLCD16_Format != maskFormat) {
                bitmapRowBytes = glyph.rowBytes();
            }
            SkBitmap dstBitmap;
            // TODO: mark this as sRGB when the blits will be sRGB.
            dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight,
                                                SkColorType_for_SkMaskFormat(maskFormat),
                                                kPremul_SkAlphaType),
                              bitmapRowBytes);
            if (SkMask::kBW_Format == maskFormat || SkMask::kLCD16_Format == maskFormat) {
                dstBitmap.allocPixels();
            } else {
                dstBitmap.setPixels(glyph.fImage);
            }

            // Scale unscaledBitmap into dstBitmap.
            SkCanvas canvas(dstBitmap);
            if constexpr (kSkShowTextBlitCoverage) {
                canvas.clear(0x33FF0000);
            } else {
                canvas.clear(SK_ColorTRANSPARENT);
            }
            canvas.translate(-glyph.fLeft, -glyph.fTop);
            canvas.concat(bitmapTransform);
            canvas.translate(face->glyph->bitmap_left, -face->glyph->bitmap_top);

            SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kNearest);
            canvas.drawImage(unscaledBitmap.asImage().get(), 0, 0, sampling, nullptr);

            // If the destination is BW or LCD, convert from A8.
            if (SkMask::kBW_Format == maskFormat) {
                // Copy the A8 dstBitmap into the A1 glyph.fImage.
                SkMask dstMask = glyph.mask();
                packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes());
            } else if (SkMask::kLCD16_Format == maskFormat) {
                // Copy the A8 dstBitmap into the LCD16 glyph.fImage.
                uint8_t* src = dstBitmap.getAddr8(0, 0);
                uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage);
                for (int y = dstBitmap.height(); y --> 0;) {
                    for (int x = 0; x < dstBitmap.width(); ++x) {
                        dst[x] = grayToRGB16(src[x]);
                    }
                    dst = (uint16_t*)((char*)dst + glyph.rowBytes());
                    src += dstBitmap.rowBytes();
                }
            }
        } break;

        default:
            SkDEBUGFAIL("unknown glyph format");
            memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
            return;
    }

// We used to always do this pre-USE_COLOR_LUMINANCE, but with colorlum,
// it is optional
#if defined(SK_GAMMA_APPLY_TO_A8)
    if (SkMask::kA8_Format == glyph.fMaskFormat && fPreBlend.isApplicable()) {
        uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
        unsigned rowBytes = glyph.rowBytes();

        for (int y = glyph.fHeight - 1; y >= 0; --y) {
            for (int x = glyph.fWidth - 1; x >= 0; --x) {
                dst[x] = fPreBlend.fG[dst[x]];
            }
            dst += rowBytes;
        }
    }
#endif
}

///////////////////////////////////////////////////////////////////////////////

namespace {

class SkFTGeometrySink {
    SkPath* fPath;
    bool fStarted;
    FT_Vector fCurrent;

    void goingTo(const FT_Vector* pt) {
        if (!fStarted) {
            fStarted = true;
            fPath->moveTo(SkFDot6ToScalar(fCurrent.x), -SkFDot6ToScalar(fCurrent.y));
        }
        fCurrent = *pt;
    }

    bool currentIsNot(const FT_Vector* pt) {
        return fCurrent.x != pt->x || fCurrent.y != pt->y;
    }

    static int Move(const FT_Vector* pt, void* ctx) {
        SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
        if (self.fStarted) {
            self.fPath->close();
            self.fStarted = false;
        }
        self.fCurrent = *pt;
        return 0;
    }

    static int Line(const FT_Vector* pt, void* ctx) {
        SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
        if (self.currentIsNot(pt)) {
            self.goingTo(pt);
            self.fPath->lineTo(SkFDot6ToScalar(pt->x), -SkFDot6ToScalar(pt->y));
        }
        return 0;
    }

    static int Quad(const FT_Vector* pt0, const FT_Vector* pt1, void* ctx) {
        SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
        if (self.currentIsNot(pt0) || self.currentIsNot(pt1)) {
            self.goingTo(pt1);
            self.fPath->quadTo(SkFDot6ToScalar(pt0->x), -SkFDot6ToScalar(pt0->y),
                               SkFDot6ToScalar(pt1->x), -SkFDot6ToScalar(pt1->y));
        }
        return 0;
    }

    static int Cubic(const FT_Vector* pt0, const FT_Vector* pt1, const FT_Vector* pt2, void* ctx) {
        SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
        if (self.currentIsNot(pt0) || self.currentIsNot(pt1) || self.currentIsNot(pt2)) {
            self.goingTo(pt2);
            self.fPath->cubicTo(SkFDot6ToScalar(pt0->x), -SkFDot6ToScalar(pt0->y),
                                SkFDot6ToScalar(pt1->x), -SkFDot6ToScalar(pt1->y),
                                SkFDot6ToScalar(pt2->x), -SkFDot6ToScalar(pt2->y));
        }
        return 0;
    }

public:
    SkFTGeometrySink(SkPath* path) : fPath{path}, fStarted{false}, fCurrent{0,0} {}

    inline static constexpr const FT_Outline_Funcs Funcs{
        /*move_to =*/ SkFTGeometrySink::Move,
        /*line_to =*/ SkFTGeometrySink::Line,
        /*conic_to =*/ SkFTGeometrySink::Quad,
        /*cubic_to =*/ SkFTGeometrySink::Cubic,
        /*shift = */ 0,
        /*delta =*/ 0,
    };
};

bool generateGlyphPathStatic(FT_Face face, SkPath* path) {
    SkFTGeometrySink sink{path};
    if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE ||
        FT_Outline_Decompose(&face->glyph->outline, &SkFTGeometrySink::Funcs, &sink))
    {
        path->reset();
        return false;
    }
    path->close();
    return true;
}

bool generateFacePathStatic(FT_Face face, SkGlyphID glyphID, uint32_t loadGlyphFlags, SkPath* path){
    loadGlyphFlags |= FT_LOAD_BITMAP_METRICS_ONLY;  // Don't decode any bitmaps.
    loadGlyphFlags |= FT_LOAD_NO_BITMAP; // Ignore embedded bitmaps.
    loadGlyphFlags &= ~FT_LOAD_RENDER;  // Don't scan convert.
    loadGlyphFlags &= ~FT_LOAD_COLOR;  // Ignore SVG.
    if (FT_Load_Glyph(face, glyphID, loadGlyphFlags)) {
        path->reset();
        return false;
    }
    return generateGlyphPathStatic(face, path);
}

#ifdef TT_SUPPORT_COLRV1
bool generateFacePathCOLRv1(FT_Face face, SkGlyphID glyphID, SkPath* path) {
    uint32_t flags = 0;
    flags |= FT_LOAD_BITMAP_METRICS_ONLY;  // Don't decode any bitmaps.
    flags |= FT_LOAD_NO_BITMAP; // Ignore embedded bitmaps.
    flags &= ~FT_LOAD_RENDER;  // Don't scan convert.
    flags &= ~FT_LOAD_COLOR;  // Ignore SVG.
    flags |= FT_LOAD_NO_HINTING;
    flags |= FT_LOAD_NO_AUTOHINT;
    flags |= FT_LOAD_IGNORE_TRANSFORM;

    using DoneFTSize = SkFunctionWrapper<decltype(FT_Done_Size), FT_Done_Size>;
    std::unique_ptr<std::remove_pointer_t<FT_Size>, DoneFTSize> unscaledFtSize([face]() -> FT_Size {
        FT_Size size;
        FT_Error err = FT_New_Size(face, &size);
        if (err != 0) {
            SK_TRACEFTR(err, "FT_New_Size(%s) failed in generateFacePathStaticCOLRv1.",
                        face->family_name);
            return nullptr;
        }
        return size;
    }());

    if (!unscaledFtSize) {
      return false;
    }

    FT_Size oldSize = face->size;

    auto tryGeneratePath = [face, &unscaledFtSize, glyphID, flags, path]() {
        FT_Error err = 0;

        err = FT_Activate_Size(unscaledFtSize.get());
        if (err != 0) {
          return false;
        }

        err = FT_Set_Char_Size(face, SkIntToFDot6(face->units_per_EM),
                                     SkIntToFDot6(face->units_per_EM), 72, 72);
        if (err != 0) {
            return false;
        }

        err = FT_Load_Glyph(face, glyphID, flags);
        if (err != 0) {
            path->reset();
            return false;
        }

        if (!generateGlyphPathStatic(face, path)) {
            path->reset();
            return false;
        }

        return true;
    };

    bool pathGenerationResult = tryGeneratePath();

    FT_Activate_Size(oldSize);

    return pathGenerationResult;
}
#endif

}  // namespace

bool SkScalerContext_FreeType_Base::generateGlyphPath(FT_Face face, SkPath* path) {
    if (!generateGlyphPathStatic(face, path)) {
        return false;
    }
    if (face->glyph->outline.flags & FT_OUTLINE_OVERLAP) {
        Simplify(*path, path);
    }
    return true;
}

bool SkScalerContext_FreeType_Base::generateFacePath(FT_Face face,
                                                     SkGlyphID glyphID,
                                                     uint32_t loadGlyphFlags,
                                                     SkPath* path) {
    return generateFacePathStatic(face, glyphID, loadGlyphFlags, path);
}

#ifdef TT_SUPPORT_COLRV1
bool SkScalerContext_FreeType_Base::computeColrV1GlyphBoundingBox(FT_Face face,
                                                                  SkGlyphID glyphID,
                                                                  SkRect* bounds) {
    SkMatrix ctm;
    *bounds = SkRect::MakeEmpty();
    VisitedSet activePaints;
    return colrv1_start_glyph_bounds(&ctm, bounds, face, glyphID,
                                     FT_COLOR_INCLUDE_ROOT_TRANSFORM, &activePaints);
}
#endif
