/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "GrAtlasTextContext.h"
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrSDFMaskFilter.h"
#include "GrTextBlobCache.h"
#include "SkDistanceFieldGen.h"
#include "SkDraw.h"
#include "SkDrawFilter.h"
#include "SkDrawProcs.h"
#include "SkFindAndPlaceGlyph.h"
#include "SkGr.h"
#include "SkGraphics.h"
#include "SkMakeUnique.h"
#include "SkMaskFilterBase.h"
#include "SkPaintPriv.h"
#include "SkTextMapStateProc.h"

#include "ops/GrMeshDrawOp.h"

// DF sizes and thresholds for usage of the small and medium sizes. For example, above
// kSmallDFFontLimit we will use the medium size. The large size is used up until the size at
// which we switch over to drawing as paths as controlled by Options.
static const int kSmallDFFontSize = 32;
static const int kSmallDFFontLimit = 32;
static const int kMediumDFFontSize = 72;
static const int kMediumDFFontLimit = 72;
static const int kLargeDFFontSize = 162;

static const int kDefaultMinDistanceFieldFontSize = 18;
#ifdef SK_BUILD_FOR_ANDROID
static const int kDefaultMaxDistanceFieldFontSize = 384;
#else
static const int kDefaultMaxDistanceFieldFontSize = 2 * kLargeDFFontSize;
#endif

GrAtlasTextContext::GrAtlasTextContext(const Options& options)
        : fDistanceAdjustTable(new GrDistanceFieldAdjustTable) {
    fMaxDistanceFieldFontSize = options.fMaxDistanceFieldFontSize < 0.f
                                        ? kDefaultMaxDistanceFieldFontSize
                                        : options.fMaxDistanceFieldFontSize;
    fMinDistanceFieldFontSize = options.fMinDistanceFieldFontSize < 0.f
                                        ? kDefaultMinDistanceFieldFontSize
                                        : options.fMinDistanceFieldFontSize;
    fDistanceFieldVerticesAlwaysHaveW = options.fDistanceFieldVerticesAlwaysHaveW;
}

std::unique_ptr<GrAtlasTextContext> GrAtlasTextContext::Make(const Options& options) {
    return std::unique_ptr<GrAtlasTextContext>(new GrAtlasTextContext(options));
}

SkColor GrAtlasTextContext::ComputeCanonicalColor(const SkPaint& paint, bool lcd) {
    SkColor canonicalColor = paint.computeLuminanceColor();
    if (lcd) {
        // This is the correct computation, but there are tons of cases where LCD can be overridden.
        // For now we just regenerate if any run in a textblob has LCD.
        // TODO figure out where all of these overrides are and see if we can incorporate that logic
        // at a higher level *OR* use sRGB
        SkASSERT(false);
        //canonicalColor = SkMaskGamma::CanonicalColor(canonicalColor);
    } else {
        // A8, though can have mixed BMP text but it shouldn't matter because BMP text won't have
        // gamma corrected masks anyways, nor color
        U8CPU lum = SkComputeLuminance(SkColorGetR(canonicalColor),
                                       SkColorGetG(canonicalColor),
                                       SkColorGetB(canonicalColor));
        // reduce to our finite number of bits
        canonicalColor = SkMaskGamma::CanonicalColor(SkColorSetRGB(lum, lum, lum));
    }
    return canonicalColor;
}

SkScalerContextFlags GrAtlasTextContext::ComputeScalerContextFlags(
        const GrColorSpaceInfo& colorSpaceInfo) {
    // If we're doing gamma-correct rendering, then we can disable the gamma hacks.
    // Otherwise, leave them on. In either case, we still want the contrast boost:
    if (colorSpaceInfo.isGammaCorrect()) {
        return SkScalerContextFlags::kBoostContrast;
    } else {
        return SkScalerContextFlags::kFakeGammaAndBoostContrast;
    }
}

// TODO if this function ever shows up in profiling, then we can compute this value when the
// textblob is being built and cache it.  However, for the time being textblobs mostly only have 1
// run so this is not a big deal to compute here.
bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) {
    SkTextBlobRunIterator it(blob);
    for (; !it.done(); it.next()) {
        if (it.isLCD()) {
            return true;
        }
    }
    return false;
}

