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 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 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 112 unsigned SkScalerContext_Ascender::generateGlyphCount() 113 { 114 return 1000; 115 } 116 117 uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni) 118 { 119 return (uint16_t)(uni & 0xFFFF); 120 } 121 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 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 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 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 226 SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) 227 { 228 return SkNEW_ARGS(SkScalerContext_Ascender, (desc)); 229 } 230 231