/*
 *******************************************************************************
 *
 *   © 2016 and later: Unicode, Inc. and others.
 *   License & terms of use: http://www.unicode.org/copyright.html#License
 *
 *******************************************************************************
 *******************************************************************************
 *
 *   Copyright (C) 1999-2007, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
 *   file name:  GnomeFontInstance.cpp
 *
 *   created on: 08/30/2001
 *   created by: Eric R. Mader
 */

#include <gnome.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_RENDER_H
#include FT_TRUETYPE_TABLES_H
#include <cairo.h>
#include <cairo-ft.h>

#include "layout/LETypes.h"
#include "layout/LESwaps.h"

#include "GnomeFontInstance.h"
#include "sfnt.h"
#include "cmaps.h"

GnomeSurface::GnomeSurface(GtkWidget *theWidget)
    : fWidget(theWidget)
{
    fCairo = gdk_cairo_create(fWidget->window);
}

GnomeSurface::~GnomeSurface()
{
    cairo_destroy(fCairo);
}

void GnomeSurface::drawGlyphs(const LEFontInstance *font, const LEGlyphID *glyphs, le_int32 count,
                              const float *positions, le_int32 x, le_int32 y, le_int32 /*width*/, le_int32 /*height*/)
{
    GnomeFontInstance *gFont = (GnomeFontInstance *) font;
    
    gFont->rasterizeGlyphs(fCairo, glyphs, count, positions, x, y);
}

GnomeFontInstance::GnomeFontInstance(FT_Library engine, const char *fontPathName, le_int16 pointSize, LEErrorCode &status)
    : FontTableCache(), fPointSize(pointSize), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
      fDeviceScaleX(1), fDeviceScaleY(1), fMapper(NULL)
{
    FT_Error error;

    fFace      = NULL;
    fCairoFace = NULL;

    error = FT_New_Face(engine, fontPathName, 0, &fFace);

    if (error != 0) {
        printf("OOPS! Got error code %d\n", error);
        status = LE_FONT_FILE_NOT_FOUND_ERROR;
        return;
    }

    // FIXME: what about the display resolution?
    fDeviceScaleX = ((float) 96) / 72;
    fDeviceScaleY = ((float) 96) / 72;

    error = FT_Set_Char_Size(fFace, 0, pointSize << 6, 92, 92);
    
    fCairoFace = cairo_ft_font_face_create_for_ft_face(fFace, 0);

    fUnitsPerEM = fFace->units_per_EM;

    fAscent  = (le_int32) (yUnitsToPoints(fFace->ascender) * fDeviceScaleY);
    fDescent = (le_int32) -(yUnitsToPoints(fFace->descender) * fDeviceScaleY);
    fLeading = (le_int32) (yUnitsToPoints(fFace->height) * fDeviceScaleY) - fAscent - fDescent;

    // printf("Face = %s, unitsPerEM = %d, ascent = %d, descent = %d\n", fontPathName, fUnitsPerEM, fAscent, fDescent);

    if (error != 0) {
        status = LE_MEMORY_ALLOCATION_ERROR;
        return;
    }

    status = initMapper();
}

GnomeFontInstance::~GnomeFontInstance()
{
    cairo_font_face_destroy(fCairoFace);
    
    if (fFace != NULL) {
        FT_Done_Face(fFace);
    }
}

LEErrorCode GnomeFontInstance::initMapper()
{
    LETag cmapTag = LE_CMAP_TABLE_TAG;
    const CMAPTable *cmap = (const CMAPTable *) readFontTable(cmapTag);

    if (cmap == NULL) {
        return LE_MISSING_FONT_TABLE_ERROR;
    }

    fMapper = CMAPMapper::createUnicodeMapper(cmap);

    if (fMapper == NULL) {
        return LE_MISSING_FONT_TABLE_ERROR;
    }

    return LE_NO_ERROR;
}

const void *GnomeFontInstance::getFontTable(LETag tableTag) const
{
    return FontTableCache::find(tableTag);
}

const void *GnomeFontInstance::readFontTable(LETag tableTag) const
{
    FT_ULong len = 0;
    FT_Byte *result = NULL;

    FT_Load_Sfnt_Table(fFace, tableTag, 0, NULL, &len);

    if (len > 0) {
        result = LE_NEW_ARRAY(FT_Byte, len);
        FT_Load_Sfnt_Table(fFace, tableTag, 0, result, &len);
    }

    return result;
}

void GnomeFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
{
    advance.fX = 0;
    advance.fY = 0;

    if (glyph >= 0xFFFE) {
        return;
    }

    FT_Error error;

    error = FT_Load_Glyph(fFace, glyph, FT_LOAD_DEFAULT);

    if (error != 0) {
        return;
    }

    advance.fX = fFace->glyph->metrics.horiAdvance >> 6;
    return;
}

le_bool GnomeFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const
{
    FT_Error error;

    error = FT_Load_Glyph(fFace, glyph, FT_LOAD_DEFAULT);

    if (error != 0) {
        return FALSE;
    }

    if (pointNumber >= fFace->glyph->outline.n_points) {
        return FALSE;
    }

    point.fX = fFace->glyph->outline.points[pointNumber].x >> 6;
    point.fY = fFace->glyph->outline.points[pointNumber].y >> 6;

    return TRUE;
}

void GnomeFontInstance::rasterizeGlyphs(cairo_t *cairo, const LEGlyphID *glyphs, le_int32 glyphCount, const float *positions,
                                        le_int32 x, le_int32 y) const
{
    cairo_glyph_t *glyph_t = LE_NEW_ARRAY(cairo_glyph_t, glyphCount);
    le_int32 in, out;
    
    for (in = 0, out = 0; in < glyphCount; in += 1) {
        TTGlyphID glyph = LE_GET_GLYPH(glyphs[in]);
        
        if (glyph < 0xFFFE) {
            glyph_t[out].index = glyph;
            glyph_t[out].x     = x + positions[in*2];
            glyph_t[out].y     = y + positions[in*2 + 1];
            
            out += 1;
        }
    }
    
    cairo_set_font_face(cairo, fCairoFace);
    cairo_set_font_size(cairo, getXPixelsPerEm() * getScaleFactorX());
    cairo_show_glyphs(cairo, glyph_t, out);
    
    LE_DELETE_ARRAY(glyph_t);
}
