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

#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkPaint.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "tools/fonts/FontToolUtils.h"

#include <string.h>
#include <initializer_list>

#ifdef SK_BUILD_FOR_MAC

#include "include/core/SkSurface.h"

#import <ApplicationServices/ApplicationServices.h>

static void std_cg_setup(CGContextRef ctx) {
    CGContextSetAllowsFontSubpixelQuantization(ctx, false);
    CGContextSetShouldSubpixelQuantizeFonts(ctx, false);

    // Because CG always draws from the horizontal baseline,
    // if there is a non-integral translation from the horizontal origin to the vertical origin,
    // then CG cannot draw the glyph in the correct location without subpixel positioning.
    CGContextSetAllowsFontSubpixelPositioning(ctx, true);
    CGContextSetShouldSubpixelPositionFonts(ctx, true);

    CGContextSetAllowsFontSmoothing(ctx, true);
    CGContextSetShouldAntialias(ctx, true);

    CGContextSetTextDrawingMode(ctx, kCGTextFill);

    // Draw black on white to create mask. (Special path exists to speed this up in CG.)
    CGContextSetGrayFillColor(ctx, 0.0f, 1.0f);
}

static CGContextRef make_cg_ctx(const SkPixmap& pm) {
    CGBitmapInfo info;
    CGColorSpaceRef cs;

    switch (pm.colorType()) {
        case kRGBA_8888_SkColorType:
            info = kCGBitmapByteOrder32Host | (CGBitmapInfo)kCGImageAlphaNoneSkipFirst;
            cs = CGColorSpaceCreateDeviceRGB();
            break;
        case kGray_8_SkColorType:
            info = kCGImageAlphaNone;
            cs = CGColorSpaceCreateDeviceGray();
            break;
        case kAlpha_8_SkColorType:
            info = kCGImageAlphaOnly;
            cs = nullptr;
            break;
        default:
            return nullptr;
    }
    auto ctx = CGBitmapContextCreate(pm.writable_addr(), pm.width(), pm.height(), 8, pm.rowBytes(),
                                     cs, info);
    std_cg_setup(ctx);
    return ctx;
}

static void test_mac_fonts(SkCanvas* canvas, SkScalar size, SkScalar xpos) {
    int w = 32;
    int h = 32;

    canvas->scale(10, 10);
    SkScalar y = 1;

    for (SkColorType ct : {kRGBA_8888_SkColorType, kGray_8_SkColorType, kAlpha_8_SkColorType}) {
        SkImageInfo ii = SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType);
        auto surf = SkSurfaces::Raster(ii);
        SkPixmap pm;
        surf->peekPixels(&pm);
        CGContextRef ctx = make_cg_ctx(pm);
        CGContextSelectFont(ctx, "Times", size, kCGEncodingMacRoman);

        SkScalar x = 1;
        for (bool smooth : {false, true}) {
            surf->getCanvas()->clear(ct == kAlpha_8_SkColorType ? 0 : 0xFFFFFFFF);
            CGContextSetShouldSmoothFonts(ctx, smooth);
            CGContextShowTextAtPoint(ctx, 2 + xpos, 2, "A", 1);

            surf->draw(canvas, x, y);
            x += pm.width();
        }
        y += pm.height();
    }
}

class MacAAFontsGM : public skiagm::GM {
    SkScalar fSize = 16;
    SkScalar fXPos = 0;

public:
    MacAAFontsGM() {}
    ~MacAAFontsGM() override {}

protected:
    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        test_mac_fonts(canvas, fSize, fXPos);

        return DrawResult::kOk;
    }

    SkISize getISize() override { return {1024, 768}; }

    SkString getName() const override { return SkString("macaatest"); }

    bool onChar(SkUnichar uni) override {
        switch (uni) {
            case 'i': fSize += 1; return true;
            case 'k': fSize -= 1; return true;
            case 'j': fXPos -= 1.0f/16; return true;
            case 'l': fXPos += 1.0f/16; return true;
            default: break;
        }
        return false;
    }
};
DEF_GM(return new MacAAFontsGM;)

#endif

DEF_SIMPLE_GM(macaa_colors, canvas, 800, 500) {
    const SkColor GRAY = 0xFF808080;
    const SkColor colors[] = {
        SK_ColorBLACK, SK_ColorWHITE,
        SK_ColorBLACK, GRAY,
        SK_ColorWHITE, SK_ColorBLACK,
        SK_ColorWHITE, GRAY,
    };
    const SkScalar sizes[] = {10, 12, 15, 18, 24};

    const SkScalar width = 200;
    const SkScalar height = 500;
    const char str[] = "Hamburgefons";
    const size_t len = strlen(str);

    sk_sp<SkTypeface> face = ToolUtils::CreateTestTypeface("Times", SkFontStyle());
    if (!face) {
        face = ToolUtils::DefaultPortableTypeface();
    }
    SkFont font(face, 12);

    for (size_t i = 0; i < std::size(colors); i += 2) {
        canvas->save();

        SkPaint paint;
        paint.setColor(colors[i+1]);
        canvas->drawRect({0, 0, width, height}, paint);
        paint.setColor(colors[i]);

        SkScalar y = 10;
        SkScalar x = 10;
        for (SkScalar ps : sizes) {
            font.setSize(ps);
            for (bool lcd : {false, true}) {
                font.setEdging(lcd ? SkFont::Edging::kSubpixelAntiAlias
                                   : SkFont::Edging::kAntiAlias);
                for (auto h : {SkFontHinting::kNone, SkFontHinting::kNormal}) {
                    font.setHinting(h);

                    y += font.getSpacing() + 2;
                    canvas->drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
                }
            }
            y += 8;
        }
        canvas->restore();
        canvas->translate(width, 0);
    }
}