void GrAtlasTextContext::drawTextBlob(GrContext* context, GrTextUtils::Target* target,
                                      const GrClip& clip, const SkPaint& skPaint,
                                      const SkMatrix& viewMatrix, const SkSurfaceProps& props,
                                      const SkTextBlob* blob, SkScalar x, SkScalar y,
                                      SkDrawFilter* drawFilter, const SkIRect& clipBounds) {
    // If we have been abandoned, then don't draw
    if (context->contextPriv().abandoned()) {
        return;
    }

    sk_sp<GrAtlasTextBlob> cacheBlob;
    SkMaskFilterBase::BlurRec blurRec;
    GrAtlasTextBlob::Key key;
    // It might be worth caching these things, but its not clear at this time
    // TODO for animated mask filters, this will fill up our cache.  We need a safeguard here
    const SkMaskFilter* mf = skPaint.getMaskFilter();
    bool canCache = !(skPaint.getPathEffect() ||
                      (mf && !as_MFB(mf)->asABlur(&blurRec)) ||
                      drawFilter);
    SkScalerContextFlags scalerContextFlags = ComputeScalerContextFlags(target->colorSpaceInfo());

    auto glyphCache = context->contextPriv().getGlyphCache();
    GrTextBlobCache* textBlobCache = context->contextPriv().getTextBlobCache();

    if (canCache) {
        bool hasLCD = HasLCD(blob);

        // We canonicalize all non-lcd draws to use kUnknown_SkPixelGeometry
        SkPixelGeometry pixelGeometry = hasLCD ? props.pixelGeometry() :
                                                 kUnknown_SkPixelGeometry;

        // TODO we want to figure out a way to be able to use the canonical color on LCD text,
        // see the note on ComputeCanonicalColor above.  We pick a dummy value for LCD text to
        // ensure we always match the same key
        GrColor canonicalColor = hasLCD ? SK_ColorTRANSPARENT :
                                          ComputeCanonicalColor(skPaint, hasLCD);

        key.fPixelGeometry = pixelGeometry;
        key.fUniqueID = blob->uniqueID();
        key.fStyle = skPaint.getStyle();
        key.fHasBlur = SkToBool(mf);
        key.fCanonicalColor = canonicalColor;
        key.fScalerContextFlags = scalerContextFlags;
        cacheBlob = textBlobCache->find(key);
    }

    GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo());
    if (cacheBlob) {
        if (cacheBlob->mustRegenerate(paint, blurRec, viewMatrix, x, y)) {
            // We have to remake the blob because changes may invalidate our masks.
            // TODO we could probably get away reuse most of the time if the pointer is unique,
            // but we'd have to clear the subrun information
            textBlobCache->remove(cacheBlob.get());
            cacheBlob = textBlobCache->makeCachedBlob(blob, key, blurRec, skPaint);
            this->regenerateTextBlob(cacheBlob.get(), glyphCache,
                                     *context->caps()->shaderCaps(), paint, scalerContextFlags,
                                     viewMatrix, props, blob, x, y, drawFilter);
        } else {
            textBlobCache->makeMRU(cacheBlob.get());

            if (CACHE_SANITY_CHECK) {
                int glyphCount = 0;
                int runCount = 0;
                GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob);
                sk_sp<GrAtlasTextBlob> sanityBlob(textBlobCache->makeBlob(glyphCount, runCount));
                sanityBlob->setupKey(key, blurRec, skPaint);
                this->regenerateTextBlob(sanityBlob.get(), glyphCache,
                                         *context->caps()->shaderCaps(), paint, scalerContextFlags,
                                         viewMatrix, props, blob, x, y, drawFilter);
                GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob);
            }
        }
    } else {
        if (canCache) {
            cacheBlob = textBlobCache->makeCachedBlob(blob, key, blurRec, skPaint);
        } else {
            cacheBlob = textBlobCache->makeBlob(blob);
        }
        this->regenerateTextBlob(cacheBlob.get(), glyphCache,
                                 *context->caps()->shaderCaps(), paint, scalerContextFlags,
                                 viewMatrix, props, blob, x, y, drawFilter);
    }

    cacheBlob->flush(target, props, fDistanceAdjustTable.get(), paint,
                     clip, viewMatrix, clipBounds, x, y);
}

void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
                                            GrGlyphCache* glyphCache,
                                            const GrShaderCaps& shaderCaps,
                                            const GrTextUtils::Paint& paint,
                                            SkScalerContextFlags scalerContextFlags,
                                            const SkMatrix& viewMatrix,
                                            const SkSurfaceProps& props, const SkTextBlob* blob,
                                            SkScalar x, SkScalar y,
                                            SkDrawFilter* drawFilter) const {
    cacheBlob->initReusableBlob(paint.luminanceColor(), viewMatrix, x, y);

    // Regenerate textblob
    SkTextBlobRunIterator it(blob);
    GrTextUtils::RunPaint runPaint(&paint, drawFilter);
    for (int run = 0; !it.done(); it.next(), run++) {
        int glyphCount = it.glyphCount();
        size_t textLen = glyphCount * sizeof(uint16_t);
        const SkPoint& offset = it.offset();
        cacheBlob->push_back_run(run);
        if (!runPaint.modifyForRun([it](SkPaint* p) { it.applyFontToPaint(p); })) {
            continue;
        }
        cacheBlob->setRunPaintFlags(run, runPaint.skPaint().getFlags());

        if (this->canDrawAsDistanceFields(runPaint, viewMatrix, props, shaderCaps)) {
            switch (it.positioning()) {
                case SkTextBlob::kDefault_Positioning: {
                    this->drawDFText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
                                     viewMatrix, (const char*)it.glyphs(), textLen, x + offset.x(),
                                     y + offset.y());
                    break;
                }
                case SkTextBlob::kHorizontal_Positioning: {
                    SkPoint dfOffset = SkPoint::Make(x, y + offset.y());
                    this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
                                        scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
                                        textLen, it.pos(), 1, dfOffset);
                    break;
                }
                case SkTextBlob::kFull_Positioning: {
                    SkPoint dfOffset = SkPoint::Make(x, y);
                    this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
                                        scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
                                        textLen, it.pos(), 2, dfOffset);
                    break;
                }
            }
        } else {
            switch (it.positioning()) {
                case SkTextBlob::kDefault_Positioning:
                    DrawBmpText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
                                viewMatrix, (const char*)it.glyphs(), textLen, x + offset.x(),
                                y + offset.y());
                    break;
                case SkTextBlob::kHorizontal_Positioning:
                    DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
                                   viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 1,
                                   SkPoint::Make(x, y + offset.y()));
                    break;
                case SkTextBlob::kFull_Positioning:
                    DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
                                   viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2,
                                   SkPoint::Make(x, y));
                    break;
            }
        }
    }
}

