• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 class SkScalerContext_Ascender : public SkScalerContext {
20 public:
21     SkScalerContext_Ascender(const SkDescriptor* desc);
22     virtual ~SkScalerContext_Ascender();
23 
24 protected:
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 
32 private:
33     aca_FontHandle  fHandle;
34     void*   fWorkspace;
35     void*   fGlyphWorkspace;
36     SkStream*   fFontStream;
37     SkStream*   fHintStream;
38 };
39 
40 ///////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////
42 
SkScalerContext_Ascender(const SkDescriptor * desc)43 SkScalerContext_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 
~SkScalerContext_Ascender()96 SkScalerContext_Ascender::~SkScalerContext_Ascender()
97 {
98     delete fHintStream;
99     delete fFontStream;
100     sk_free(fGlyphWorkspace);
101     sk_free(fWorkspace);
102     sk_free(fHandle);
103 }
104 
generateGlyphCount()105 unsigned SkScalerContext_Ascender::generateGlyphCount()
106 {
107     return 1000;
108 }
109 
generateCharToGlyph(SkUnichar uni)110 uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni)
111 {
112     return (uint16_t)(uni & 0xFFFF);
113 }
114 
generateMetrics(SkGlyph * glyph)115 void 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     {
131 ERROR:
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 
generateImage(const SkGlyph & glyph)150 void 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 
generatePath(const SkGlyph & glyph,SkPath * path)172 void 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 
generateFontMetrics(SkPaint::FontMetrics * mx,SkPaint::FontMetrics * my)181 void 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 
CreateScalerContext(const SkDescriptor * desc)219 SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
220 {
221     return SkNEW_ARGS(SkScalerContext_Ascender, (desc));
222 }
223 
224