1
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 */
8 #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
26 class SkScalerContext_Ascender : public SkScalerContext {
27 public:
28 SkScalerContext_Ascender(const SkDescriptor* desc);
29 virtual ~SkScalerContext_Ascender();
30
31 protected:
32 virtual unsigned generateGlyphCount();
33 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
39 private:
40 aca_FontHandle fHandle;
41 void* fWorkspace;
42 void* fGlyphWorkspace;
43 SkStream* fFontStream;
44 SkStream* fHintStream;
45 };
46
47 ///////////////////////////////////////////////////////////////////////////
48 ///////////////////////////////////////////////////////////////////////////
49
SkScalerContext_Ascender(const SkDescriptor * desc)50 SkScalerContext_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
~SkScalerContext_Ascender()103 SkScalerContext_Ascender::~SkScalerContext_Ascender()
104 {
105 delete fHintStream;
106 delete fFontStream;
107 sk_free(fGlyphWorkspace);
108 sk_free(fWorkspace);
109 sk_free(fHandle);
110 }
111
generateGlyphCount()112 unsigned SkScalerContext_Ascender::generateGlyphCount()
113 {
114 return 1000;
115 }
116
generateCharToGlyph(SkUnichar uni)117 uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni)
118 {
119 return (uint16_t)(uni & 0xFFFF);
120 }
121
generateMetrics(SkGlyph * glyph)122 void 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 {
138 ERROR:
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
generateImage(const SkGlyph & glyph)157 void 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
generatePath(const SkGlyph & glyph,SkPath * path)179 void 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
generateFontMetrics(SkPaint::FontMetrics * mx,SkPaint::FontMetrics * my)188 void 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;
200
201 // FIXME:
202 mx->fAvgCharWidth = 0;
203 mx->fXMin = 0;
204 mx->fXMax = 0;
205 mx->fXHeight = 0;
206 }
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;
214
215 // FIXME:
216 my->fAvgCharWidth = 0;
217 my->fXMin = 0;
218 my->fXMax = 0;
219 my->fXHeight = 0;
220 }
221 }
222
223 ////////////////////////////////////////////////////////////////////////
224 ////////////////////////////////////////////////////////////////////////
225
CreateScalerContext(const SkDescriptor * desc)226 SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
227 {
228 return SkNEW_ARGS(SkScalerContext_Ascender, (desc));
229 }
230
231