/*
 * Copyright 2011 Google Inc.
 *
 * 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/SkFont.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "src/core/SkFontDescriptor.h"
#include "tests/Test.h"

#include <memory>
#include <utility>

static const SkColor bgColor = SK_ColorWHITE;

static void create(SkBitmap* bm, SkIRect bound) {
    bm->allocN32Pixels(bound.width(), bound.height());
}

static void drawBG(SkCanvas* canvas) {
    canvas->drawColor(bgColor);
}

/** Assumes that the ref draw was completely inside ref canvas --
    implies that everything outside is "bgColor".
    Checks that all overlap is the same and that all non-overlap on the
    ref is "bgColor".
 */
static bool compare(const SkBitmap& ref, const SkIRect& iref,
                    const SkBitmap& test, const SkIRect& itest)
{
    const int xOff = itest.fLeft - iref.fLeft;
    const int yOff = itest.fTop - iref.fTop;

    for (int y = 0; y < test.height(); ++y) {
        for (int x = 0; x < test.width(); ++x) {
            SkColor testColor = test.getColor(x, y);
            int refX = x + xOff;
            int refY = y + yOff;
            SkColor refColor;
            if (refX >= 0 && refX < ref.width() &&
                refY >= 0 && refY < ref.height())
            {
                refColor = ref.getColor(refX, refY);
            } else {
                refColor = bgColor;
            }
            if (refColor != testColor) {
                return false;
            }
        }
    }
    return true;
}

DEF_TEST(FontHostStream, reporter) {
    {
        SkPaint paint;
        paint.setColor(SK_ColorGRAY);

        SkFont font(SkTypeface::MakeFromName("Georgia", SkFontStyle()), 30);
        font.setEdging(SkFont::Edging::kAlias);

        const SkIRect origRect = SkIRect::MakeWH(64, 64);
        SkBitmap origBitmap;
        create(&origBitmap, origRect);
        SkCanvas origCanvas(origBitmap);

        SkPoint point = SkPoint::Make(24, 32);

        // Test: origTypeface and streamTypeface from orig data draw the same
        drawBG(&origCanvas);
        origCanvas.drawString("A", point.fX, point.fY, font, paint);

        sk_sp<SkTypeface> typeface = font.refTypefaceOrDefault();

        {
            SkDynamicMemoryWStream wstream;
            typeface->serialize(&wstream, SkTypeface::SerializeBehavior::kDoIncludeData);
            std::unique_ptr<SkStreamAsset> stream = wstream.detachAsStream();
            sk_sp<SkTypeface> deserializedTypeface = SkTypeface::MakeDeserialize(&*stream);
            if (!deserializedTypeface) {
                REPORTER_ASSERT(reporter, deserializedTypeface);
                return;
            }

            SkFontDescriptor desc;
            bool mustSerializeData = false;
            deserializedTypeface->getFontDescriptor(&desc, &mustSerializeData);
            REPORTER_ASSERT(reporter, mustSerializeData);

            SkBitmap deserializedBitmap;
            create(&deserializedBitmap, origRect);
            SkCanvas deserializedCanvas(deserializedBitmap);

            font.setTypeface(deserializedTypeface);
            drawBG(&deserializedCanvas);
            deserializedCanvas.drawString("A", point.fX, point.fY, font, paint);

            REPORTER_ASSERT(reporter, compare(origBitmap, origRect, deserializedBitmap, origRect));
        }

        {
            int ttcIndex;
            std::unique_ptr<SkStreamAsset> fontData = typeface->openStream(&ttcIndex);
            if (!fontData) {
                REPORTER_ASSERT(reporter, fontData);
                return;
            }

            sk_sp<SkTypeface> streamTypeface(SkTypeface::MakeFromStream(std::move(fontData)));
            if (!streamTypeface) {
                // TODO: enable assert after SkTypeface::MakeFromStream uses factories
                //REPORTER_ASSERT(reporter, streamTypeface);
                return;
            }

            SkBitmap streamBitmap;
            create(&streamBitmap, origRect);
            SkCanvas streamCanvas(streamBitmap);

            SkFontDescriptor desc;
            bool mustSerializeData = false;
            streamTypeface->getFontDescriptor(&desc, &mustSerializeData);
            REPORTER_ASSERT(reporter, mustSerializeData);

            font.setTypeface(streamTypeface);
            drawBG(&streamCanvas);
            streamCanvas.drawString("A", point.fX, point.fY, font, paint);

            REPORTER_ASSERT(reporter, compare(origBitmap, origRect, streamBitmap, origRect));
        }
    }
    //Make sure the typeface is deleted and removed.
    SkGraphics::PurgeFontCache();
}
