1#include "SkScalerContext.h"
2#include "SkBitmap.h"
3#include "SkCanvas.h"
4#include "SkDescriptor.h"
5#include "SkFDot6.h"
6#include "SkFontHost.h"
7#include "SkMask.h"
8#include "SkStream.h"
9#include "SkString.h"
10#include "SkThread.h"
11#include "SkTemplates.h"
12
13#include <acaapi.h>
14
15//////////////////////////////////////////////////////////////////////////
16
17#include "SkMMapStream.h"
18
19class SkScalerContext_Ascender : public SkScalerContext {
20public:
21    SkScalerContext_Ascender(const SkDescriptor* desc);
22    virtual ~SkScalerContext_Ascender();
23
24protected:
25    virtual unsigned generateGlyphCount();
26    virtual uint16_t generateCharToGlyph(SkUnichar uni);
27    virtual void generateMetrics(SkGlyph* glyph);
28    virtual void generateImage(const SkGlyph& glyph);
29    virtual void generatePath(const SkGlyph& glyph, SkPath* path);
30    virtual void generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my);
31
32private:
33    aca_FontHandle  fHandle;
34    void*   fWorkspace;
35    void*   fGlyphWorkspace;
36    SkStream*   fFontStream;
37    SkStream*   fHintStream;
38};
39
40///////////////////////////////////////////////////////////////////////////
41///////////////////////////////////////////////////////////////////////////
42
43SkScalerContext_Ascender::SkScalerContext_Ascender(const SkDescriptor* desc)
44    : SkScalerContext(desc)
45{
46    int size = aca_Get_FontHandleRec_Size();
47    fHandle = (aca_FontHandle)sk_malloc_throw(size);
48
49    // get the pointer to the font
50
51    fFontStream = new SkMMAPStream("/UcsGB2312-Hei-H.FDL");
52    fHintStream = new SkMMAPStream("/genv6-23.bin");
53
54    void* hints = sk_malloc_throw(fHintStream->getLength());
55    memcpy(hints, fHintStream->getMemoryBase(), fHintStream->getLength());
56
57    aca_Create_Font_Handle(fHandle,
58                           (void*)fFontStream->getMemoryBase(), fFontStream->getLength(),
59                           "fred",
60                           hints, fHintStream->getLength());
61
62    // compute our factors from the record
63
64    SkMatrix    m;
65
66    fRec.getSingleMatrix(&m);
67
68    //  now compute our scale factors
69    SkScalar    sx = m.getScaleX();
70    SkScalar    sy = m.getScaleY();
71
72    int ppemX = SkScalarRound(sx);
73    int ppemY = SkScalarRound(sy);
74
75    size = aca_Find_Font_Memory_Required(fHandle, ppemX, ppemY);
76    size *= 8;  // Jeff suggests this :)
77    fWorkspace = sk_malloc_throw(size);
78    aca_Set_Font_Memory(fHandle, (uint8_t*)fWorkspace, size);
79
80    aca_GlyphAttribsRec rec;
81
82    memset(&rec, 0, sizeof(rec));
83    rec.xSize = ppemX;
84    rec.ySize = ppemY;
85    rec.doAdjust = true;
86    rec.doExceptions = true;
87    rec.doGlyphHints = true;
88    rec.doInterpolate = true;
89    rec.grayMode = 2;
90    aca_Set_Font_Attributes(fHandle, &rec, &size);
91
92    fGlyphWorkspace = sk_malloc_throw(size);
93    aca_Set_Glyph_Memory(fHandle, fGlyphWorkspace);
94}
95
96SkScalerContext_Ascender::~SkScalerContext_Ascender()
97{
98    delete fHintStream;
99    delete fFontStream;
100    sk_free(fGlyphWorkspace);
101    sk_free(fWorkspace);
102    sk_free(fHandle);
103}
104
105unsigned SkScalerContext_Ascender::generateGlyphCount()
106{
107    return 1000;
108}
109
110uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni)
111{
112    return (uint16_t)(uni & 0xFFFF);
113}
114
115void SkScalerContext_Ascender::generateMetrics(SkGlyph* glyph)
116{
117    glyph->fRsbDelta = 0;
118    glyph->fLsbDelta = 0;
119
120    aca_GlyphImageRec   rec;
121    aca_Vector          topLeft;
122
123    int adv = aca_Get_Adv_Width(fHandle, glyph->getGlyphID());
124    if (aca_GLYPH_NOT_PRESENT == adv)
125        goto ERROR;
126
127    aca_Rasterize(glyph->getGlyphID(), fHandle, &rec, &topLeft);
128
129    if (false)  // error
130    {
131ERROR:
132        glyph->fWidth   = 0;
133        glyph->fHeight  = 0;
134        glyph->fTop     = 0;
135        glyph->fLeft    = 0;
136        glyph->fAdvanceX = 0;
137        glyph->fAdvanceY = 0;
138        return;
139    }
140
141    glyph->fWidth = rec.width;
142    glyph->fHeight = rec.rows;
143    glyph->fRowBytes = rec.width;
144    glyph->fTop = -topLeft.y;
145    glyph->fLeft = topLeft.x;
146    glyph->fAdvanceX = SkIntToFixed(adv);
147    glyph->fAdvanceY = SkIntToFixed(0);
148}
149
150void SkScalerContext_Ascender::generateImage(const SkGlyph& glyph)
151{
152    aca_GlyphImageRec   rec;
153    aca_Vector          topLeft;
154
155    aca_Rasterize(glyph.getGlyphID(), fHandle, &rec, &topLeft);
156
157    const uint8_t* src = (const uint8_t*)rec.buffer;
158    uint8_t* dst = (uint8_t*)glyph.fImage;
159    int height = glyph.fHeight;
160
161    src += rec.y0 * rec.pitch + rec.x0;
162    while (--height >= 0)
163    {
164        memcpy(dst, src, glyph.fWidth);
165        src += rec.pitch;
166        dst += glyph.fRowBytes;
167    }
168}
169
170///////////////////////////////////////////////////////////////////////////////////////////
171
172void SkScalerContext_Ascender::generatePath(const SkGlyph& glyph, SkPath* path)
173{
174    SkRect r;
175
176    r.set(0, 0, SkIntToScalar(4), SkIntToScalar(4));
177    path->reset();
178    path->addRect(r);
179}
180
181void SkScalerContext_Ascender::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my)
182{
183    if (NULL == mx && NULL == my)
184        return;
185
186    if (mx)
187    {
188        mx->fTop = SkIntToScalar(-16);
189        mx->fAscent = SkIntToScalar(-16);
190        mx->fDescent = SkIntToScalar(4);
191        mx->fBottom = SkIntToScalar(4);
192        mx->fLeading = 0;
193
194        // FIXME:
195        mx->fAvgCharWidth = 0;
196        mx->fXMin = 0;
197        mx->fXMax = 0;
198        mx->fXHeight = 0;
199    }
200    if (my)
201    {
202        my->fTop = SkIntToScalar(-16);
203        my->fAscent = SkIntToScalar(-16);
204        my->fDescent = SkIntToScalar(4);
205        my->fBottom = SkIntToScalar(4);
206        my->fLeading = 0;
207
208        // FIXME:
209        my->fAvgCharWidth = 0;
210        my->fXMin = 0;
211        my->fXMax = 0;
212        my->fXHeight = 0;
213    }
214}
215
216////////////////////////////////////////////////////////////////////////
217////////////////////////////////////////////////////////////////////////
218
219SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
220{
221    return SkNEW_ARGS(SkScalerContext_Ascender, (desc));
222}
223
224