inline sk_sp<GrAtlasTextBlob>
GrAtlasTextContext::makeDrawTextBlob(GrTextBlobCache* blobCache,
                                     GrGlyphCache* glyphCache,
                                     const GrShaderCaps& shaderCaps,
                                     const GrTextUtils::Paint& paint,
                                     SkScalerContextFlags scalerContextFlags,
                                     const SkMatrix& viewMatrix,
                                     const SkSurfaceProps& props,
                                     const char text[], size_t byteLength,
                                     SkScalar x, SkScalar y) const {
    int glyphCount = paint.skPaint().countText(text, byteLength);
    if (!glyphCount) {
        return nullptr;
    }
    sk_sp<GrAtlasTextBlob> blob = blobCache->makeBlob(glyphCount, 1);
    blob->initThrowawayBlob(viewMatrix, x, y);
    blob->setRunPaintFlags(0, paint.skPaint().getFlags());

    if (this->canDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps)) {
        this->drawDFText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
                         text, byteLength, x, y);
    } else {
        DrawBmpText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix, text,
                    byteLength, x, y);
    }
    return blob;
}

inline sk_sp<GrAtlasTextBlob>
GrAtlasTextContext::makeDrawPosTextBlob(GrTextBlobCache* blobCache,
                                        GrGlyphCache* glyphCache,
                                        const GrShaderCaps& shaderCaps,
                                        const GrTextUtils::Paint& paint,
                                        SkScalerContextFlags scalerContextFlags,
                                        const SkMatrix& viewMatrix,
                                        const SkSurfaceProps& props,
                                        const char text[], size_t byteLength,
                                        const SkScalar pos[], int scalarsPerPosition, const
                                        SkPoint& offset) const {
    int glyphCount = paint.skPaint().countText(text, byteLength);
    if (!glyphCount) {
        return nullptr;
    }

    sk_sp<GrAtlasTextBlob> blob = blobCache->makeBlob(glyphCount, 1);
    blob->initThrowawayBlob(viewMatrix, offset.x(), offset.y());
    blob->setRunPaintFlags(0, paint.skPaint().getFlags());

    if (this->canDrawAsDistanceFields(paint, viewMatrix, props, shaderCaps)) {
        this->drawDFPosText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
                            text, byteLength, pos, scalarsPerPosition, offset);
    } else {
        DrawBmpPosText(blob.get(), 0, glyphCache, props, paint, scalerContextFlags, viewMatrix,
                       text, byteLength, pos, scalarsPerPosition, offset);
    }
    return blob;
}

void GrAtlasTextContext::drawText(GrContext* context, GrTextUtils::Target* target,
                                  const GrClip& clip, const SkPaint& skPaint,
                                  const SkMatrix& viewMatrix, const SkSurfaceProps& props,
                                  const char text[], size_t byteLength, SkScalar x, SkScalar y,
                                  const SkIRect& regionClipBounds) {
    if (context->contextPriv().abandoned()) {
        return;
    }

    auto glyphCache = context->contextPriv().getGlyphCache();
    auto textBlobCache = context->contextPriv().getTextBlobCache();

    GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo());
    sk_sp<GrAtlasTextBlob> blob(
            this->makeDrawTextBlob(textBlobCache, glyphCache,
                                    *context->caps()->shaderCaps(), paint,
                                    ComputeScalerContextFlags(target->colorSpaceInfo()),
                                    viewMatrix, props, text, byteLength, x, y));
    if (blob) {
        blob->flush(target, props, fDistanceAdjustTable.get(), paint,
                    clip, viewMatrix, regionClipBounds, x, y);
    }
}

void GrAtlasTextContext::drawPosText(GrContext* context, GrTextUtils::Target* target,
                                     const GrClip& clip, const SkPaint& skPaint,
                                     const SkMatrix& viewMatrix, const SkSurfaceProps& props,
                                     const char text[], size_t byteLength, const SkScalar pos[],
                                     int scalarsPerPosition, const SkPoint& offset,
                                     const SkIRect& regionClipBounds) {
    GrTextUtils::Paint paint(&skPaint, &target->colorSpaceInfo());
    if (context->contextPriv().abandoned()) {
        return;
    }

    auto glyphCache = context->contextPriv().getGlyphCache();
    auto textBlobCache = context->contextPriv().getTextBlobCache();

    sk_sp<GrAtlasTextBlob> blob(this->makeDrawPosTextBlob(
            textBlobCache, glyphCache,
            *context->caps()->shaderCaps(), paint,
            ComputeScalerContextFlags(target->colorSpaceInfo()), viewMatrix, props, text,
            byteLength, pos, scalarsPerPosition, offset));
    if (blob) {
        blob->flush(target, props, fDistanceAdjustTable.get(), paint,
                    clip, viewMatrix, regionClipBounds, offset.fX, offset.fY);
    }
}

