/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Paint.h"
#include "BlurDrawLooper.h"

namespace android {

Paint::Paint()
        : SkPaint()
        , mLetterSpacing(0)
        , mWordSpacing(0)
        , mFontFeatureSettings()
        , mMinikinLocaleListId(0)
        , mFamilyVariant(minikin::FamilyVariant::DEFAULT) {
    // SkPaint::antialiasing defaults to false, but
    // SkFont::edging defaults to kAntiAlias. To keep them
    // insync, we manually set the font to kAilas.
    mFont.setEdging(SkFont::Edging::kAlias);
}

Paint::Paint(const Paint& paint)
        : SkPaint(paint)
        , mFont(paint.mFont)
        , mLooper(paint.mLooper)
        , mLetterSpacing(paint.mLetterSpacing)
        , mWordSpacing(paint.mWordSpacing)
        , mFontFeatureSettings(paint.mFontFeatureSettings)
        , mMinikinLocaleListId(paint.mMinikinLocaleListId)
        , mFamilyVariant(paint.mFamilyVariant)
        , mHyphenEdit(paint.mHyphenEdit)
        , mTypeface(paint.mTypeface)
        , mAlign(paint.mAlign)
        , mFilterBitmap(paint.mFilterBitmap)
        , mStrikeThru(paint.mStrikeThru)
        , mUnderline(paint.mUnderline)
        , mDevKern(paint.mDevKern) {}


Paint::~Paint() {}

Paint& Paint::operator=(const Paint& other) {
    SkPaint::operator=(other);
    mFont = other.mFont;
    mLooper = other.mLooper;
    mLetterSpacing = other.mLetterSpacing;
    mWordSpacing = other.mWordSpacing;
    mFontFeatureSettings = other.mFontFeatureSettings;
    mMinikinLocaleListId = other.mMinikinLocaleListId;
    mFamilyVariant = other.mFamilyVariant;
    mHyphenEdit = other.mHyphenEdit;
    mTypeface = other.mTypeface;
    mAlign = other.mAlign;
    mFilterBitmap = other.mFilterBitmap;
    mStrikeThru = other.mStrikeThru;
    mUnderline = other.mUnderline;
    mDevKern = other.mDevKern;
    return *this;
}

bool operator==(const Paint& a, const Paint& b) {
    return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b) &&
           a.mFont == b.mFont &&
           a.mLooper == b.mLooper && 
           a.mLetterSpacing == b.mLetterSpacing && a.mWordSpacing == b.mWordSpacing &&
           a.mFontFeatureSettings == b.mFontFeatureSettings &&
           a.mMinikinLocaleListId == b.mMinikinLocaleListId &&
           a.mFamilyVariant == b.mFamilyVariant && a.mHyphenEdit == b.mHyphenEdit &&
           a.mTypeface == b.mTypeface && a.mAlign == b.mAlign &&
           a.mFilterBitmap == b.mFilterBitmap &&
           a.mStrikeThru == b.mStrikeThru && a.mUnderline == b.mUnderline &&
           a.mDevKern == b.mDevKern;
}

void Paint::reset() {
    SkPaint::reset();

    mFont = SkFont();
    mFont.setEdging(SkFont::Edging::kAlias);
    mLooper.reset();

    mFilterBitmap = false;
    mStrikeThru = false;
    mUnderline = false;
    mDevKern = false;
}

void Paint::setLooper(sk_sp<BlurDrawLooper> looper) {
    mLooper = std::move(looper);
}

void Paint::setAntiAlias(bool aa) {
    // Java does not support/understand subpixel(lcd) antialiasing
    SkASSERT(mFont.getEdging() != SkFont::Edging::kSubpixelAntiAlias);
    // JavaPaint antialiasing affects both the SkPaint and SkFont settings.
    SkPaint::setAntiAlias(aa);
    mFont.setEdging(aa ? SkFont::Edging::kAntiAlias : SkFont::Edging::kAlias);
}

////////////////// Java flags compatibility //////////////////

