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

#include "src/text/gpu/SubRunControl.h"

#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkScalar.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"

#include <tuple>

struct SkPoint;

namespace sktext::gpu {

#if !defined(SK_DISABLE_SDF_TEXT)
// 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 Control.
static const int kSmallDFFontLimit = 32;
static const int kMediumDFFontLimit = 72;
static const int kLargeDFFontLimit = 162;
#ifdef SK_BUILD_FOR_MAC
static const int kExtraLargeDFFontLimit = 256;
#endif

SkScalar SubRunControl::MinSDFTRange(bool useSDFTForSmallText, SkScalar min) {
    if (!useSDFTForSmallText) {
        return kLargeDFFontLimit;
    }
    return min;
}

SubRunControl::SubRunControl(
        bool ableToUseSDFT, bool useSDFTForSmallText, bool useSDFTForPerspectiveText,
        SkScalar min, SkScalar max,
        bool forcePathAA,
        bool useBilerp)
        : fMinDistanceFieldFontSize{MinSDFTRange(useSDFTForSmallText, min)}
        , fMaxDistanceFieldFontSize{max}
        , fAbleToUseSDFT{ableToUseSDFT}
        , fAbleToUsePerspectiveSDFT{useSDFTForPerspectiveText}
        , fForcePathAA{forcePathAA}
        , fUseBilerp{useBilerp} {
    SkASSERT_RELEASE(0 < min && min <= max);
}
#endif // !defined(SK_DISABLE_SDF_TEXT)

bool SubRunControl::isDirect(SkScalar approximateDeviceTextSize, const SkPaint& paint,
                             const SkMatrix& matrix) const {
#if !defined(SK_DISABLE_SDF_TEXT)
    const bool isSDFT = this->isSDFT(approximateDeviceTextSize, paint, matrix);
#else
    const bool isSDFT = false;
#endif
    const SkScalar maxAtlasDimension = fUseBilerp
            ? SkGlyphDigest::kSkSideTooBigForAtlas - 2
            : SkGlyphDigest::kSkSideTooBigForAtlas;
    return !isSDFT &&
           !matrix.hasPerspective() &&
            0 < approximateDeviceTextSize &&
            approximateDeviceTextSize < maxAtlasDimension;
}

#if !defined(SK_DISABLE_SDF_TEXT)
bool SubRunControl::isSDFT(SkScalar approximateDeviceTextSize, const SkPaint& paint,
                           const SkMatrix& matrix) const {
    const bool wideStroke = paint.getStyle() == SkPaint::kStroke_Style &&
            paint.getStrokeWidth() > 0;
    return fAbleToUseSDFT &&
           paint.getMaskFilter() == nullptr &&
            (paint.getStyle() == SkPaint::kFill_Style || wideStroke) &&
           0 < approximateDeviceTextSize &&
           (fAbleToUsePerspectiveSDFT || !matrix.hasPerspective()) &&
           (fMinDistanceFieldFontSize <= approximateDeviceTextSize || matrix.hasPerspective()) &&
           approximateDeviceTextSize <= fMaxDistanceFieldFontSize;
}

std::tuple<SkFont, SkScalar, SDFTMatrixRange>
SubRunControl::getSDFFont(const SkFont& font, const SkMatrix& viewMatrix,
                        const SkPoint& textLoc) const {
    SkScalar textSize = font.getSize();
    SkScalar scaledTextSize = SkFontPriv::ApproximateTransformedTextSize(font, viewMatrix, textLoc);
    if (scaledTextSize <= 0 || SkScalarNearlyEqual(textSize, scaledTextSize)) {
        scaledTextSize = textSize;
    }

    SkFont dfFont{font};

    SkScalar dfMaskScaleFloor;
    SkScalar dfMaskScaleCeil;
    SkScalar dfMaskSize;
    if (scaledTextSize <= kSmallDFFontLimit) {
        dfMaskScaleFloor = fMinDistanceFieldFontSize;
        dfMaskScaleCeil = kSmallDFFontLimit;
        dfMaskSize = kSmallDFFontLimit;
    } else if (scaledTextSize <= kMediumDFFontLimit) {
        dfMaskScaleFloor = kSmallDFFontLimit;
        dfMaskScaleCeil = kMediumDFFontLimit;
        dfMaskSize = kMediumDFFontLimit;
#ifdef SK_BUILD_FOR_MAC
    } else if (scaledTextSize <= kLargeDFFontLimit) {
        dfMaskScaleFloor = kMediumDFFontLimit;
        dfMaskScaleCeil = kLargeDFFontLimit;
        dfMaskSize = kLargeDFFontLimit;
    } else {
        dfMaskScaleFloor = kLargeDFFontLimit;
        dfMaskScaleCeil = fMaxDistanceFieldFontSize;
        dfMaskSize = kExtraLargeDFFontLimit;
    }
#else
    } else {
        dfMaskScaleFloor = kMediumDFFontLimit;
        dfMaskScaleCeil = fMaxDistanceFieldFontSize;
        dfMaskSize = kLargeDFFontLimit;
    }
#endif

    dfFont.setSize(dfMaskSize);
    dfFont.setForceAutoHinting(false);
    dfFont.setHinting(SkFontHinting::kNormal);

    // The sub-pixel position will always happen when transforming to the screen, so we effectively
    // disable the LCD path in StrikeSpec creation by overwriting the edging here.
    dfFont.setSubpixel(false);
    dfFont.setEdging(SkFont::Edging::kAntiAlias);

    SkScalar minMatrixScale = dfMaskScaleFloor / textSize,
             maxMatrixScale = dfMaskScaleCeil  / textSize;
    return {dfFont, textSize / dfMaskSize, {minMatrixScale, maxMatrixScale}};
}

bool SDFTMatrixRange::matrixInRange(const SkMatrix& matrix) const {
    SkScalar maxScale = matrix.getMaxScale();
    return fMatrixMin < maxScale && maxScale <= fMatrixMax;
}

void SDFTMatrixRange::flatten(SkWriteBuffer& buffer) const {
    buffer.writeScalar(fMatrixMin);
    buffer.writeScalar(fMatrixMax);
}

SDFTMatrixRange SDFTMatrixRange::MakeFromBuffer(SkReadBuffer& buffer) {
    SkScalar min = buffer.readScalar();
    SkScalar max = buffer.readScalar();
    return SDFTMatrixRange{min, max};
}
#endif // !defined(SK_DISABLE_SDF_TEXT)

}  // namespace sktext::gpu