void GrAtlasTextContext::DrawBmpText(GrAtlasTextBlob* blob, int runIndex,
                                     GrGlyphCache* glyphCache, const SkSurfaceProps& props,
                                     const GrTextUtils::Paint& paint,
                                     SkScalerContextFlags scalerContextFlags,
                                     const SkMatrix& viewMatrix, const char text[],
                                     size_t byteLength, SkScalar x, SkScalar y) {
    SkASSERT(byteLength == 0 || text != nullptr);

    // nothing to draw
    if (text == nullptr || byteLength == 0) {
        return;
    }

    // Ensure the blob is set for bitmaptext
    blob->setHasBitmap();

    if (SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix)) {
        DrawBmpTextAsPaths(blob, runIndex, glyphCache, props, paint, scalerContextFlags, viewMatrix,
                           text, byteLength, x, y);
        return;
    }

    sk_sp<GrTextStrike> currStrike;
    auto cache = blob->setupCache(runIndex, props, scalerContextFlags, paint, &viewMatrix);
    SkFindAndPlaceGlyph::ProcessText(paint.skPaint().getTextEncoding(), text, byteLength, {x, y},
                                     viewMatrix, paint.skPaint().getTextAlign(), cache.get(),
                                     [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
                                         position += rounding;
                                         BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike,
                                                        glyph, SkScalarFloorToScalar(position.fX),
                                                        SkScalarFloorToScalar(position.fY),
                                                        paint.filteredPremulColor(), cache.get(),
                                                        SK_Scalar1);
                                     });
}

void GrAtlasTextContext::DrawBmpPosText(GrAtlasTextBlob* blob, int runIndex,
                                        GrGlyphCache* glyphCache, const SkSurfaceProps& props,
                                        const GrTextUtils::Paint& paint,
                                        SkScalerContextFlags scalerContextFlags,
                                        const SkMatrix& viewMatrix,
                                        const char text[], size_t byteLength, const SkScalar pos[],
                                        int scalarsPerPosition, const SkPoint& offset) {
    SkASSERT(byteLength == 0 || text != nullptr);
    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);

    // nothing to draw
    if (text == nullptr || byteLength == 0) {
        return;
    }

    // Ensure the blob is set for bitmaptext
    blob->setHasBitmap();

    if (SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix)) {
        DrawBmpPosTextAsPaths(blob, runIndex, glyphCache, props, paint, scalerContextFlags,
                              viewMatrix, text, byteLength, pos, scalarsPerPosition, offset);
        return;
    }

    sk_sp<GrTextStrike> currStrike;
    auto cache = blob->setupCache(runIndex, props, scalerContextFlags, paint, &viewMatrix);
    SkFindAndPlaceGlyph::ProcessPosText(
            paint.skPaint().getTextEncoding(), text, byteLength, offset, viewMatrix, pos,
            scalarsPerPosition, paint.skPaint().getTextAlign(), cache.get(),
            [&](const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
                position += rounding;
                BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph,
                               SkScalarFloorToScalar(position.fX),
                               SkScalarFloorToScalar(position.fY),
                               paint.filteredPremulColor(), cache.get(), SK_Scalar1);
            });
}

void GrAtlasTextContext::DrawBmpTextAsPaths(GrAtlasTextBlob* blob, int runIndex,
                                            GrGlyphCache* glyphCache,
                                            const SkSurfaceProps& props,
                                            const GrTextUtils::Paint& origPaint,
                                            SkScalerContextFlags scalerContextFlags,
                                            const SkMatrix& viewMatrix, const char text[],
                                            size_t byteLength, SkScalar x, SkScalar y) {
    // nothing to draw
    if (text == nullptr || byteLength == 0) {
        return;
    }

    // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
    SkPaint pathPaint(origPaint);
    pathPaint.setStyle(SkPaint::kFill_Style);
    pathPaint.setPathEffect(nullptr);

    GrTextUtils::PathTextIter iter(text, byteLength, pathPaint, true);
    FallbackTextHelper fallbackTextHelper(viewMatrix, pathPaint, glyphCache, iter.getPathScale());

    const SkGlyph* iterGlyph;
    const SkPath* iterPath;
    SkScalar xpos = 0;
    const char* lastText = text;
    while (iter.next(&iterGlyph, &iterPath, &xpos)) {
        if (iterGlyph) {
            SkPoint pos = SkPoint::Make(xpos + x, y);
            fallbackTextHelper.appendText(*iterGlyph, iter.getText() - lastText, lastText, pos);
        } else if (iterPath) {
            blob->appendPathGlyph(runIndex, *iterPath, xpos + x, y, iter.getPathScale(), false);
        }
        lastText = iter.getText();
    }

    fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, origPaint, scalerContextFlags);
}

