• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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