Home | History | Annotate | Download | only in ports
      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