void GrAtlasTextContext::DrawBmpPosTextAsPaths(GrAtlasTextBlob* blob, int runIndex,
                                               GrGlyphCache* glyphCache,
                                               const SkSurfaceProps& props,
                                               const GrTextUtils::Paint& origPaint,
                                               SkScalerContextFlags scalerContextFlags,
                                               const SkMatrix& viewMatrix,
                                               const char text[], size_t byteLength,
                                               const SkScalar pos[], int scalarsPerPosition,
                                               const SkPoint& offset) {
    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);

    // nothing to draw
    if (text == nullptr || byteLength == 0) {
        return;
    }

    // setup our std paint, in hopes of getting hits in the cache
    SkPaint pathPaint(origPaint);
    SkScalar matrixScale = pathPaint.setupForAsPaths();
    FallbackTextHelper fallbackTextHelper(viewMatrix, origPaint, glyphCache, matrixScale);

    // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
    pathPaint.setStyle(SkPaint::kFill_Style);
    pathPaint.setPathEffect(nullptr);

    SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(pathPaint.getTextEncoding(),
                                                                        true);
    auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(
            pathPaint, &props, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr);

    const char*        stop = text + byteLength;
    const char*        lastText = text;
    SkTextAlignProc    alignProc(pathPaint.getTextAlign());
    SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);

    while (text < stop) {
        const SkGlyph& glyph = glyphCacheProc(cache.get(), &text);
        if (glyph.fWidth) {
            SkPoint tmsLoc;
            tmsProc(pos, &tmsLoc);
            SkPoint loc;
            alignProc(tmsLoc, glyph, &loc);
            if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
                fallbackTextHelper.appendText(glyph, text - lastText, lastText, loc);
            } else {
                const SkPath* path = cache->findPath(glyph);
                if (path) {
                    blob->appendPathGlyph(runIndex, *path, loc.fX, loc.fY, matrixScale, false);
                }
            }
        }
        lastText = text;
        pos += scalarsPerPosition;
    }

    fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, origPaint, scalerContextFlags);
}

void GrAtlasTextContext::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
                                        GrGlyphCache* grGlyphCache,
                                        sk_sp<GrTextStrike>* strike,
                                        const SkGlyph& skGlyph, SkScalar sx, SkScalar sy,
                                        GrColor color, SkGlyphCache* skGlyphCache,
                                        SkScalar textRatio) {
    if (!*strike) {
        *strike = grGlyphCache->getStrike(skGlyphCache);
    }

    GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
                                         skGlyph.getSubXFixed(),
                                         skGlyph.getSubYFixed(),
                                         GrGlyph::kCoverage_MaskStyle);
    GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, skGlyphCache);
    if (!glyph) {
        return;
    }

    SkASSERT(skGlyph.fWidth == glyph->width());
    SkASSERT(skGlyph.fHeight == glyph->height());

    SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft);
    SkScalar dy = SkIntToScalar(glyph->fBounds.fTop);
    SkScalar width = SkIntToScalar(glyph->fBounds.width());
    SkScalar height = SkIntToScalar(glyph->fBounds.height());

    dx *= textRatio;
    dy *= textRatio;
    width *= textRatio;
    height *= textRatio;

    SkRect glyphRect = SkRect::MakeXYWH(sx + dx, sy + dy, width, height);

    blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, skGlyphCache, skGlyph, sx, sy,
                      textRatio, true);
}

bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
                                                 const SkSurfaceProps& props,
                                                 const GrShaderCaps& caps) const {
    if (!viewMatrix.hasPerspective()) {
        SkScalar maxScale = viewMatrix.getMaxScale();
        SkScalar scaledTextSize = maxScale * skPaint.getTextSize();
        // Hinted text looks far better at small resolutions
        // Scaling up beyond 2x yields undesireable artifacts
        if (scaledTextSize < fMinDistanceFieldFontSize ||
            scaledTextSize > fMaxDistanceFieldFontSize) {
            return false;
        }

        bool useDFT = props.isUseDeviceIndependentFonts();
#if SK_FORCE_DISTANCE_FIELD_TEXT
        useDFT = true;
#endif

        if (!useDFT && scaledTextSize < kLargeDFFontSize) {
            return false;
        }
    }

    // mask filters modify alpha, which doesn't translate well to distance
    if (skPaint.getMaskFilter() || !caps.shaderDerivativeSupport()) {
        return false;
    }

    // TODO: add some stroking support
    if (skPaint.getStyle() != SkPaint::kFill_Style) {
        return false;
    }

    return true;
}

