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 26class SkScalerContext_Ascender : public SkScalerContext { 27public: 28 SkScalerContext_Ascender(const SkDescriptor* desc); 29 virtual ~SkScalerContext_Ascender(); 30 31protected: 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 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 112unsigned SkScalerContext_Ascender::generateGlyphCount() 113{ 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; 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 226SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) 227{ 228 return SkNEW_ARGS(SkScalerContext_Ascender, (desc)); 229} 230 231