
/*
 * 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 "SkScalerContext.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkDescriptor.h"
#include "SkFDot6.h"
#include "SkFontHost.h"
#include "SkMask.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkThread.h"
#include "SkTemplates.h"

#include <acaapi.h>

//////////////////////////////////////////////////////////////////////////

#include "SkMMapStream.h"

class SkScalerContext_Ascender : public SkScalerContext {
public:
    SkScalerContext_Ascender(const SkDescriptor* desc);
    virtual ~SkScalerContext_Ascender();

protected:
    virtual unsigned generateGlyphCount();
    virtual uint16_t generateCharToGlyph(SkUnichar uni);
    virtual void generateMetrics(SkGlyph* glyph);
    virtual void generateImage(const SkGlyph& glyph);
    virtual void generatePath(const SkGlyph& glyph, SkPath* path);
    virtual void generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my);

private:
    aca_FontHandle  fHandle;
    void*   fWorkspace;
    void*   fGlyphWorkspace;
    SkStream*   fFontStream;
    SkStream*   fHintStream;
};

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

SkScalerContext_Ascender::SkScalerContext_Ascender(const SkDescriptor* desc)
    : SkScalerContext(desc)
{
    int size = aca_Get_FontHandleRec_Size();
    fHandle = (aca_FontHandle)sk_malloc_throw(size);

    // get the pointer to the font

    fFontStream = new SkMMAPStream("/UcsGB2312-Hei-H.FDL");
    fHintStream = new SkMMAPStream("/genv6-23.bin");

    void* hints = sk_malloc_throw(fHintStream->getLength());
    memcpy(hints, fHintStream->getMemoryBase(), fHintStream->getLength());

    aca_Create_Font_Handle(fHandle,
                           (void*)fFontStream->getMemoryBase(), fFontStream->getLength(),
                           "fred",
                           hints, fHintStream->getLength());

    // compute our factors from the record

    SkMatrix    m;

    fRec.getSingleMatrix(&m);

    //  now compute our scale factors
    SkScalar    sx = m.getScaleX();
    SkScalar    sy = m.getScaleY();

    int ppemX = SkScalarRound(sx);
    int ppemY = SkScalarRound(sy);

    size = aca_Find_Font_Memory_Required(fHandle, ppemX, ppemY);
    size *= 8;  // Jeff suggests this :)
    fWorkspace = sk_malloc_throw(size);
    aca_Set_Font_Memory(fHandle, (uint8_t*)fWorkspace, size);

    aca_GlyphAttribsRec rec;

    memset(&rec, 0, sizeof(rec));
    rec.xSize = ppemX;
    rec.ySize = ppemY;
    rec.doAdjust = true;
    rec.doExceptions = true;
    rec.doGlyphHints = true;
    rec.doInterpolate = true;
    rec.grayMode = 2;
    aca_Set_Font_Attributes(fHandle, &rec, &size);

    fGlyphWorkspace = sk_malloc_throw(size);
    aca_Set_Glyph_Memory(fHandle, fGlyphWorkspace);
}

SkScalerContext_Ascender::~SkScalerContext_Ascender()
{
    delete fHintStream;
    delete fFontStream;
    sk_free(fGlyphWorkspace);
    sk_free(fWorkspace);
    sk_free(fHandle);
}

unsigned SkScalerContext_Ascender::generateGlyphCount()
{
    return 1000;
}

uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni)
{
    return (uint16_t)(uni & 0xFFFF);
}

void SkScalerContext_Ascender::generateMetrics(SkGlyph* glyph)
{
    glyph->fRsbDelta = 0;
    glyph->fLsbDelta = 0;

    aca_GlyphImageRec   rec;
    aca_Vector          topLeft;

    int adv = aca_Get_Adv_Width(fHandle, glyph->getGlyphID());
    if (aca_GLYPH_NOT_PRESENT == adv)
        goto ERROR;

    aca_Rasterize(glyph->getGlyphID(), fHandle, &rec, &topLeft);

    if (false)  // error
    {
ERROR:
        glyph->fWidth   = 0;
        glyph->fHeight  = 0;
        glyph->fTop     = 0;
        glyph->fLeft    = 0;
        glyph->fAdvanceX = 0;
        glyph->fAdvanceY = 0;
        return;
    }

    glyph->fWidth = rec.width;
    glyph->fHeight = rec.rows;
    glyph->fRowBytes = rec.width;
    glyph->fTop = -topLeft.y;
    glyph->fLeft = topLeft.x;
    glyph->fAdvanceX = SkIntToFixed(adv);
    glyph->fAdvanceY = SkIntToFixed(0);
}

void SkScalerContext_Ascender::generateImage(const SkGlyph& glyph)
{
    aca_GlyphImageRec   rec;
    aca_Vector          topLeft;

    aca_Rasterize(glyph.getGlyphID(), fHandle, &rec, &topLeft);

    const uint8_t* src = (const uint8_t*)rec.buffer;
    uint8_t* dst = (uint8_t*)glyph.fImage;
    int height = glyph.fHeight;

    src += rec.y0 * rec.pitch + rec.x0;
    while (--height >= 0)
    {
        memcpy(dst, src, glyph.fWidth);
        src += rec.pitch;
        dst += glyph.fRowBytes;
    }
}

///////////////////////////////////////////////////////////////////////////////////////////

void SkScalerContext_Ascender::generatePath(const SkGlyph& glyph, SkPath* path)
{
    SkRect r;

    r.set(0, 0, SkIntToScalar(4), SkIntToScalar(4));
    path->reset();
    path->addRect(r);
}

void SkScalerContext_Ascender::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my)
{
    if (NULL == mx && NULL == my)
        return;

    if (mx)
    {
        mx->fTop = SkIntToScalar(-16);
        mx->fAscent = SkIntToScalar(-16);
        mx->fDescent = SkIntToScalar(4);
        mx->fBottom = SkIntToScalar(4);
        mx->fLeading = 0;

        // FIXME:
        mx->fAvgCharWidth = 0;
        mx->fXMin = 0;
        mx->fXMax = 0;
        mx->fXHeight = 0;
    }
    if (my)
    {
        my->fTop = SkIntToScalar(-16);
        my->fAscent = SkIntToScalar(-16);
        my->fDescent = SkIntToScalar(4);
        my->fBottom = SkIntToScalar(4);
        my->fLeading = 0;

        // FIXME:
        my->fAvgCharWidth = 0;
        my->fXMin = 0;
        my->fXMax = 0;
        my->fXHeight = 0;
    }
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
{
    return SkNEW_ARGS(SkScalerContext_Ascender, (desc));
}

