/*
 * Copyright (C) 2006-2009, 2013, 2016 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "FontCascade.h"

#if USE(CG)

#include "AffineTransform.h"
#include "FloatConversion.h"
#include "Font.h"
#include "GlyphBuffer.h"
#include "GraphicsContext.h"
#include "IntRect.h"
#include "WebCoreTextRenderer.h"
#include <pal/spi/cg/CoreGraphicsSPI.h>
#include <wtf/MathExtras.h>

namespace WebCore {

static inline CGFloat toCGFloat(FIXED f)
{
    return f.value + f.fract / CGFloat(65536.0);
}

static CGPathRef createPathForGlyph(HDC hdc, Glyph glyph)
{
    CGMutablePathRef path = CGPathCreateMutable();

    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    GLYPHMETRICS glyphMetrics;
    // GGO_NATIVE matches the outline perfectly when Windows font smoothing is off.
    // GGO_NATIVE | GGO_UNHINTED does not match perfectly either when Windows font smoothing is on or off.
    DWORD outlineLength = GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, 0, 0, &identity);
    ASSERT(outlineLength >= 0);
    if (outlineLength < 0)
        return path;

    Vector<UInt8> outline(outlineLength);
    GetGlyphOutline(hdc, glyph, GGO_GLYPH_INDEX | GGO_NATIVE, &glyphMetrics, outlineLength, outline.data(), &identity);

    unsigned offset = 0;
    while (offset < outlineLength) {
        LPTTPOLYGONHEADER subpath = reinterpret_cast<LPTTPOLYGONHEADER>(outline.data() + offset);
        ASSERT(subpath->dwType == TT_POLYGON_TYPE);
        if (subpath->dwType != TT_POLYGON_TYPE)
            return path;

        CGPathMoveToPoint(path, 0, toCGFloat(subpath->pfxStart.x), toCGFloat(subpath->pfxStart.y));

        unsigned subpathOffset = sizeof(*subpath);
        while (subpathOffset < subpath->cb) {
            LPTTPOLYCURVE segment = reinterpret_cast<LPTTPOLYCURVE>(reinterpret_cast<UInt8*>(subpath) + subpathOffset);
            switch (segment->wType) {
                case TT_PRIM_LINE:
                    for (unsigned i = 0; i < segment->cpfx; i++)
                        CGPathAddLineToPoint(path, 0, toCGFloat(segment->apfx[i].x), toCGFloat(segment->apfx[i].y));
                    break;

                case TT_PRIM_QSPLINE:
                    for (unsigned i = 0; i < segment->cpfx; i++) {
                        CGFloat x = toCGFloat(segment->apfx[i].x);
                        CGFloat y = toCGFloat(segment->apfx[i].y);
                        CGFloat cpx;
                        CGFloat cpy;

                        if (i == segment->cpfx - 2) {
                            cpx = toCGFloat(segment->apfx[i + 1].x);
                            cpy = toCGFloat(segment->apfx[i + 1].y);
                            i++;
                        } else {
                            cpx = (toCGFloat(segment->apfx[i].x) + toCGFloat(segment->apfx[i + 1].x)) / 2;
                            cpy = (toCGFloat(segment->apfx[i].y) + toCGFloat(segment->apfx[i + 1].y)) / 2;
                        }

                        CGPathAddQuadCurveToPoint(path, 0, x, y, cpx, cpy);
                    }
                    break;

                case TT_PRIM_CSPLINE:
                    for (unsigned i = 0; i < segment->cpfx; i += 3) {
                        CGFloat cp1x = toCGFloat(segment->apfx[i].x);
                        CGFloat cp1y = toCGFloat(segment->apfx[i].y);
                        CGFloat cp2x = toCGFloat(segment->apfx[i + 1].x);
                        CGFloat cp2y = toCGFloat(segment->apfx[i + 1].y);
                        CGFloat x = toCGFloat(segment->apfx[i + 2].x);
                        CGFloat y = toCGFloat(segment->apfx[i + 2].y);

                        CGPathAddCurveToPoint(path, 0, cp1x, cp1y, cp2x, cp2y, x, y);
                    }
                    break;

                default:
                    ASSERT_NOT_REACHED();
                    return path;
            }

            subpathOffset += sizeof(*segment) + (segment->cpfx - 1) * sizeof(segment->apfx[0]);
        }
        CGPathCloseSubpath(path);
        offset += subpath->cb;
    }
    return path;
}

void FontCascade::drawGlyphs(GraphicsContext& graphicsContext, const Font& font, const GlyphBuffer& glyphBuffer,
    unsigned from, unsigned numGlyphs, const FloatPoint& point, FontSmoothingMode smoothingMode)
{
    CGContextRef cgContext = graphicsContext.platformContext();
    bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();

    switch (smoothingMode) {
    case FontSmoothingMode::Antialiased: {
        graphicsContext.setShouldAntialias(true);
        shouldUseFontSmoothing = false;
        break;
    }
    case FontSmoothingMode::SubpixelAntialiased: {
        graphicsContext.setShouldAntialias(true);
        shouldUseFontSmoothing = true;
        break;
    }
    case FontSmoothingMode::NoSmoothing: {
        graphicsContext.setShouldAntialias(false);
        shouldUseFontSmoothing = false;
        break;
    }
    case FontSmoothingMode::AutoSmoothing: {
        // For the AutoSmooth case, don't do anything! Keep the default settings.
        break; 
    }
    default: 
        ASSERT_NOT_REACHED();
    }

    uint32_t oldFontSmoothingStyle = FontCascade::setFontSmoothingStyle(cgContext, shouldUseFontSmoothing);

    const FontPlatformData& platformData = font.platformData();

    CGContextSetFont(cgContext, platformData.cgFont());

    CGAffineTransform matrix = CGAffineTransformIdentity;
    matrix.b = -matrix.b;
    matrix.d = -matrix.d;

    if (platformData.syntheticOblique()) {
        static float skew = -tanf(syntheticObliqueAngle() * piFloat / 180.0f);
        matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
    }

    CGAffineTransform savedMatrix = CGContextGetTextMatrix(cgContext);
    CGContextSetTextMatrix(cgContext, matrix);

    CGContextSetFontSize(cgContext, platformData.size());
    FontCascade::setCGContextFontRenderingStyle(cgContext, font.platformData().isSystemFont(), false, font.platformData().useGDI());

    FloatSize shadowOffset;
    float shadowBlur;
    Color shadowColor;
    graphicsContext.getShadow(shadowOffset, shadowBlur, shadowColor);

    bool hasSimpleShadow = graphicsContext.textDrawingMode() == TextModeFill && shadowColor.isValid() && !shadowBlur && (!graphicsContext.shadowsIgnoreTransforms() || graphicsContext.getCTM().isIdentityOrTranslationOrFlipped());
    if (hasSimpleShadow) {
        // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
        graphicsContext.clearShadow();
        Color fillColor = graphicsContext.fillColor();
        Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
        graphicsContext.setFillColor(shadowFillColor);
        float shadowTextX = point.x() + shadowOffset.width();
        // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
        float shadowTextY = point.y() + shadowOffset.height() * (graphicsContext.shadowsIgnoreTransforms() ? -1 : 1);
        CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
        if (font.syntheticBoldOffset()) {
            CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width() + font.syntheticBoldOffset(), point.y() + shadowOffset.height());
            CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
        }
        graphicsContext.setFillColor(fillColor);
    }

    CGContextSetTextPosition(cgContext, point.x(), point.y());
    CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
    if (font.syntheticBoldOffset()) {
        CGContextSetTextPosition(cgContext, point.x() + font.syntheticBoldOffset(), point.y());
        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), static_cast<const CGSize*>(glyphBuffer.advances(from)), numGlyphs);
    }

    if (hasSimpleShadow)
        graphicsContext.setShadow(shadowOffset, shadowBlur, shadowColor);

    FontCascade::setFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
    CGContextSetTextMatrix(cgContext, savedMatrix);
}

constexpr uint32_t kCGFontSmoothingStyleMinimum = (1 << 4);
constexpr uint32_t kCGFontSmoothingStyleLight = (2 << 4);
constexpr uint32_t kCGFontSmoothingStyleMedium = (3 << 4);
constexpr uint32_t kCGFontSmoothingStyleHeavy = (4 << 4);

constexpr int fontSmoothingLevelMedium = 2;
constexpr CGFloat antialiasingGamma = 2.3;

double FontCascade::s_fontSmoothingContrast = 2;
uint32_t FontCascade::s_fontSmoothingType = kCGFontSmoothingStyleMedium;
int FontCascade::s_fontSmoothingLevel = fontSmoothingLevelMedium;
bool FontCascade::s_systemFontSmoothingEnabled;
uint32_t FontCascade::s_systemFontSmoothingType;
bool FontCascade::s_systemFontSmoothingSet;

void FontCascade::setFontSmoothingLevel(int level)
{
    const uint32_t smoothingType[] = { 
        0, // FontSmoothingTypeStandard
        kCGFontSmoothingStyleLight, // FontSmoothingTypeLight
        kCGFontSmoothingStyleMedium, // FontSmoothingTypeMedium
        kCGFontSmoothingStyleHeavy, // FontSmoothingTypeStrong
    };

    if (level < 0 || static_cast<size_t>(level) > ARRAYSIZE(smoothingType))
        return;

    s_fontSmoothingType = smoothingType[level];
    s_fontSmoothingLevel = level;
}

static void setCGFontSmoothingStyle(CGContextRef cgContext, uint32_t smoothingType, bool fontAllowsSmoothing = true)
{
    if (smoothingType) {
        CGContextSetShouldSmoothFonts(cgContext, fontAllowsSmoothing);
        CGContextSetFontSmoothingStyle(cgContext, smoothingType);
    } else
        CGContextSetShouldSmoothFonts(cgContext, false);
}

uint32_t FontCascade::setFontSmoothingStyle(CGContextRef cgContext, bool fontAllowsSmoothing)
{
    uint32_t oldFontSmoothingStyle = 0;
    if (CGContextGetShouldSmoothFonts(cgContext))
        oldFontSmoothingStyle = CGContextGetFontSmoothingStyle(cgContext);
    setCGFontSmoothingStyle(cgContext, s_fontSmoothingType, fontAllowsSmoothing);

    return oldFontSmoothingStyle;
}

void FontCascade::setFontSmoothingContrast(CGFloat contrast)
{
    s_fontSmoothingContrast = contrast;
}

static float clearTypeContrast()
{
    const WCHAR referenceCharacter = '\\';
    static UINT lastContrast = 2000;
    static float gamma = 2;
    UINT contrast;

    if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0) || contrast == lastContrast)
        return gamma;

    lastContrast = contrast;

    auto dc = adoptGDIObject(::CreateCompatibleDC(0));

    HGDIOBJ oldHFONT = ::SelectObject(dc.get(), GetStockObject(DEFAULT_GUI_FONT));
    GLYPHMETRICS glyphMetrics;

    static const MAT2 identity = { 0, 1,  0, 0,  0, 0,  0, 1 };
    if (::GetGlyphOutline(dc.get(), referenceCharacter, GGO_METRICS, &glyphMetrics, 0, 0, &identity) == GDI_ERROR)
        return contrast / 1000.0f;

    BITMAPINFO bitmapInfo;
    bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitmapInfo.bmiHeader.biPlanes = 1;
    bitmapInfo.bmiHeader.biCompression = BI_RGB;
    bitmapInfo.bmiHeader.biSizeImage = 0;
    bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
    bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
    bitmapInfo.bmiHeader.biClrImportant = 0;
    bitmapInfo.bmiHeader.biWidth = glyphMetrics.gmBlackBoxX;
    bitmapInfo.bmiHeader.biHeight = -static_cast<int>(glyphMetrics.gmBlackBoxY);
    bitmapInfo.bmiHeader.biBitCount = 32;
    bitmapInfo.bmiHeader.biClrUsed = 0;

    uint8_t* pixels = nullptr;
    auto bitmap = adoptGDIObject(::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast<void**>(&pixels), 0, 0));
    if (!bitmap)
        return contrast / 1000.0f;

    HGDIOBJ oldBitmap = ::SelectObject(dc.get(), bitmap.get());

    BITMAP bmpInfo;
    ::GetObject(bitmap.get(), sizeof(bmpInfo), &bmpInfo);
    memset(pixels, 0, glyphMetrics.gmBlackBoxY * bmpInfo.bmWidthBytes);

    ::SetBkMode(dc.get(), OPAQUE);
    ::SetTextAlign(dc.get(), TA_LEFT | TA_TOP);

    ::SetTextColor(dc.get(), RGB(255, 255, 255));
    ::SetBkColor(dc.get(), RGB(0, 0, 0));
    ::ExtTextOutW(dc.get(), 0, 0, 0, 0, &referenceCharacter, 1, 0);

    uint8_t* referencePixel = nullptr;
    uint8_t whiteReferenceValue = 0;
    for (size_t i = 0; i < glyphMetrics.gmBlackBoxY && !referencePixel; ++i) {
        for (size_t j = 0; j < 4 * glyphMetrics.gmBlackBoxX; ++j) {
            whiteReferenceValue = pixels[i * bmpInfo.bmWidthBytes + j];
            // Look for a pixel value in the range that allows us to estimate
            // gamma within 0.1 without an error.
            if (whiteReferenceValue > 32 && whiteReferenceValue < 240) {
                referencePixel = pixels + i * bmpInfo.bmWidthBytes + j;
                break;
            }
        }
    }

    if (referencePixel) {
        ::SetTextColor(dc.get(), RGB(0, 0, 0));
        ::SetBkColor(dc.get(), RGB(255, 255, 255));
        ::ExtTextOutW(dc.get(), 0, 0, 0, 0, &referenceCharacter, 1, 0);
        uint8_t blackReferenceValue = *referencePixel;

        float minDelta = 1;
        for (float g = 1; g < 2.3f; g += 0.1f) {
            float delta = fabs(powf((whiteReferenceValue / 255.0f), g) + powf((blackReferenceValue / 255.0f), g) - 1);
            if (delta < minDelta) {
                minDelta = delta;
                gamma = g;
            }
        }
    } else
        gamma = contrast / 1000.0f;

    ::SelectObject(dc.get(), oldBitmap);
    ::SelectObject(dc.get(), oldHFONT);

    return gamma;
}

void FontCascade::systemFontSmoothingChanged()
{
    ::SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &s_systemFontSmoothingEnabled, 0);
    ::SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &s_systemFontSmoothingType, 0);
    s_fontSmoothingContrast = clearTypeContrast();
    s_systemFontSmoothingSet = true;
}

void FontCascade::setCGContextFontRenderingStyle(CGContextRef cgContext, bool isSystemFont, bool /*isPrinterFont*/, bool usePlatformNativeGlyphs)
{
    bool shouldAntialias = true;
    bool maySubpixelPosition = true;
    CGFloat contrast = 2;
    if (usePlatformNativeGlyphs) {
        // <rdar://6564501> GDI can't subpixel-position, so don't bother asking.
        maySubpixelPosition = false;
        if (!s_systemFontSmoothingSet)
            systemFontSmoothingChanged();
        contrast = s_fontSmoothingContrast;
        shouldAntialias = s_systemFontSmoothingEnabled;
        if (s_systemFontSmoothingType == FE_FONTSMOOTHINGSTANDARD) {
            CGContextSetFontSmoothingStyle(cgContext, kCGFontSmoothingStyleMinimum);
            contrast = antialiasingGamma;
        }
    }
    CGContextSetFontSmoothingContrast(cgContext, contrast);
    CGContextSetShouldUsePlatformNativeGlyphs(cgContext, usePlatformNativeGlyphs);
    CGContextSetShouldAntialiasFonts(cgContext, shouldAntialias);
    CGAffineTransform contextTransform = CGContextGetCTM(cgContext);
    bool isPureTranslation = contextTransform.a == 1 && (contextTransform.d == 1 || contextTransform.d == -1) && !contextTransform.b && !contextTransform.c;
    CGContextSetShouldSubpixelPositionFonts(cgContext, maySubpixelPosition && (isSystemFont || !isPureTranslation));
    CGContextSetShouldSubpixelQuantizeFonts(cgContext, isPureTranslation);
}

