diff options
Diffstat (limited to 'skia/ports/SkFontHost_ascender.cpp')
-rw-r--r-- | skia/ports/SkFontHost_ascender.cpp | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/skia/ports/SkFontHost_ascender.cpp b/skia/ports/SkFontHost_ascender.cpp new file mode 100644 index 0000000..2148850 --- /dev/null +++ b/skia/ports/SkFontHost_ascender.cpp @@ -0,0 +1,211 @@ +#include "SkScalerContext.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkDescriptor.h" +#include "SkFDot6.h" +#include "SkFontHost.h" +#include "SkMask.h" +#include "SkStream.h" +#include "SkString.h" +#include "SkThread.h" +#include "SkTemplates.h" + +#include <acaapi.h> + +////////////////////////////////////////////////////////////////////////// + +#include "SkMMapStream.h" + +class SkScalerContext_Ascender : public SkScalerContext { +public: + SkScalerContext_Ascender(const SkDescriptor* desc); + virtual ~SkScalerContext_Ascender(); + +protected: + virtual unsigned generateGlyphCount() const; + virtual uint16_t generateCharToGlyph(SkUnichar uni); + virtual void generateMetrics(SkGlyph* glyph); + virtual void generateImage(const SkGlyph& glyph); + virtual void generatePath(const SkGlyph& glyph, SkPath* path); + virtual void generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my); + +private: + aca_FontHandle fHandle; + void* fWorkspace; + void* fGlyphWorkspace; + SkStream* fFontStream; + SkStream* fHintStream; +}; + +/////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// + +SkScalerContext_Ascender::SkScalerContext_Ascender(const SkDescriptor* desc) + : SkScalerContext(desc) +{ + int size = aca_Get_FontHandleRec_Size(); + fHandle = (aca_FontHandle)sk_malloc_throw(size); + + // get the pointer to the font + + fFontStream = new SkMMAPStream("/UcsGB2312-Hei-H.FDL"); + fHintStream = new SkMMAPStream("/genv6-23.bin"); + + void* hints = sk_malloc_throw(fHintStream->getLength()); + memcpy(hints, fHintStream->getMemoryBase(), fHintStream->getLength()); + + aca_Create_Font_Handle(fHandle, + (void*)fFontStream->getMemoryBase(), fFontStream->getLength(), + "fred", + hints, fHintStream->getLength()); + + // compute our factors from the record + + SkMatrix m; + + fRec.getSingleMatrix(&m); + + // now compute our scale factors + SkScalar sx = m.getScaleX(); + SkScalar sy = m.getScaleY(); + + int ppemX = SkScalarRound(sx); + int ppemY = SkScalarRound(sy); + + size = aca_Find_Font_Memory_Required(fHandle, ppemX, ppemY); + size *= 8; // Jeff suggests this :) + fWorkspace = sk_malloc_throw(size); + aca_Set_Font_Memory(fHandle, (uint8_t*)fWorkspace, size); + + aca_GlyphAttribsRec rec; + + memset(&rec, 0, sizeof(rec)); + rec.xSize = ppemX; + rec.ySize = ppemY; + rec.doAdjust = true; + rec.doExceptions = true; + rec.doGlyphHints = true; + rec.doInterpolate = true; + rec.grayMode = 2; + aca_Set_Font_Attributes(fHandle, &rec, &size); + + fGlyphWorkspace = sk_malloc_throw(size); + aca_Set_Glyph_Memory(fHandle, fGlyphWorkspace); +} + +SkScalerContext_Ascender::~SkScalerContext_Ascender() +{ + delete fHintStream; + delete fFontStream; + sk_free(fGlyphWorkspace); + sk_free(fWorkspace); + sk_free(fHandle); +} + +unsigned SkScalerContext_Ascender::generateGlyphCount() const +{ + return 1000; +} + +uint16_t SkScalerContext_Ascender::generateCharToGlyph(SkUnichar uni) +{ + return (uint16_t)(uni & 0xFFFF); +} + +void SkScalerContext_Ascender::generateMetrics(SkGlyph* glyph) +{ + glyph->fRsbDelta = 0; + glyph->fLsbDelta = 0; + + aca_GlyphImageRec rec; + aca_Vector topLeft; + + int adv = aca_Get_Adv_Width(fHandle, glyph->getGlyphID()); + if (aca_GLYPH_NOT_PRESENT == adv) + goto ERROR; + + aca_Rasterize(glyph->getGlyphID(), fHandle, &rec, &topLeft); + + if (false) // error + { +ERROR: + glyph->fWidth = 0; + glyph->fHeight = 0; + glyph->fTop = 0; + glyph->fLeft = 0; + glyph->fAdvanceX = 0; + glyph->fAdvanceY = 0; + return; + } + + glyph->fWidth = rec.width; + glyph->fHeight = rec.rows; + glyph->fRowBytes = rec.width; + glyph->fTop = -topLeft.y; + glyph->fLeft = topLeft.x; + glyph->fAdvanceX = SkIntToFixed(adv); + glyph->fAdvanceY = SkIntToFixed(0); +} + +void SkScalerContext_Ascender::generateImage(const SkGlyph& glyph) +{ + aca_GlyphImageRec rec; + aca_Vector topLeft; + + aca_Rasterize(glyph.getGlyphID(), fHandle, &rec, &topLeft); + + const uint8_t* src = (const uint8_t*)rec.buffer; + uint8_t* dst = (uint8_t*)glyph.fImage; + int height = glyph.fHeight; + + src += rec.y0 * rec.pitch + rec.x0; + while (--height >= 0) + { + memcpy(dst, src, glyph.fWidth); + src += rec.pitch; + dst += glyph.fRowBytes; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////// + +void SkScalerContext_Ascender::generatePath(const SkGlyph& glyph, SkPath* path) +{ + SkRect r; + + r.set(0, 0, SkIntToScalar(4), SkIntToScalar(4)); + path->reset(); + path->addRect(r); +} + +void SkScalerContext_Ascender::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) +{ + if (NULL == mx && NULL == my) + return; + + if (mx) + { + mx->fTop = SkIntToScalar(-16); + mx->fAscent = SkIntToScalar(-16); + mx->fDescent = SkIntToScalar(4); + mx->fBottom = SkIntToScalar(4); + mx->fLeading = 0; + } + if (my) + { + my->fTop = SkIntToScalar(-16); + my->fAscent = SkIntToScalar(-16); + my->fDescent = SkIntToScalar(4); + my->fBottom = SkIntToScalar(4); + my->fLeading = 0; + } +} + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) +{ + return SkNEW_ARGS(SkScalerContext_Ascender, (desc)); +} + |