void GrAtlasTextContext::initDistanceFieldPaint(GrAtlasTextBlob* blob,
                                                SkPaint* skPaint,
                                                SkScalar* textRatio,
                                                const SkMatrix& viewMatrix) const {
    SkScalar textSize = skPaint->getTextSize();
    SkScalar scaledTextSize = textSize;

    if (viewMatrix.hasPerspective()) {
        // for perspective, we simply force to the medium size
        // TODO: compute a size based on approximate screen area
        scaledTextSize = kMediumDFFontLimit;
    } else {
        SkScalar maxScale = viewMatrix.getMaxScale();
        // if we have non-unity scale, we need to choose our base text size
        // based on the SkPaint's text size multiplied by the max scale factor
        // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
        if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
            scaledTextSize *= maxScale;
        }
    }

    // We have three sizes of distance field text, and within each size 'bucket' there is a floor
    // and ceiling.  A scale outside of this range would require regenerating the distance fields
    SkScalar dfMaskScaleFloor;
    SkScalar dfMaskScaleCeil;
    if (scaledTextSize <= kSmallDFFontLimit) {
        dfMaskScaleFloor = fMinDistanceFieldFontSize;
        dfMaskScaleCeil = kSmallDFFontLimit;
        *textRatio = textSize / kSmallDFFontSize;
        skPaint->setTextSize(SkIntToScalar(kSmallDFFontSize));
    } else if (scaledTextSize <= kMediumDFFontLimit) {
        dfMaskScaleFloor = kSmallDFFontLimit;
        dfMaskScaleCeil = kMediumDFFontLimit;
        *textRatio = textSize / kMediumDFFontSize;
        skPaint->setTextSize(SkIntToScalar(kMediumDFFontSize));
    } else {
        dfMaskScaleFloor = kMediumDFFontLimit;
        dfMaskScaleCeil = fMaxDistanceFieldFontSize;
        *textRatio = textSize / kLargeDFFontSize;
        skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize));
    }

    // Because there can be multiple runs in the blob, we want the overall maxMinScale, and
    // minMaxScale to make regeneration decisions.  Specifically, we want the maximum minimum scale
    // we can tolerate before we'd drop to a lower mip size, and the minimum maximum scale we can
    // tolerate before we'd have to move to a large mip size.  When we actually test these values
    // we look at the delta in scale between the new viewmatrix and the old viewmatrix, and test
    // against these values to decide if we can reuse or not(ie, will a given scale change our mip
    // level)
    SkASSERT(dfMaskScaleFloor <= scaledTextSize && scaledTextSize <= dfMaskScaleCeil);
    blob->setMinAndMaxScale(dfMaskScaleFloor / scaledTextSize, dfMaskScaleCeil / scaledTextSize);

    skPaint->setAntiAlias(true);
    skPaint->setLCDRenderText(false);
    skPaint->setAutohinted(false);
    skPaint->setHinting(SkPaint::kNormal_Hinting);
    skPaint->setSubpixelText(true);

    skPaint->setMaskFilter(GrSDFMaskFilter::Make());
}

void GrAtlasTextContext::drawDFText(GrAtlasTextBlob* blob, int runIndex,
                                    GrGlyphCache* glyphCache, const SkSurfaceProps& props,
                                    const GrTextUtils::Paint& paint,
                                    SkScalerContextFlags scalerContextFlags,
                                    const SkMatrix& viewMatrix, const char text[],
                                    size_t byteLength, SkScalar x, SkScalar y) const {
    SkASSERT(byteLength == 0 || text != nullptr);

    // nothing to draw
    if (text == nullptr || byteLength == 0) {
        return;
    }

    const SkPaint& skPaint = paint.skPaint();
    SkPaint::GlyphCacheProc glyphCacheProc =
            SkPaint::GetGlyphCacheProc(skPaint.getTextEncoding(), true);

    SkTArray<SkScalar> positions;

    const char* textPtr = text;
    SkScalar stopX = 0;
    SkScalar stopY = 0;
    SkScalar origin = 0;
    switch (skPaint.getTextAlign()) {
        case SkPaint::kRight_Align: origin = SK_Scalar1; break;
        case SkPaint::kCenter_Align: origin = SK_ScalarHalf; break;
        case SkPaint::kLeft_Align: origin = 0; break;
    }

    SkAutoDescriptor desc;
    SkScalerContextEffects effects;
    // We apply the fake-gamma by altering the distance in the shader, so we ignore the
    // passed-in scaler context flags. (It's only used when we fall-back to bitmap text).
    SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
        skPaint, &props, SkScalerContextFlags::kNone, nullptr, &desc, &effects);
    auto typeface = SkPaintPriv::GetTypefaceOrDefault(skPaint);

    {
        auto origPaintCache =
            SkStrikeCache::FindOrCreateStrikeExclusive(*desc.getDesc(), effects, *typeface);

        const char* stop = text + byteLength;
        while (textPtr < stop) {
            // don't need x, y here, since all subpixel variants will have the
            // same advance
            const SkGlyph& glyph = glyphCacheProc(origPaintCache.get(), &textPtr);

            SkScalar width = SkFloatToScalar(glyph.fAdvanceX);
            positions.push_back(stopX + origin * width);

            SkScalar height = SkFloatToScalar(glyph.fAdvanceY);
            positions.push_back(stopY + origin * height);

            stopX += width;
            stopY += height;
        }
        SkASSERT(textPtr == stop);
    }

    // now adjust starting point depending on alignment
    SkScalar alignX = stopX;
    SkScalar alignY = stopY;
    if (skPaint.getTextAlign() == SkPaint::kCenter_Align) {
        alignX = SkScalarHalf(alignX);
        alignY = SkScalarHalf(alignY);
    } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) {
        alignX = 0;
        alignY = 0;
    }
    x -= alignX;
    y -= alignY;
    SkPoint offset = SkPoint::Make(x, y);

    this->drawDFPosText(blob, runIndex, glyphCache, props, paint, scalerContextFlags, viewMatrix,
                        text, byteLength, positions.begin(), 2, offset);
}

