/*
 * Copyright 2024 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/ganesh/AtlasTextOpTools.h"

#include "include/core/SkFont.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkStrikeCache.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/ops/AtlasTextOp.h"
#include "src/text/GlyphRun.h"
#include "src/text/gpu/TextBlob.h"
#include "tools/text/gpu/TextBlobTools.h"

#if defined(GPU_TEST_UTILS)
#include "src/base/SkRandom.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#endif

namespace skgpu::ganesh {

GrOp::Owner AtlasTextOpTools::CreateOp(skgpu::ganesh::SurfaceDrawContext* sdc,
                                       const SkPaint& skPaint,
                                       const SkFont& font,
                                       const SkMatrix& ctm,
                                       const char* text,
                                       int x,
                                       int y) {
    size_t textLen = (int)strlen(text);

    SkMatrix drawMatrix = ctm;
    drawMatrix.preTranslate(x, y);
    auto drawOrigin = SkPoint::Make(x, y);
    sktext::GlyphRunBuilder builder;
    auto glyphRunList = builder.textToGlyphRunList(font, skPaint, text, textLen, drawOrigin);
    if (glyphRunList.empty()) {
        return nullptr;
    }

    auto rContext = sdc->recordingContext();
    sktext::gpu::SubRunControl control =
            rContext->priv().getSubRunControl(sdc->surfaceProps().isUseDeviceIndependentFonts());

    SkStrikeDeviceInfo strikeDeviceInfo{
            sdc->surfaceProps(), SkScalerContextFlags::kBoostContrast, &control};

    sk_sp<sktext::gpu::TextBlob> blob =
            sktext::gpu::TextBlob::Make(glyphRunList,
                                        skPaint,
                                        drawMatrix,
                                        strikeDeviceInfo,
                                        SkStrikeCache::GlobalStrikeCache());

    const sktext::gpu::AtlasSubRun* subRun = sktext::gpu::TextBlobTools::FirstSubRun(blob.get());
    if (!subRun) {
        return nullptr;
    }

    GrOp::Owner op;
    std::tie(std::ignore, op) =
            AtlasTextOp::Make(sdc, subRun, nullptr, ctm, glyphRunList.origin(), skPaint, blob);
    return op;
}

}  // namespace skgpu::ganesh

#if defined(GPU_TEST_UTILS)
GR_DRAW_OP_TEST_DEFINE(AtlasTextOp) {
    SkMatrix ctm = GrTest::TestMatrixInvertible(random);

    SkPaint skPaint;
    skPaint.setColor(random->nextU());

    SkFont font;
    if (random->nextBool()) {
        font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
    } else {
        font.setEdging(random->nextBool() ? SkFont::Edging::kAntiAlias : SkFont::Edging::kAlias);
    }
    font.setSubpixel(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 skgpu::ganesh::AtlasTextOpTools::CreateOp(sdc, skPaint, font, ctm, text, xInt, yInt);
}
#endif