/*  Flags are tricky. Java has its own idea of the "paint" flags, but they don't really
    match up with skia anymore, so we have to do some shuffling in get/set flags()

	3 flags apply to SkPaint (antialias, dither, filter -> enum)
    5 flags (merged with antialias) are for SkFont
    2 flags are for minikin::Paint (underline and strikethru)
*/

// flags relating to SkPaint
static const uint32_t sAntiAliasFlag    = 0x01;   // affects paint and font-edging
static const uint32_t sFilterBitmapFlag = 0x02;   // maps to enum
static const uint32_t sDitherFlag       = 0x04;
// flags relating to SkFont
static const uint32_t sFakeBoldFlag     = 0x020;
static const uint32_t sLinearMetrics    = 0x040;
static const uint32_t sSubpixelMetrics  = 0x080;
static const uint32_t sEmbeddedBitmaps  = 0x400;
static const uint32_t sForceAutoHinting = 0x800;
// flags related to minikin::Paint
static const uint32_t sUnderlineFlag    = 0x08;
static const uint32_t sStrikeThruFlag   = 0x10;
// flags no longer supported on native side (but mirrored for compatibility)
static const uint32_t sDevKernFlag      = 0x100;

static uint32_t paintToLegacyFlags(const SkPaint& paint) {
    uint32_t flags = 0;
    flags |= -(int)paint.isAntiAlias() & sAntiAliasFlag;
    flags |= -(int)paint.isDither()    & sDitherFlag;
    return flags;
}

static uint32_t fontToLegacyFlags(const SkFont& font) {
    uint32_t flags = 0;
    flags |= -(int)font.isEmbolden()         & sFakeBoldFlag;
    flags |= -(int)font.isLinearMetrics()    & sLinearMetrics;
    flags |= -(int)font.isSubpixel()         & sSubpixelMetrics;
    flags |= -(int)font.isEmbeddedBitmaps()  & sEmbeddedBitmaps;
    flags |= -(int)font.isForceAutoHinting() & sForceAutoHinting;
    return flags;
}

static void applyLegacyFlagsToPaint(uint32_t flags, SkPaint* paint) {
    paint->setAntiAlias((flags & sAntiAliasFlag) != 0);
    paint->setDither   ((flags & sDitherFlag) != 0);
}

static void applyLegacyFlagsToFont(uint32_t flags, SkFont* font) {
    font->setEmbolden        ((flags & sFakeBoldFlag) != 0);
    font->setLinearMetrics   ((flags & sLinearMetrics) != 0);
    font->setSubpixel        ((flags & sSubpixelMetrics) != 0);
    font->setEmbeddedBitmaps ((flags & sEmbeddedBitmaps) != 0);
    font->setForceAutoHinting((flags & sForceAutoHinting) != 0);

    if (flags & sAntiAliasFlag) {
        font->setEdging(SkFont::Edging::kAntiAlias);
    } else {
        font->setEdging(SkFont::Edging::kAlias);
    }
}

uint32_t Paint::GetSkPaintJavaFlags(const SkPaint& paint) {
    return paintToLegacyFlags(paint);
}

void Paint::SetSkPaintJavaFlags(SkPaint* paint, uint32_t flags) {
    applyLegacyFlagsToPaint(flags, paint);
}

uint32_t Paint::getJavaFlags() const {
    uint32_t flags = paintToLegacyFlags(*this) | fontToLegacyFlags(mFont);
    flags |= -(int)mStrikeThru   & sStrikeThruFlag;
    flags |= -(int)mUnderline    & sUnderlineFlag;
    flags |= -(int)mDevKern      & sDevKernFlag;
    flags |= -(int)mFilterBitmap & sFilterBitmapFlag;
    return flags;
}

void Paint::setJavaFlags(uint32_t flags) {
    applyLegacyFlagsToPaint(flags, this);
    applyLegacyFlagsToFont(flags, &mFont);
    mStrikeThru   = (flags & sStrikeThruFlag) != 0;
    mUnderline    = (flags & sUnderlineFlag) != 0;
    mDevKern      = (flags & sDevKernFlag) != 0;
    mFilterBitmap = (flags & sFilterBitmapFlag) != 0;
}

}  // namespace android