void GrAtlasTextContext::drawDFPosText(GrAtlasTextBlob* blob, int runIndex,
                                       GrGlyphCache* glyphCache, const SkSurfaceProps& props,
                                       const GrTextUtils::Paint& paint,
                                       SkScalerContextFlags scalerContextFlags,
                                       const SkMatrix& viewMatrix, const char text[],
                                       size_t byteLength, const SkScalar pos[],
                                       int scalarsPerPosition, const SkPoint& offset) const {
    SkASSERT(byteLength == 0 || text != nullptr);
    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);

    // nothing to draw
    if (text == nullptr || byteLength == 0) {
        return;
    }

    bool hasWCoord = viewMatrix.hasPerspective() || fDistanceFieldVerticesAlwaysHaveW;

    // Setup distance field paint and text ratio
    SkScalar textRatio;
    SkPaint dfPaint(paint);
    this->initDistanceFieldPaint(blob, &dfPaint, &textRatio, viewMatrix);
    blob->setHasDistanceField();
    blob->setSubRunHasDistanceFields(runIndex, paint.skPaint().isLCDRenderText(),
                                     paint.skPaint().isAntiAlias(), hasWCoord);

    FallbackTextHelper fallbackTextHelper(viewMatrix, paint, glyphCache, textRatio);

    sk_sp<GrTextStrike> currStrike;

    {
        // We apply the fake-gamma by altering the distance in the shader, so we ignore the
        // passed-in scaler context flags. (It's only used when we fall-back to bitmap text).
        auto cache = blob->setupCache(runIndex, props, SkScalerContextFlags::kNone, dfPaint,
                                      nullptr);
        SkPaint::GlyphCacheProc glyphCacheProc =
            SkPaint::GetGlyphCacheProc(dfPaint.getTextEncoding(), true);

        const char* stop = text + byteLength;

        SkPaint::Align align = dfPaint.getTextAlign();
        SkScalar alignMul = SkPaint::kCenter_Align == align ? SK_ScalarHalf :
                            (SkPaint::kRight_Align == align ? SK_Scalar1 : 0);
        while (text < stop) {
            const char* lastText = text;
            // the last 2 parameters are ignored
            const SkGlyph& glyph = glyphCacheProc(cache.get(), &text);

            if (glyph.fWidth) {
                SkPoint glyphPos(offset);
                glyphPos.fX += pos[0] - SkFloatToScalar(glyph.fAdvanceX) * alignMul * textRatio;
                glyphPos.fY += (2 == scalarsPerPosition ? pos[1] : 0) -
                               SkFloatToScalar(glyph.fAdvanceY) * alignMul * textRatio;

                if (glyph.fMaskFormat == SkMask::kSDF_Format) {
                    DfAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph, glyphPos.fX,
                                  glyphPos.fY, paint.filteredPremulColor(), cache.get(), textRatio);
                } else {
                    // can't append non-SDF glyph to SDF batch, send to fallback
                    fallbackTextHelper.appendText(glyph, SkToInt(text - lastText), lastText,
                                                  glyphPos);
                }
            }
            pos += scalarsPerPosition;
        }
    }

    fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, paint, scalerContextFlags);
}

// TODO: merge with BmpAppendGlyph
void GrAtlasTextContext::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
                                       GrGlyphCache* grGlyphCache, sk_sp<GrTextStrike>* strike,
                                       const SkGlyph& skGlyph, SkScalar sx, SkScalar sy,
                                       GrColor color, SkGlyphCache* skGlyphCache,
                                       SkScalar textRatio) {
    if (!*strike) {
        *strike = grGlyphCache->getStrike(skGlyphCache);
    }

    GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
                                         skGlyph.getSubXFixed(),
                                         skGlyph.getSubYFixed(),
                                         GrGlyph::kDistance_MaskStyle);
    GrGlyph* glyph = (*strike)->getGlyph(skGlyph, id, skGlyphCache);
    if (!glyph) {
        return;
    }

    SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset);
    SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset);
    SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2 * SK_DistanceFieldInset);
    SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2 * SK_DistanceFieldInset);

    dx *= textRatio;
    dy *= textRatio;
    width *= textRatio;
    height *= textRatio;
    SkRect glyphRect = SkRect::MakeXYWH(sx + dx, sy + dy, width, height);

    blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, skGlyphCache, skGlyph, sx, sy,
                      textRatio, false);
}

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

void GrAtlasTextContext::FallbackTextHelper::appendText(const SkGlyph& glyph, int count,
                                                        const char* text, SkPoint glyphPos) {
    SkScalar maxDim = SkTMax(glyph.fWidth, glyph.fHeight)*fTextRatio;
    if (!fUseScaledFallback) {
        SkScalar scaledGlyphSize = maxDim * fMaxScale;
        if (!fViewMatrix.hasPerspective() && scaledGlyphSize > fMaxTextSize) {
            fUseScaledFallback = true;
            fMaxTextSize -= 2;    // Subtract 2 to account for the bilerp pad around the glyph
        }
    }

    fFallbackTxt.append(count, text);
    if (fUseScaledFallback) {
        // If there's a glyph in the font that's particularly large, it's possible
        // that fScaledFallbackTextSize may end up minimizing too much. We'd rather skip
        // that glyph than make the others pixelated, so we set a minimum size of half the
        // maximum text size to avoid this case.
        SkScalar glyphTextSize = SkTMax(SkScalarFloorToScalar(fMaxTextSize*fTextSize / maxDim),
                                        0.5f*fMaxTextSize);
        fScaledFallbackTextSize = SkTMin(glyphTextSize, fScaledFallbackTextSize);
    }
    *fFallbackPos.append() = glyphPos;
}

