SkFontHost_FreeType.cpp revision e7f3300f4250cbe308651f59c992edf6b779a24d
1
2/*
3 * Copyright 2006 The Android Open Source Project
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
9
10#include "SkBitmap.h"
11#include "SkCanvas.h"
12#include "SkColorPriv.h"
13#include "SkDescriptor.h"
14#include "SkFDot6.h"
15#include "SkFontHost.h"
16#include "SkMask.h"
17#include "SkAdvancedTypefaceMetrics.h"
18#include "SkScalerContext.h"
19#include "SkStream.h"
20#include "SkString.h"
21#include "SkTemplates.h"
22#include "SkThread.h"
23
24#include <ft2build.h>
25#include FT_FREETYPE_H
26#include FT_OUTLINE_H
27#include FT_SIZES_H
28#include FT_TRUETYPE_TABLES_H
29#include FT_TYPE1_TABLES_H
30#include FT_BITMAP_H
31// In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file.
32#include FT_SYNTHESIS_H
33#include FT_XFREE86_H
34#ifdef FT_LCD_FILTER_H
35#include FT_LCD_FILTER_H
36#endif
37
38#ifdef   FT_ADVANCES_H
39#include FT_ADVANCES_H
40#endif
41
42#if 0
43// Also include the files by name for build tools which require this.
44#include <freetype/freetype.h>
45#include <freetype/ftoutln.h>
46#include <freetype/ftsizes.h>
47#include <freetype/tttables.h>
48#include <freetype/ftadvanc.h>
49#include <freetype/ftlcdfil.h>
50#include <freetype/ftbitmap.h>
51#include <freetype/ftsynth.h>
52#endif
53
54//#define ENABLE_GLYPH_SPEW     // for tracing calls
55//#define DUMP_STRIKE_CREATION
56
57#ifdef SK_DEBUG
58    #define SkASSERT_CONTINUE(pred)                                                         \
59        do {                                                                                \
60            if (!(pred))                                                                    \
61                SkDebugf("file %s:%d: assert failed '" #pred "'\n", __FILE__, __LINE__);    \
62        } while (false)
63#else
64    #define SkASSERT_CONTINUE(pred)
65#endif
66
67using namespace skia_advanced_typeface_metrics_utils;
68
69// SK_FREETYPE_LCD_LERP should be 0...256
70//   0 means no color reduction (e.g. just as returned from FreeType)
71//   256 means 100% color reduction (e.g. gray)
72//
73#ifndef SK_FREETYPE_LCD_LERP
74    #define SK_FREETYPE_LCD_LERP    96
75#endif
76
77static bool isLCD(const SkScalerContext::Rec& rec) {
78    switch (rec.fMaskFormat) {
79        case SkMask::kLCD16_Format:
80        case SkMask::kLCD32_Format:
81            return true;
82        default:
83            return false;
84    }
85}
86
87//////////////////////////////////////////////////////////////////////////
88
89struct SkFaceRec;
90
91static SkMutex      gFTMutex;
92static int          gFTCount;
93static FT_Library   gFTLibrary;
94static SkFaceRec*   gFaceRecHead;
95static bool         gLCDSupportValid;  // true iff |gLCDSupport| has been set.
96static bool         gLCDSupport;  // true iff LCD is supported by the runtime.
97
98/////////////////////////////////////////////////////////////////////////
99
100// See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
101// This value was chosen by eyeballing the result in Firefox and trying to match it.
102static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
103
104static bool
105InitFreetype() {
106    FT_Error err = FT_Init_FreeType(&gFTLibrary);
107    if (err) {
108        return false;
109    }
110
111    // Setup LCD filtering. This reduces colour fringes for LCD rendered
112    // glyphs.
113#ifdef FT_LCD_FILTER_H
114    err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT);
115    gLCDSupport = err == 0;
116#else
117    gLCDSupport = false;
118#endif
119    gLCDSupportValid = true;
120
121    return true;
122}
123
124class SkScalerContext_FreeType : public SkScalerContext {
125public:
126    SkScalerContext_FreeType(const SkDescriptor* desc);
127    virtual ~SkScalerContext_FreeType();
128
129    bool success() const {
130        return fFaceRec != NULL &&
131               fFTSize != NULL &&
132               fFace != NULL;
133    }
134
135protected:
136    virtual unsigned generateGlyphCount();
137    virtual uint16_t generateCharToGlyph(SkUnichar uni);
138    virtual void generateAdvance(SkGlyph* glyph);
139    virtual void generateMetrics(SkGlyph* glyph);
140    virtual void generateImage(const SkGlyph& glyph);
141    virtual void generatePath(const SkGlyph& glyph, SkPath* path);
142    virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
143                                     SkPaint::FontMetrics* my);
144    virtual SkUnichar generateGlyphToChar(uint16_t glyph);
145
146private:
147    SkFaceRec*  fFaceRec;
148    FT_Face     fFace;              // reference to shared face in gFaceRecHead
149    FT_Size     fFTSize;            // our own copy
150    SkFixed     fScaleX, fScaleY;
151    FT_Matrix   fMatrix22;
152    uint32_t    fLoadGlyphFlags;
153
154    FT_Error setupSize();
155    void emboldenOutline(FT_Outline* outline);
156};
157
158///////////////////////////////////////////////////////////////////////////
159///////////////////////////////////////////////////////////////////////////
160
161#include "SkStream.h"
162
163struct SkFaceRec {
164    SkFaceRec*      fNext;
165    FT_Face         fFace;
166    FT_StreamRec    fFTStream;
167    SkStream*       fSkStream;
168    uint32_t        fRefCnt;
169    uint32_t        fFontID;
170
171    // assumes ownership of the stream, will call unref() when its done
172    SkFaceRec(SkStream* strm, uint32_t fontID);
173    ~SkFaceRec() {
174        fSkStream->unref();
175    }
176};
177
178extern "C" {
179    static unsigned long sk_stream_read(FT_Stream       stream,
180                                        unsigned long   offset,
181                                        unsigned char*  buffer,
182                                        unsigned long   count ) {
183        SkStream* str = (SkStream*)stream->descriptor.pointer;
184
185        if (count) {
186            if (!str->rewind()) {
187                return 0;
188            } else {
189                unsigned long ret;
190                if (offset) {
191                    ret = str->read(NULL, offset);
192                    if (ret != offset) {
193                        return 0;
194                    }
195                }
196                ret = str->read(buffer, count);
197                if (ret != count) {
198                    return 0;
199                }
200                count = ret;
201            }
202        }
203        return count;
204    }
205
206    static void sk_stream_close( FT_Stream stream) {}
207}
208
209SkFaceRec::SkFaceRec(SkStream* strm, uint32_t fontID)
210        : fSkStream(strm), fFontID(fontID) {
211//    SkDEBUGF(("SkFaceRec: opening %s (%p)\n", key.c_str(), strm));
212
213    sk_bzero(&fFTStream, sizeof(fFTStream));
214    fFTStream.size = fSkStream->getLength();
215    fFTStream.descriptor.pointer = fSkStream;
216    fFTStream.read  = sk_stream_read;
217    fFTStream.close = sk_stream_close;
218}
219
220// Will return 0 on failure
221static SkFaceRec* ref_ft_face(uint32_t fontID) {
222    SkFaceRec* rec = gFaceRecHead;
223    while (rec) {
224        if (rec->fFontID == fontID) {
225            SkASSERT(rec->fFace);
226            rec->fRefCnt += 1;
227            return rec;
228        }
229        rec = rec->fNext;
230    }
231
232    SkStream* strm = SkFontHost::OpenStream(fontID);
233    if (NULL == strm) {
234        SkDEBUGF(("SkFontHost::OpenStream failed opening %x\n", fontID));
235        return 0;
236    }
237
238    // this passes ownership of strm to the rec
239    rec = SkNEW_ARGS(SkFaceRec, (strm, fontID));
240
241    FT_Open_Args    args;
242    memset(&args, 0, sizeof(args));
243    const void* memoryBase = strm->getMemoryBase();
244
245    if (NULL != memoryBase) {
246//printf("mmap(%s)\n", keyString.c_str());
247        args.flags = FT_OPEN_MEMORY;
248        args.memory_base = (const FT_Byte*)memoryBase;
249        args.memory_size = strm->getLength();
250    } else {
251//printf("fopen(%s)\n", keyString.c_str());
252        args.flags = FT_OPEN_STREAM;
253        args.stream = &rec->fFTStream;
254    }
255
256    int face_index;
257    int length = SkFontHost::GetFileName(fontID, NULL, 0, &face_index);
258    FT_Error err = FT_Open_Face(gFTLibrary, &args, length ? face_index : 0,
259                                &rec->fFace);
260
261    if (err) {    // bad filename, try the default font
262        fprintf(stderr, "ERROR: unable to open font '%x'\n", fontID);
263        SkDELETE(rec);
264        return 0;
265    } else {
266        SkASSERT(rec->fFace);
267        //fprintf(stderr, "Opened font '%s'\n", filename.c_str());
268        rec->fNext = gFaceRecHead;
269        gFaceRecHead = rec;
270        rec->fRefCnt = 1;
271        return rec;
272    }
273}
274
275static void unref_ft_face(FT_Face face) {
276    SkFaceRec*  rec = gFaceRecHead;
277    SkFaceRec*  prev = NULL;
278    while (rec) {
279        SkFaceRec* next = rec->fNext;
280        if (rec->fFace == face) {
281            if (--rec->fRefCnt == 0) {
282                if (prev) {
283                    prev->fNext = next;
284                } else {
285                    gFaceRecHead = next;
286                }
287                FT_Done_Face(face);
288                SkDELETE(rec);
289            }
290            return;
291        }
292        prev = rec;
293        rec = next;
294    }
295    SkASSERT("shouldn't get here, face not in list");
296}
297
298///////////////////////////////////////////////////////////////////////////
299
300// Work around for old versions of freetype.
301static FT_Error getAdvances(FT_Face face, FT_UInt start, FT_UInt count,
302                           FT_Int32 loadFlags, FT_Fixed* advances) {
303#ifdef FT_ADVANCES_H
304    return FT_Get_Advances(face, start, count, loadFlags, advances);
305#else
306    if (!face || start >= face->num_glyphs ||
307            start + count > face->num_glyphs || loadFlags != FT_LOAD_NO_SCALE) {
308        return 6;  // "Invalid argument."
309    }
310    if (count == 0)
311        return 0;
312
313    for (int i = 0; i < count; i++) {
314        FT_Error err = FT_Load_Glyph(face, start + i, FT_LOAD_NO_SCALE);
315        if (err)
316            return err;
317        advances[i] = face->glyph->advance.x;
318    }
319
320    return 0;
321#endif
322}
323
324static bool canEmbed(FT_Face face) {
325#ifdef FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING
326    FT_UShort fsType = FT_Get_FSType_Flags(face);
327    return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
328                      FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0;
329#else
330    // No embedding is 0x2 and bitmap embedding only is 0x200.
331    TT_OS2* os2_table;
332    if ((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != NULL) {
333        return (os2_table->fsType & 0x202) == 0;
334    }
335    return false;  // We tried, fail safe.
336#endif
337}
338
339static bool GetLetterCBox(FT_Face face, char letter, FT_BBox* bbox) {
340    const FT_UInt glyph_id = FT_Get_Char_Index(face, letter);
341    if (!glyph_id)
342        return false;
343    FT_Load_Glyph(face, glyph_id, FT_LOAD_NO_SCALE);
344    FT_Outline_Get_CBox(&face->glyph->outline, bbox);
345    return true;
346}
347
348static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
349    FT_Fixed advance = 0;
350    if (getAdvances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) {
351        return false;
352    }
353    SkASSERT(data);
354    *data = advance;
355    return true;
356}
357
358static void populate_glyph_to_unicode(FT_Face& face,
359                                      SkTDArray<SkUnichar>* glyphToUnicode) {
360    // Check and see if we have Unicode cmaps.
361    for (int i = 0; i < face->num_charmaps; ++i) {
362        // CMaps known to support Unicode:
363        // Platform ID   Encoding ID   Name
364        // -----------   -----------   -----------------------------------
365        // 0             0,1           Apple Unicode
366        // 0             3             Apple Unicode 2.0 (preferred)
367        // 3             1             Microsoft Unicode UCS-2
368        // 3             10            Microsoft Unicode UCS-4 (preferred)
369        //
370        // See Apple TrueType Reference Manual
371        // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6cmap.html
372        // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html#ID
373        // Microsoft OpenType Specification
374        // http://www.microsoft.com/typography/otspec/cmap.htm
375
376        FT_UShort platformId = face->charmaps[i]->platform_id;
377        FT_UShort encodingId = face->charmaps[i]->encoding_id;
378
379        if (platformId != 0 && platformId != 3) {
380            continue;
381        }
382        if (platformId == 3 && encodingId != 1 && encodingId != 10) {
383            continue;
384        }
385        bool preferredMap = ((platformId == 3 && encodingId == 10) ||
386                             (platformId == 0 && encodingId == 3));
387
388        FT_Set_Charmap(face, face->charmaps[i]);
389        if (glyphToUnicode->isEmpty()) {
390            glyphToUnicode->setCount(face->num_glyphs);
391            memset(glyphToUnicode->begin(), 0,
392                   sizeof(SkUnichar) * face->num_glyphs);
393        }
394
395        // Iterate through each cmap entry.
396        FT_UInt glyphIndex;
397        for (SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
398             glyphIndex != 0;
399             charCode = FT_Get_Next_Char(face, charCode, &glyphIndex)) {
400            if (charCode &&
401                    ((*glyphToUnicode)[glyphIndex] == 0 || preferredMap)) {
402                (*glyphToUnicode)[glyphIndex] = charCode;
403            }
404        }
405    }
406}
407
408// static
409SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
410        uint32_t fontID,
411        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
412        const uint32_t* glyphIDs,
413        uint32_t glyphIDsCount) {
414#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
415    return NULL;
416#else
417    SkAutoMutexAcquire ac(gFTMutex);
418    FT_Library libInit = NULL;
419    if (gFTCount == 0) {
420        if (!InitFreetype())
421            sk_throw();
422        libInit = gFTLibrary;
423    }
424    SkAutoTCallIProc<struct FT_LibraryRec_, FT_Done_FreeType> ftLib(libInit);
425    SkFaceRec* rec = ref_ft_face(fontID);
426    if (NULL == rec)
427        return NULL;
428    FT_Face face = rec->fFace;
429
430    SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
431    info->fFontName.set(FT_Get_Postscript_Name(face));
432    info->fMultiMaster = FT_HAS_MULTIPLE_MASTERS(face);
433    info->fLastGlyphID = face->num_glyphs - 1;
434    info->fEmSize = 1000;
435
436    bool cid = false;
437    const char* fontType = FT_Get_X11_Font_Format(face);
438    if (strcmp(fontType, "Type 1") == 0) {
439        info->fType = SkAdvancedTypefaceMetrics::kType1_Font;
440    } else if (strcmp(fontType, "CID Type 1") == 0) {
441        info->fType = SkAdvancedTypefaceMetrics::kType1CID_Font;
442        cid = true;
443    } else if (strcmp(fontType, "CFF") == 0) {
444        info->fType = SkAdvancedTypefaceMetrics::kCFF_Font;
445    } else if (strcmp(fontType, "TrueType") == 0) {
446        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
447        cid = true;
448        TT_Header* ttHeader;
449        if ((ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face,
450                                                      ft_sfnt_head)) != NULL) {
451            info->fEmSize = ttHeader->Units_Per_EM;
452        }
453    }
454
455    info->fStyle = 0;
456    if (FT_IS_FIXED_WIDTH(face))
457        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
458    if (face->style_flags & FT_STYLE_FLAG_ITALIC)
459        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
460    // We should set either Symbolic or Nonsymbolic; Nonsymbolic if the font's
461    // character set is a subset of 'Adobe standard Latin.'
462    info->fStyle |= SkAdvancedTypefaceMetrics::kSymbolic_Style;
463
464    PS_FontInfoRec ps_info;
465    TT_Postscript* tt_info;
466    if (FT_Get_PS_Font_Info(face, &ps_info) == 0) {
467        info->fItalicAngle = ps_info.italic_angle;
468    } else if ((tt_info =
469                (TT_Postscript*)FT_Get_Sfnt_Table(face,
470                                                  ft_sfnt_post)) != NULL) {
471        info->fItalicAngle = SkFixedToScalar(tt_info->italicAngle);
472    } else {
473        info->fItalicAngle = 0;
474    }
475
476    info->fAscent = face->ascender;
477    info->fDescent = face->descender;
478
479    // Figure out a good guess for StemV - Min width of i, I, !, 1.
480    // This probably isn't very good with an italic font.
481    int16_t min_width = SHRT_MAX;
482    info->fStemV = 0;
483    char stem_chars[] = {'i', 'I', '!', '1'};
484    for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
485        FT_BBox bbox;
486        if (GetLetterCBox(face, stem_chars[i], &bbox)) {
487            int16_t width = bbox.xMax - bbox.xMin;
488            if (width > 0 && width < min_width) {
489                min_width = width;
490                info->fStemV = min_width;
491            }
492        }
493    }
494
495    TT_PCLT* pclt_info;
496    TT_OS2* os2_table;
497    if ((pclt_info = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != NULL) {
498        info->fCapHeight = pclt_info->CapHeight;
499        uint8_t serif_style = pclt_info->SerifStyle & 0x3F;
500        if (serif_style >= 2 && serif_style <= 6)
501            info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
502        else if (serif_style >= 9 && serif_style <= 12)
503            info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
504    } else if ((os2_table =
505                (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != NULL) {
506        info->fCapHeight = os2_table->sCapHeight;
507    } else {
508        // Figure out a good guess for CapHeight: average the height of M and X.
509        FT_BBox m_bbox, x_bbox;
510        bool got_m, got_x;
511        got_m = GetLetterCBox(face, 'M', &m_bbox);
512        got_x = GetLetterCBox(face, 'X', &x_bbox);
513        if (got_m && got_x) {
514            info->fCapHeight = (m_bbox.yMax - m_bbox.yMin + x_bbox.yMax -
515                    x_bbox.yMin) / 2;
516        } else if (got_m && !got_x) {
517            info->fCapHeight = m_bbox.yMax - m_bbox.yMin;
518        } else if (!got_m && got_x) {
519            info->fCapHeight = x_bbox.yMax - x_bbox.yMin;
520        }
521    }
522
523    info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
524                                    face->bbox.xMax, face->bbox.yMin);
525
526    if (!canEmbed(face) || !FT_IS_SCALABLE(face) ||
527            info->fType == SkAdvancedTypefaceMetrics::kOther_Font) {
528        perGlyphInfo = SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo;
529    }
530
531    if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
532        if (FT_IS_FIXED_WIDTH(face)) {
533            appendRange(&info->fGlyphWidths, 0);
534            int16_t advance = face->max_advance_width;
535            info->fGlyphWidths->fAdvance.append(1, &advance);
536            finishRange(info->fGlyphWidths.get(), 0,
537                        SkAdvancedTypefaceMetrics::WidthRange::kDefault);
538        } else if (!cid) {
539            appendRange(&info->fGlyphWidths, 0);
540            // So as to not blow out the stack, get advances in batches.
541            for (int gID = 0; gID < face->num_glyphs; gID += 128) {
542                FT_Fixed advances[128];
543                int advanceCount = 128;
544                if (gID + advanceCount > face->num_glyphs)
545                    advanceCount = face->num_glyphs - gID + 1;
546                getAdvances(face, gID, advanceCount, FT_LOAD_NO_SCALE,
547                            advances);
548                for (int i = 0; i < advanceCount; i++) {
549                    int16_t advance = advances[gID + i];
550                    info->fGlyphWidths->fAdvance.append(1, &advance);
551                }
552            }
553            finishRange(info->fGlyphWidths.get(), face->num_glyphs - 1,
554                        SkAdvancedTypefaceMetrics::WidthRange::kRange);
555        } else {
556            info->fGlyphWidths.reset(
557                getAdvanceData(face,
558                               face->num_glyphs,
559                               glyphIDs,
560                               glyphIDsCount,
561                               &getWidthAdvance));
562        }
563    }
564
565    if (perGlyphInfo & SkAdvancedTypefaceMetrics::kVAdvance_PerGlyphInfo &&
566            FT_HAS_VERTICAL(face)) {
567        SkASSERT(false);  // Not implemented yet.
568    }
569
570    if (perGlyphInfo & SkAdvancedTypefaceMetrics::kGlyphNames_PerGlyphInfo &&
571            info->fType == SkAdvancedTypefaceMetrics::kType1_Font) {
572        // Postscript fonts may contain more than 255 glyphs, so we end up
573        // using multiple font descriptions with a glyph ordering.  Record
574        // the name of each glyph.
575        info->fGlyphNames.reset(
576                new SkAutoTArray<SkString>(face->num_glyphs));
577        for (int gID = 0; gID < face->num_glyphs; gID++) {
578            char glyphName[128];  // PS limit for names is 127 bytes.
579            FT_Get_Glyph_Name(face, gID, glyphName, 128);
580            info->fGlyphNames->get()[gID].set(glyphName);
581        }
582    }
583
584    if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo &&
585           info->fType != SkAdvancedTypefaceMetrics::kType1_Font &&
586           face->num_charmaps) {
587        populate_glyph_to_unicode(face, &(info->fGlyphToUnicode));
588    }
589
590    if (!canEmbed(face))
591        info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
592
593    unref_ft_face(face);
594    return info;
595#endif
596}
597
598///////////////////////////////////////////////////////////////////////////
599
600static bool bothZero(SkScalar a, SkScalar b) {
601    return 0 == a && 0 == b;
602}
603
604// returns false if there is any non-90-rotation or skew
605static bool isAxisAligned(const SkScalerContext::Rec& rec) {
606    return 0 == rec.fPreSkewX &&
607           (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
608            bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
609}
610
611void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
612    if (!gLCDSupportValid) {
613        InitFreetype();
614        FT_Done_FreeType(gFTLibrary);
615    }
616
617    if (!gLCDSupport && isLCD(*rec)) {
618        // If the runtime Freetype library doesn't support LCD mode, we disable
619        // it here.
620        rec->fMaskFormat = SkMask::kA8_Format;
621    }
622
623    SkPaint::Hinting h = rec->getHinting();
624    if (SkPaint::kFull_Hinting == h && !isLCD(*rec)) {
625        // collapse full->normal hinting if we're not doing LCD
626        h = SkPaint::kNormal_Hinting;
627    } else if ((rec->fFlags & SkScalerContext::kSubpixelPositioning_Flag) &&
628               SkPaint::kNo_Hinting != h) {
629        // to do subpixel, we must have at most slight hinting
630        h = SkPaint::kSlight_Hinting;
631    }
632#ifndef SK_IGNORE_ROTATED_FREETYPE_FIX
633    // rotated text looks bad with hinting, so we disable it as needed
634    if (!isAxisAligned(*rec)) {
635        h = SkPaint::kNo_Hinting;
636    }
637#endif
638    rec->setHinting(h);
639}
640
641#ifdef ANDROID
642uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
643    SkAutoMutexAcquire ac(gFTMutex);
644    SkFaceRec *rec = ref_ft_face(fontID);
645    uint16_t unitsPerEm = 0;
646
647    if (rec != NULL && rec->fFace != NULL) {
648        unitsPerEm = rec->fFace->units_per_EM;
649        unref_ft_face(rec->fFace);
650    }
651
652    return (uint32_t)unitsPerEm;
653}
654#endif
655
656SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
657        : SkScalerContext(desc) {
658    SkAutoMutexAcquire  ac(gFTMutex);
659
660    if (gFTCount == 0) {
661        if (!InitFreetype()) {
662            sk_throw();
663        }
664    }
665    ++gFTCount;
666
667    // load the font file
668    fFTSize = NULL;
669    fFace = NULL;
670    fFaceRec = ref_ft_face(fRec.fFontID);
671    if (NULL == fFaceRec) {
672        return;
673    }
674    fFace = fFaceRec->fFace;
675
676    // compute our factors from the record
677
678    SkMatrix    m;
679
680    fRec.getSingleMatrix(&m);
681
682#ifdef DUMP_STRIKE_CREATION
683    SkString     keyString;
684    SkFontHost::GetDescriptorKeyString(desc, &keyString);
685    printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
686           SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
687           SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0][1]),
688           SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1][1]),
689           fRec.getHinting(), fRec.fMaskFormat, keyString.c_str());
690#endif
691
692    //  now compute our scale factors
693    SkScalar    sx = m.getScaleX();
694    SkScalar    sy = m.getScaleY();
695
696    if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) {
697        // sort of give up on hinting
698        sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX()));
699        sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy));
700        sx = sy = SkScalarAve(sx, sy);
701
702        SkScalar inv = SkScalarInvert(sx);
703
704        // flip the skew elements to go from our Y-down system to FreeType's
705        fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv));
706        fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv));
707        fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv));
708        fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv));
709    } else {
710        fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
711        fMatrix22.xy = fMatrix22.yx = 0;
712    }
713
714    fScaleX = SkScalarToFixed(sx);
715    fScaleY = SkScalarToFixed(sy);
716
717    // compute the flags we send to Load_Glyph
718    {
719        FT_Int32 loadFlags = FT_LOAD_DEFAULT;
720
721        if (SkMask::kBW_Format == fRec.fMaskFormat) {
722            // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
723            loadFlags = FT_LOAD_TARGET_MONO;
724            if (fRec.getHinting() == SkPaint::kNo_Hinting) {
725                loadFlags = FT_LOAD_NO_HINTING;
726            }
727        } else {
728            switch (fRec.getHinting()) {
729            case SkPaint::kNo_Hinting:
730                loadFlags = FT_LOAD_NO_HINTING;
731                break;
732            case SkPaint::kSlight_Hinting:
733                loadFlags = FT_LOAD_TARGET_LIGHT;  // This implies FORCE_AUTOHINT
734                break;
735            case SkPaint::kNormal_Hinting:
736                if (fRec.fFlags & SkScalerContext::kAutohinting_Flag)
737                    loadFlags = FT_LOAD_FORCE_AUTOHINT;
738                else
739                    loadFlags = FT_LOAD_NO_AUTOHINT;
740                break;
741            case SkPaint::kFull_Hinting:
742                if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
743                    loadFlags = FT_LOAD_FORCE_AUTOHINT;
744                    break;
745                }
746                loadFlags = FT_LOAD_TARGET_NORMAL;
747                if (isLCD(fRec)) {
748                    if (fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag) {
749                        loadFlags = FT_LOAD_TARGET_LCD_V;
750                    } else {
751                        loadFlags = FT_LOAD_TARGET_LCD;
752                    }
753                }
754                break;
755            default:
756                SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
757                break;
758            }
759        }
760
761        if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
762            loadFlags |= FT_LOAD_NO_BITMAP;
763        }
764
765        // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
766        // advances, as fontconfig and cairo do.
767        // See http://code.google.com/p/skia/issues/detail?id=222.
768        loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
769
770        fLoadGlyphFlags = loadFlags;
771    }
772
773    // now create the FT_Size
774
775    {
776        FT_Error    err;
777
778        err = FT_New_Size(fFace, &fFTSize);
779        if (err != 0) {
780            SkDEBUGF(("SkScalerContext_FreeType::FT_New_Size(%x): FT_Set_Char_Size(0x%x, 0x%x) returned 0x%x\n",
781                        fFaceRec->fFontID, fScaleX, fScaleY, err));
782            fFace = NULL;
783            return;
784        }
785
786        err = FT_Activate_Size(fFTSize);
787        if (err != 0) {
788            SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
789                        fFaceRec->fFontID, fScaleX, fScaleY, err));
790            fFTSize = NULL;
791        }
792
793        err = FT_Set_Char_Size( fFace,
794                                SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScaleY),
795                                72, 72);
796        if (err != 0) {
797            SkDEBUGF(("SkScalerContext_FreeType::FT_Set_Char_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
798                        fFaceRec->fFontID, fScaleX, fScaleY, err));
799            fFace = NULL;
800            return;
801        }
802
803        FT_Set_Transform( fFace, &fMatrix22, NULL);
804    }
805}
806
807SkScalerContext_FreeType::~SkScalerContext_FreeType() {
808    if (fFTSize != NULL) {
809        FT_Done_Size(fFTSize);
810    }
811
812    SkAutoMutexAcquire  ac(gFTMutex);
813
814    if (fFace != NULL) {
815        unref_ft_face(fFace);
816    }
817    if (--gFTCount == 0) {
818//        SkDEBUGF(("FT_Done_FreeType\n"));
819        FT_Done_FreeType(gFTLibrary);
820        SkDEBUGCODE(gFTLibrary = NULL;)
821    }
822}
823
824/*  We call this before each use of the fFace, since we may be sharing
825    this face with other context (at different sizes).
826*/
827FT_Error SkScalerContext_FreeType::setupSize() {
828    /*  In the off-chance that a font has been removed, we want to error out
829        right away, so call resolve just to be sure.
830
831        TODO: perhaps we can skip this, by walking the global font cache and
832        killing all of the contexts when we know that a given fontID is going
833        away...
834     */
835    if (!SkFontHost::ValidFontID(fRec.fFontID)) {
836        return (FT_Error)-1;
837    }
838
839    FT_Error    err = FT_Activate_Size(fFTSize);
840
841    if (err != 0) {
842        SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) returned 0x%x\n",
843                    fFaceRec->fFontID, fScaleX, fScaleY, err));
844        fFTSize = NULL;
845    } else {
846        // seems we need to reset this every time (not sure why, but without it
847        // I get random italics from some other fFTSize)
848        FT_Set_Transform( fFace, &fMatrix22, NULL);
849    }
850    return err;
851}
852
853void SkScalerContext_FreeType::emboldenOutline(FT_Outline* outline) {
854    FT_Pos strength;
855    strength = FT_MulFix(fFace->units_per_EM, fFace->size->metrics.y_scale)
856               / 24;
857    FT_Outline_Embolden(outline, strength);
858}
859
860unsigned SkScalerContext_FreeType::generateGlyphCount() {
861    return fFace->num_glyphs;
862}
863
864uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) {
865    return SkToU16(FT_Get_Char_Index( fFace, uni ));
866}
867
868SkUnichar SkScalerContext_FreeType::generateGlyphToChar(uint16_t glyph) {
869    // iterate through each cmap entry, looking for matching glyph indices
870    FT_UInt glyphIndex;
871    SkUnichar charCode = FT_Get_First_Char( fFace, &glyphIndex );
872
873    while (glyphIndex != 0) {
874        if (glyphIndex == glyph) {
875            return charCode;
876        }
877        charCode = FT_Get_Next_Char( fFace, charCode, &glyphIndex );
878    }
879
880    return 0;
881}
882
883static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
884    switch (format) {
885        case SkMask::kBW_Format:
886            return FT_PIXEL_MODE_MONO;
887        case SkMask::kA8_Format:
888        default:
889            return FT_PIXEL_MODE_GRAY;
890    }
891}
892
893void SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) {
894#ifdef FT_ADVANCES_H
895   /* unhinted and light hinted text have linearly scaled advances
896    * which are very cheap to compute with some font formats...
897    */
898    {
899        SkAutoMutexAcquire  ac(gFTMutex);
900
901        if (this->setupSize()) {
902            glyph->zeroMetrics();
903            return;
904        }
905
906        FT_Error    error;
907        FT_Fixed    advance;
908
909        error = FT_Get_Advance( fFace, glyph->getGlyphID(fBaseGlyphCount),
910                                fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY,
911                                &advance );
912        if (0 == error) {
913            glyph->fRsbDelta = 0;
914            glyph->fLsbDelta = 0;
915            glyph->fAdvanceX = advance;  // advance *2/3; //DEBUG
916            glyph->fAdvanceY = 0;
917            return;
918        }
919    }
920#endif /* FT_ADVANCES_H */
921    /* otherwise, we need to load/hint the glyph, which is slower */
922    this->generateMetrics(glyph);
923    return;
924}
925
926void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
927    SkAutoMutexAcquire  ac(gFTMutex);
928
929    glyph->fRsbDelta = 0;
930    glyph->fLsbDelta = 0;
931
932    FT_Error    err;
933
934    if (this->setupSize()) {
935        goto ERROR;
936    }
937
938    err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags );
939    if (err != 0) {
940        SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
941                    fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, err));
942    ERROR:
943        glyph->zeroMetrics();
944        return;
945    }
946
947    switch ( fFace->glyph->format ) {
948      case FT_GLYPH_FORMAT_OUTLINE: {
949        FT_BBox bbox;
950
951        if (fRec.fFlags & kEmbolden_Flag) {
952            emboldenOutline(&fFace->glyph->outline);
953        }
954        FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
955
956        if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
957            int dx = glyph->getSubXFixed() >> 10;
958            int dy = glyph->getSubYFixed() >> 10;
959            // negate dy since freetype-y-goes-up and skia-y-goes-down
960            bbox.xMin += dx;
961            bbox.yMin -= dy;
962            bbox.xMax += dx;
963            bbox.yMax -= dy;
964        }
965
966        bbox.xMin &= ~63;
967        bbox.yMin &= ~63;
968        bbox.xMax  = (bbox.xMax + 63) & ~63;
969        bbox.yMax  = (bbox.yMax + 63) & ~63;
970
971        glyph->fWidth   = SkToU16((bbox.xMax - bbox.xMin) >> 6);
972        glyph->fHeight  = SkToU16((bbox.yMax - bbox.yMin) >> 6);
973        glyph->fTop     = -SkToS16(bbox.yMax >> 6);
974        glyph->fLeft    = SkToS16(bbox.xMin >> 6);
975        break;
976      }
977
978      case FT_GLYPH_FORMAT_BITMAP:
979        if (fRec.fFlags & kEmbolden_Flag) {
980            FT_GlyphSlot_Own_Bitmap(fFace->glyph);
981            FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmboldenStrength, 0);
982        }
983        glyph->fWidth   = SkToU16(fFace->glyph->bitmap.width);
984        glyph->fHeight  = SkToU16(fFace->glyph->bitmap.rows);
985        glyph->fTop     = -SkToS16(fFace->glyph->bitmap_top);
986        glyph->fLeft    = SkToS16(fFace->glyph->bitmap_left);
987        break;
988
989      default:
990        SkASSERT(!"unknown glyph format");
991        goto ERROR;
992    }
993
994    if ((fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) == 0) {
995        glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x);
996        glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y);
997        if (fRec.fFlags & kDevKernText_Flag) {
998            glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta);
999            glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta);
1000        }
1001    } else {
1002        glyph->fAdvanceX = SkFixedMul(fMatrix22.xx, fFace->glyph->linearHoriAdvance);
1003        glyph->fAdvanceY = -SkFixedMul(fMatrix22.yx, fFace->glyph->linearHoriAdvance);
1004    }
1005
1006#ifdef ENABLE_GLYPH_SPEW
1007    SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
1008    SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFlags, glyph->fWidth));
1009#endif
1010}
1011
1012static int lerp(int start, int end) {
1013    SkASSERT((unsigned)SK_FREETYPE_LCD_LERP <= 256);
1014    return start + ((end - start) * (SK_FREETYPE_LCD_LERP) >> 8);
1015}
1016
1017static uint16_t packTriple(unsigned r, unsigned g, unsigned b) {
1018    if (SK_FREETYPE_LCD_LERP) {
1019        // want (a+b+c)/3, but we approx to avoid the divide
1020        unsigned ave = (5 * (r + g + b) + b) >> 4;
1021        r = lerp(r, ave);
1022        g = lerp(g, ave);
1023        b = lerp(b, ave);
1024    }
1025    return SkPackRGB16(r >> 3, g >> 2, b >> 3);
1026}
1027
1028static uint16_t grayToRGB16(U8CPU gray) {
1029    SkASSERT(gray <= 255);
1030    return SkPackRGB16(gray >> 3, gray >> 2, gray >> 3);
1031}
1032
1033static int bittst(const uint8_t data[], int bitOffset) {
1034    SkASSERT(bitOffset >= 0);
1035    int lowBit = data[bitOffset >> 3] >> (~bitOffset & 7);
1036    return lowBit & 1;
1037}
1038
1039static void copyFT2LCD16(const SkGlyph& glyph, const FT_Bitmap& bitmap,
1040                         int lcdIsBGR) {
1041    SkASSERT(glyph.fHeight == bitmap.rows);
1042    uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage);
1043    const size_t dstRB = glyph.rowBytes();
1044    const int width = glyph.fWidth;
1045    const uint8_t* src = bitmap.buffer;
1046
1047    switch (bitmap.pixel_mode) {
1048        case FT_PIXEL_MODE_MONO: {
1049            for (int y = 0; y < glyph.fHeight; ++y) {
1050                for (int x = 0; x < width; ++x) {
1051                    dst[x] = -bittst(src, x);
1052                }
1053                dst = (uint16_t*)((char*)dst + dstRB);
1054                src += bitmap.pitch;
1055            }
1056        } break;
1057        case FT_PIXEL_MODE_GRAY: {
1058            for (int y = 0; y < glyph.fHeight; ++y) {
1059                for (int x = 0; x < width; ++x) {
1060                    dst[x] = grayToRGB16(src[x]);
1061                }
1062                dst = (uint16_t*)((char*)dst + dstRB);
1063                src += bitmap.pitch;
1064            }
1065        } break;
1066        default: {
1067            SkASSERT(glyph.fWidth * 3 == bitmap.width - 6);
1068            src += 3;
1069            for (int y = 0; y < glyph.fHeight; y++) {
1070                const uint8_t* triple = src;
1071                if (lcdIsBGR) {
1072                    for (int x = 0; x < width; x++) {
1073                        dst[x] = packTriple(triple[2], triple[1], triple[0]);
1074                        triple += 3;
1075                    }
1076                } else {
1077                    for (int x = 0; x < width; x++) {
1078                        dst[x] = packTriple(triple[0], triple[1], triple[2]);
1079                        triple += 3;
1080                    }
1081                }
1082                src += bitmap.pitch;
1083                dst = (uint16_t*)((char*)dst + dstRB);
1084            }
1085        } break;
1086    }
1087}
1088
1089void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1090    SkAutoMutexAcquire  ac(gFTMutex);
1091
1092    FT_Error    err;
1093
1094    if (this->setupSize()) {
1095        goto ERROR;
1096    }
1097
1098    err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
1099    if (err != 0) {
1100        SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d width:%d height:%d rb:%d flags:%d) returned 0x%x\n",
1101                    glyph.getGlyphID(fBaseGlyphCount), glyph.fWidth, glyph.fHeight, glyph.rowBytes(), fLoadGlyphFlags, err));
1102    ERROR:
1103        memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
1104        return;
1105    }
1106
1107    switch ( fFace->glyph->format ) {
1108        case FT_GLYPH_FORMAT_OUTLINE: {
1109            FT_Outline* outline = &fFace->glyph->outline;
1110            FT_BBox     bbox;
1111            FT_Bitmap   target;
1112
1113            if (fRec.fFlags & kEmbolden_Flag) {
1114                emboldenOutline(outline);
1115            }
1116
1117            int dx = 0, dy = 0;
1118            if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
1119                dx = glyph.getSubXFixed() >> 10;
1120                dy = glyph.getSubYFixed() >> 10;
1121                // negate dy since freetype-y-goes-up and skia-y-goes-down
1122                dy = -dy;
1123            }
1124            FT_Outline_Get_CBox(outline, &bbox);
1125            /*
1126                what we really want to do for subpixel is
1127                    offset(dx, dy)
1128                    compute_bounds
1129                    offset(bbox & !63)
1130                but that is two calls to offset, so we do the following, which
1131                achieves the same thing with only one offset call.
1132            */
1133            FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
1134                                          dy - ((bbox.yMin + dy) & ~63));
1135
1136            if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
1137                FT_Render_Glyph(fFace->glyph, FT_RENDER_MODE_LCD);
1138                copyFT2LCD16(glyph, fFace->glyph->bitmap,
1139                             fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag);
1140            } else {
1141                target.width = glyph.fWidth;
1142                target.rows = glyph.fHeight;
1143                target.pitch = glyph.rowBytes();
1144                target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
1145                target.pixel_mode = compute_pixel_mode(
1146                                                (SkMask::Format)fRec.fMaskFormat);
1147                target.num_grays = 256;
1148
1149                memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
1150                FT_Outline_Get_Bitmap(gFTLibrary, outline, &target);
1151            }
1152        } break;
1153
1154        case FT_GLYPH_FORMAT_BITMAP: {
1155            if (fRec.fFlags & kEmbolden_Flag) {
1156                FT_GlyphSlot_Own_Bitmap(fFace->glyph);
1157                FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmboldenStrength, 0);
1158            }
1159            SkASSERT_CONTINUE(glyph.fWidth == fFace->glyph->bitmap.width);
1160            SkASSERT_CONTINUE(glyph.fHeight == fFace->glyph->bitmap.rows);
1161            SkASSERT_CONTINUE(glyph.fTop == -fFace->glyph->bitmap_top);
1162            SkASSERT_CONTINUE(glyph.fLeft == fFace->glyph->bitmap_left);
1163
1164            const uint8_t*  src = (const uint8_t*)fFace->glyph->bitmap.buffer;
1165            uint8_t*        dst = (uint8_t*)glyph.fImage;
1166
1167            if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY ||
1168                (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO &&
1169                 glyph.fMaskFormat == SkMask::kBW_Format)) {
1170                unsigned    srcRowBytes = fFace->glyph->bitmap.pitch;
1171                unsigned    dstRowBytes = glyph.rowBytes();
1172                unsigned    minRowBytes = SkMin32(srcRowBytes, dstRowBytes);
1173                unsigned    extraRowBytes = dstRowBytes - minRowBytes;
1174
1175                for (int y = fFace->glyph->bitmap.rows - 1; y >= 0; --y) {
1176                    memcpy(dst, src, minRowBytes);
1177                    memset(dst + minRowBytes, 0, extraRowBytes);
1178                    src += srcRowBytes;
1179                    dst += dstRowBytes;
1180                }
1181            } else if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO &&
1182                       glyph.fMaskFormat == SkMask::kA8_Format) {
1183                for (int y = 0; y < fFace->glyph->bitmap.rows; ++y) {
1184                    uint8_t byte = 0;
1185                    int bits = 0;
1186                    const uint8_t* src_row = src;
1187                    uint8_t* dst_row = dst;
1188
1189                    for (int x = 0; x < fFace->glyph->bitmap.width; ++x) {
1190                        if (!bits) {
1191                            byte = *src_row++;
1192                            bits = 8;
1193                        }
1194
1195                        *dst_row++ = byte & 0x80 ? 0xff : 0;
1196                        bits--;
1197                        byte <<= 1;
1198                    }
1199
1200                    src += fFace->glyph->bitmap.pitch;
1201                    dst += glyph.rowBytes();
1202                }
1203            } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
1204                copyFT2LCD16(glyph, fFace->glyph->bitmap,
1205                             fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag);
1206            } else {
1207                SkASSERT(!"unknown glyph bitmap transform needed");
1208            }
1209        } break;
1210
1211    default:
1212        SkASSERT(!"unknown glyph format");
1213        goto ERROR;
1214    }
1215}
1216
1217///////////////////////////////////////////////////////////////////////////////
1218
1219#define ft2sk(x)    SkFixedToScalar((x) << 10)
1220
1221#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 2
1222    #define CONST_PARAM const
1223#else   // older freetype doesn't use const here
1224    #define CONST_PARAM
1225#endif
1226
1227static int move_proc(CONST_PARAM FT_Vector* pt, void* ctx) {
1228    SkPath* path = (SkPath*)ctx;
1229    path->close();  // to close the previous contour (if any)
1230    path->moveTo(ft2sk(pt->x), -ft2sk(pt->y));
1231    return 0;
1232}
1233
1234static int line_proc(CONST_PARAM FT_Vector* pt, void* ctx) {
1235    SkPath* path = (SkPath*)ctx;
1236    path->lineTo(ft2sk(pt->x), -ft2sk(pt->y));
1237    return 0;
1238}
1239
1240static int quad_proc(CONST_PARAM FT_Vector* pt0, CONST_PARAM FT_Vector* pt1,
1241                     void* ctx) {
1242    SkPath* path = (SkPath*)ctx;
1243    path->quadTo(ft2sk(pt0->x), -ft2sk(pt0->y), ft2sk(pt1->x), -ft2sk(pt1->y));
1244    return 0;
1245}
1246
1247static int cubic_proc(CONST_PARAM FT_Vector* pt0, CONST_PARAM FT_Vector* pt1,
1248                      CONST_PARAM FT_Vector* pt2, void* ctx) {
1249    SkPath* path = (SkPath*)ctx;
1250    path->cubicTo(ft2sk(pt0->x), -ft2sk(pt0->y), ft2sk(pt1->x),
1251                  -ft2sk(pt1->y), ft2sk(pt2->x), -ft2sk(pt2->y));
1252    return 0;
1253}
1254
1255void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph,
1256                                            SkPath* path) {
1257    SkAutoMutexAcquire  ac(gFTMutex);
1258
1259    SkASSERT(&glyph && path);
1260
1261    if (this->setupSize()) {
1262        path->reset();
1263        return;
1264    }
1265
1266    uint32_t flags = fLoadGlyphFlags;
1267    flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
1268    flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
1269
1270    FT_Error err = FT_Load_Glyph( fFace, glyph.getGlyphID(fBaseGlyphCount), flags);
1271
1272    if (err != 0) {
1273        SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
1274                    glyph.getGlyphID(fBaseGlyphCount), flags, err));
1275        path->reset();
1276        return;
1277    }
1278
1279    if (fRec.fFlags & kEmbolden_Flag) {
1280        emboldenOutline(&fFace->glyph->outline);
1281    }
1282
1283    FT_Outline_Funcs    funcs;
1284
1285    funcs.move_to   = move_proc;
1286    funcs.line_to   = line_proc;
1287    funcs.conic_to  = quad_proc;
1288    funcs.cubic_to  = cubic_proc;
1289    funcs.shift     = 0;
1290    funcs.delta     = 0;
1291
1292    err = FT_Outline_Decompose(&fFace->glyph->outline, &funcs, path);
1293
1294    if (err != 0) {
1295        SkDEBUGF(("SkScalerContext_FreeType::generatePath: FT_Load_Glyph(glyph:%d flags:%d) returned 0x%x\n",
1296                    glyph.getGlyphID(fBaseGlyphCount), flags, err));
1297        path->reset();
1298        return;
1299    }
1300
1301    path->close();
1302}
1303
1304void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
1305                                                   SkPaint::FontMetrics* my) {
1306    if (NULL == mx && NULL == my) {
1307        return;
1308    }
1309
1310    SkAutoMutexAcquire  ac(gFTMutex);
1311
1312    if (this->setupSize()) {
1313        ERROR:
1314        if (mx) {
1315            sk_bzero(mx, sizeof(SkPaint::FontMetrics));
1316        }
1317        if (my) {
1318            sk_bzero(my, sizeof(SkPaint::FontMetrics));
1319        }
1320        return;
1321    }
1322
1323    FT_Face face = fFace;
1324    int upem = face->units_per_EM;
1325    if (upem <= 0) {
1326        goto ERROR;
1327    }
1328
1329    SkPoint pts[6];
1330    SkFixed ys[6];
1331    SkFixed scaleY = fScaleY;
1332    SkFixed mxy = fMatrix22.xy;
1333    SkFixed myy = fMatrix22.yy;
1334    SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem;
1335    SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem;
1336
1337    int leading = face->height - (face->ascender + -face->descender);
1338    if (leading < 0) {
1339        leading = 0;
1340    }
1341
1342    // Try to get the OS/2 table from the font. This contains the specific
1343    // average font width metrics which Windows uses.
1344    TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1345
1346    ys[0] = -face->bbox.yMax;
1347    ys[1] = -face->ascender;
1348    ys[2] = -face->descender;
1349    ys[3] = -face->bbox.yMin;
1350    ys[4] = leading;
1351    ys[5] = os2 ? os2->xAvgCharWidth : 0;
1352
1353    SkScalar x_height;
1354    if (os2 && os2->sxHeight) {
1355        x_height = SkFixedToScalar(SkMulDiv(fScaleX, os2->sxHeight, upem));
1356    } else {
1357        const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x');
1358        if (x_glyph) {
1359            FT_BBox bbox;
1360            FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags);
1361            if (fRec.fFlags & kEmbolden_Flag) {
1362                emboldenOutline(&fFace->glyph->outline);
1363            }
1364            FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
1365            x_height = SkIntToScalar(bbox.yMax) / 64;
1366        } else {
1367            x_height = 0;
1368        }
1369    }
1370
1371    // convert upem-y values into scalar points
1372    for (int i = 0; i < 6; i++) {
1373        SkFixed y = SkMulDiv(scaleY, ys[i], upem);
1374        SkFixed x = SkFixedMul(mxy, y);
1375        y = SkFixedMul(myy, y);
1376        pts[i].set(SkFixedToScalar(x), SkFixedToScalar(y));
1377    }
1378
1379    if (mx) {
1380        mx->fTop = pts[0].fX;
1381        mx->fAscent = pts[1].fX;
1382        mx->fDescent = pts[2].fX;
1383        mx->fBottom = pts[3].fX;
1384        mx->fLeading = pts[4].fX;
1385        mx->fAvgCharWidth = pts[5].fX;
1386        mx->fXMin = xmin;
1387        mx->fXMax = xmax;
1388        mx->fXHeight = x_height;
1389    }
1390    if (my) {
1391        my->fTop = pts[0].fY;
1392        my->fAscent = pts[1].fY;
1393        my->fDescent = pts[2].fY;
1394        my->fBottom = pts[3].fY;
1395        my->fLeading = pts[4].fY;
1396        my->fAvgCharWidth = pts[5].fY;
1397        my->fXMin = xmin;
1398        my->fXMax = xmax;
1399        my->fXHeight = x_height;
1400    }
1401}
1402
1403////////////////////////////////////////////////////////////////////////
1404////////////////////////////////////////////////////////////////////////
1405
1406SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
1407    SkScalerContext_FreeType* c = SkNEW_ARGS(SkScalerContext_FreeType, (desc));
1408    if (!c->success()) {
1409        SkDELETE(c);
1410        c = NULL;
1411    }
1412    return c;
1413}
1414
1415///////////////////////////////////////////////////////////////////////////////
1416
1417/*  Export this so that other parts of our FonttHost port can make use of our
1418    ability to extract the name+style from a stream, using FreeType's api.
1419*/
1420SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name,
1421                                           bool* isFixedWidth) {
1422    FT_Library  library;
1423    if (FT_Init_FreeType(&library)) {
1424        name->reset();
1425        return SkTypeface::kNormal;
1426    }
1427
1428    FT_Open_Args    args;
1429    memset(&args, 0, sizeof(args));
1430
1431    const void* memoryBase = stream->getMemoryBase();
1432    FT_StreamRec    streamRec;
1433
1434    if (NULL != memoryBase) {
1435        args.flags = FT_OPEN_MEMORY;
1436        args.memory_base = (const FT_Byte*)memoryBase;
1437        args.memory_size = stream->getLength();
1438    } else {
1439        memset(&streamRec, 0, sizeof(streamRec));
1440        streamRec.size = stream->read(NULL, 0);
1441        streamRec.descriptor.pointer = stream;
1442        streamRec.read  = sk_stream_read;
1443        streamRec.close = sk_stream_close;
1444
1445        args.flags = FT_OPEN_STREAM;
1446        args.stream = &streamRec;
1447    }
1448
1449    FT_Face face;
1450    if (FT_Open_Face(library, &args, 0, &face)) {
1451        FT_Done_FreeType(library);
1452        name->reset();
1453        return SkTypeface::kNormal;
1454    }
1455
1456    name->set(face->family_name);
1457    int style = SkTypeface::kNormal;
1458
1459    if (face->style_flags & FT_STYLE_FLAG_BOLD) {
1460        style |= SkTypeface::kBold;
1461    }
1462    if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
1463        style |= SkTypeface::kItalic;
1464    }
1465    if (isFixedWidth) {
1466        *isFixedWidth = FT_IS_FIXED_WIDTH(face);
1467    }
1468
1469    FT_Done_Face(face);
1470    FT_Done_FreeType(library);
1471    return (SkTypeface::Style)style;
1472}
1473