static inline CGFontRenderingStyle renderingStyleForFont(bool isSystemFont, bool isPrinterFont)
{
    // FIXME: Need to support a minimum antialiased font size.

    if (isSystemFont || isPrinterFont)
        return kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization;

    return kCGFontRenderingStyleAntialiasing;
}

void FontCascade::getPlatformGlyphAdvances(CGFontRef font, const CGAffineTransform& m, bool isSystemFont, bool isPrinterFont, CGGlyph glyph, CGSize& advance)
{
    CGFontRenderingStyle style = renderingStyleForFont(isSystemFont, isPrinterFont);
    CGFontGetGlyphAdvancesForStyle(font, &m, style, &glyph, 1, &advance);

    // <rdar://problem/7761165> The GDI back end in Core Graphics sometimes returns advances that
    // differ from what the font's hmtx table specifies. The following code corrects that.
    CFDataRef hmtxTable = CGFontCopyTableForTag(font, 'hmtx');
    if (!hmtxTable)
        return;
    CFDataRef hheaTable = CGFontCopyTableForTag(font, 'hhea');
    if (!hheaTable) {
        CFRelease(hmtxTable);
        return;
    }

    const CFIndex hheaTableSize = 36;
    const ptrdiff_t hheaTableNumberOfHMetricsOffset = 34;
    if (CFDataGetLength(hheaTable) < hheaTableSize) {
        CFRelease(hmtxTable);
        CFRelease(hheaTable);
        return;
    }

    unsigned short numberOfHMetrics = *reinterpret_cast<const unsigned short*>(CFDataGetBytePtr(hheaTable) + hheaTableNumberOfHMetricsOffset);
    numberOfHMetrics = ((numberOfHMetrics & 0xFF) << 8) | (numberOfHMetrics >> 8);
    if (!numberOfHMetrics) {
        CFRelease(hmtxTable);
        CFRelease(hheaTable);
        return;
    }

    if (glyph >= numberOfHMetrics)
        glyph = numberOfHMetrics - 1;

    if (CFDataGetLength(hmtxTable) < 4 * (glyph + 1)) {
        CFRelease(hmtxTable);
        CFRelease(hheaTable);
        return;
    }

    unsigned short advanceInDesignUnits = *reinterpret_cast<const unsigned short*>(CFDataGetBytePtr(hmtxTable) + 4 * glyph);
    advanceInDesignUnits = ((advanceInDesignUnits & 0xFF) << 8) | (advanceInDesignUnits >> 8);
    CGSize horizontalAdvance = CGSizeMake(static_cast<CGFloat>(advanceInDesignUnits) / CGFontGetUnitsPerEm(font), 0);
    horizontalAdvance = CGSizeApplyAffineTransform(horizontalAdvance, m);
    advance.width = horizontalAdvance.width;
    if (!(style & kCGFontRenderingStyleSubpixelPositioning))
        advance.width = roundf(advance.width);

    CFRelease(hheaTable);
    CFRelease(hmtxTable);
}

}

#endif