void GrAtlasTextContext::FallbackTextHelper::drawText(GrAtlasTextBlob* blob, int runIndex,
                                                      GrGlyphCache* glyphCache,
                                                      const SkSurfaceProps& props,
                                                      const GrTextUtils::Paint& paint,
                                                      SkScalerContextFlags scalerContextFlags) {
    if (fFallbackTxt.count()) {
        if (fViewMatrix.hasPerspective()) {
            // TODO: handle perspective
            return;
        }

        blob->initOverride(runIndex);
        blob->setHasBitmap();
        SkExclusiveStrikePtr cache;
        const SkPaint& skPaint = paint.skPaint();
        SkPaint::GlyphCacheProc glyphCacheProc =
            SkPaint::GetGlyphCacheProc(skPaint.getTextEncoding(), true);
        SkColor textColor = paint.filteredPremulColor();
        SkScalar textRatio = SK_Scalar1;
        if (fUseScaledFallback) {
            // Set up paint and matrix to scale glyphs
            SkPaint scaledPaint(skPaint);
            scaledPaint.setTextSize(fScaledFallbackTextSize);
            // remove maxScale from viewMatrix and move it into textRatio
            // this keeps the base glyph size consistent regardless of matrix scale
            SkMatrix modMatrix(fViewMatrix);
            SkScalar invScale = SkScalarInvert(fMaxScale);
            modMatrix.preScale(invScale, invScale);
            textRatio = fTextSize * fMaxScale / fScaledFallbackTextSize;
            cache = blob->setupCache(runIndex, props, scalerContextFlags, scaledPaint,
                                     &modMatrix);
        } else {
            cache = blob->setupCache(runIndex, props, scalerContextFlags, paint,
                                     &fViewMatrix);
        }

        sk_sp<GrTextStrike> currStrike;
        const char* text = fFallbackTxt.begin();
        const char* stop = text + fFallbackTxt.count();
        SkPoint* glyphPos = fFallbackPos.begin();
        while (text < stop) {
            const SkGlyph& glyph = glyphCacheProc(cache.get(), &text);
            fViewMatrix.mapPoints(glyphPos, 1);
            if (!fUseScaledFallback) {
                glyphPos->fX = SkScalarFloorToScalar(glyphPos->fX);
                glyphPos->fY = SkScalarFloorToScalar(glyphPos->fY);
            }
            GrAtlasTextContext::BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph,
                                               glyphPos->fX, glyphPos->fY, textColor,
                                               cache.get(), textRatio);
            glyphPos++;
        }
    }
}

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

#if GR_TEST_UTILS

#include "GrRenderTargetContext.h"

std::unique_ptr<GrDrawOp> GrAtlasTextContext::createOp_TestingOnly(
                                                       GrContext* context,
                                                       GrAtlasTextContext* textContext,
                                                       GrRenderTargetContext* rtc,
                                                       const SkPaint& skPaint,
                                                       const SkMatrix& viewMatrix,
                                                       const char* text, int x, int y) {
    auto glyphCache = context->contextPriv().getGlyphCache();

    static SkSurfaceProps surfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);

    size_t textLen = (int)strlen(text);

    GrTextUtils::Paint utilsPaint(&skPaint, &rtc->colorSpaceInfo());

    // right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to
    // test the text op with this unit test, that is okay.
    sk_sp<GrAtlasTextBlob> blob(textContext->makeDrawTextBlob(
                                            context->contextPriv().getTextBlobCache(), glyphCache,
                                            *context->caps()->shaderCaps(), utilsPaint,
                                            GrAtlasTextContext::kTextBlobOpScalerContextFlags,
                                            viewMatrix, surfaceProps, text,
                                            static_cast<size_t>(textLen),
                                            SkIntToScalar(x), SkIntToScalar(y)));

    return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, surfaceProps,
                             textContext->dfAdjustTable(), rtc->textTarget());
}

GR_DRAW_OP_TEST_DEFINE(GrAtlasTextOp) {
    static uint32_t gContextID = SK_InvalidGenID;
    static std::unique_ptr<GrAtlasTextContext> gTextContext;
    static SkSurfaceProps gSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);

    if (context->uniqueID() != gContextID) {
        gContextID = context->uniqueID();
        gTextContext = GrAtlasTextContext::Make(GrAtlasTextContext::Options());
    }

    // Setup dummy SkPaint / GrPaint / GrRenderTargetContext
    sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeDeferredRenderTargetContext(
        SkBackingFit::kApprox, 1024, 1024, kRGBA_8888_GrPixelConfig, nullptr));

    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);

    // Because we the GrTextUtils::Paint requires an SkPaint for font info, we ignore the GrPaint
    // param.
    SkPaint skPaint;
    skPaint.setColor(random->nextU());
    skPaint.setLCDRenderText(random->nextBool());
    skPaint.setAntiAlias(skPaint.isLCDRenderText() ? true : random->nextBool());
    skPaint.setSubpixelText(random->nextBool());

    const char* text = "The quick brown fox jumps over the lazy dog.";

    // create some random x/y offsets, including negative offsets
    static const int kMaxTrans = 1024;
    int xPos = (random->nextU() % 2) * 2 - 1;
    int yPos = (random->nextU() % 2) * 2 - 1;
    int xInt = (random->nextU() % kMaxTrans) * xPos;
    int yInt = (random->nextU() % kMaxTrans) * yPos;

    return gTextContext->createOp_TestingOnly(context, gTextContext.get(), rtc.get(),
                                              skPaint, viewMatrix, text, xInt, yInt);
}

#endif
