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