tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch (14679B)


      1 From: George Wright <george@mozilla.com>
      2 Date: Wed, 1 Aug 2012 16:43:15 -0400
      3 Subject: Bug 736276 - Add a new SkFontHost that takes a cairo_scaled_font_t r=karl
      4 
      5 
      6 diff --git a/gfx/skia/include/ports/SkTypeface_cairo.h b/gfx/skia/include/ports/SkTypeface_cairo.h
      7 new file mode 100644
      8 index 0000000..7e44f04
      9 --- /dev/null
     10 +++ b/gfx/skia/include/ports/SkTypeface_cairo.h
     11 @@ -0,0 +1,11 @@
     12 +#ifndef SkTypeface_cairo_DEFINED
     13 +#define SkTypeface_cairo_DEFINED
     14 +
     15 +#include <cairo.h>
     16 +
     17 +#include "SkTypeface.h"
     18 +
     19 +SK_API extern SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth);
     20 +
     21 +#endif
     22 +
     23 diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build
     24 index 9ceba59..66efd52 100644
     25 --- a/gfx/skia/moz.build
     26 +++ b/gfx/skia/moz.build
     27 @@ -171,10 +171,12 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     28         'SkTime_win.cpp',
     29     ]
     30 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
     31 +    EXPORTS.skia += [
     32 +        'include/ports/SkTypeface_cairo.h',
     33 +    ]
     34     CPP_SOURCES += [
     35 -        'SkFontHost_FreeType.cpp',
     36 +        'SkFontHost_cairo.cpp',
     37         'SkFontHost_FreeType_common.cpp',
     38 -        'SkFontHost_linux.cpp',
     39         'SkThread_pthread.cpp',
     40         'SkThreadUtils_pthread.cpp',
     41         'SkThreadUtils_pthread_linux.cpp',
     42 @@ -183,14 +185,15 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
     43     ]
     44 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
     45     CPP_SOURCES += [
     46 -        'SkFontHost_FreeType.cpp',
     47 +        'SkFontHost_cairo.cpp',
     48         'SkFontHost_FreeType_common.cpp',
     49         'SkOSFile.cpp',
     50     ]
     51     if CONFIG['OS_TARGET'] == 'Linux':
     52 +        EXPORTS.skia += [
     53 +            'include/ports/SkTypeface_cairo.h',
     54 +        ]
     55         CPP_SOURCES += [
     56 -            'SkFontHost_linux.cpp',
     57 -            'SkFontHost_tables.cpp',
     58             'SkThread_pthread.cpp',
     59             'SkThreadUtils_pthread.cpp',
     60             'SkThreadUtils_pthread_linux.cpp',
     61 @@ -204,11 +207,13 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     62 # Separate 'if' from above, since the else below applies to all != 'android'
     63 # toolkits.
     64 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     65 +    EXPORTS.skia += [
     66 +        'include/ports/SkTypeface_cairo.h',
     67 +    ]
     68     CPP_SOURCES += [
     69         'ashmem.cpp',
     70         'SkDebug_android.cpp',
     71 -        'SkFontHost_android_old.cpp',
     72 -        'SkFontHost_FreeType.cpp',
     73 +        'SkFontHost_cairo.cpp',
     74         'SkFontHost_FreeType_common.cpp',
     75         'SkImageRef_ashmem.cpp',
     76         'SkTime_Unix.cpp',
     77 diff --git a/gfx/skia/src/ports/SkFontHost_cairo.cpp b/gfx/skia/src/ports/SkFontHost_cairo.cpp
     78 new file mode 100644
     79 index 0000000..bb5b778
     80 --- /dev/null
     81 +++ b/gfx/skia/src/ports/SkFontHost_cairo.cpp
     82 @@ -0,0 +1,364 @@
     83 +
     84 +/*
     85 + * Copyright 2012 Mozilla Foundation
     86 + *
     87 + * Use of this source code is governed by a BSD-style license that can be
     88 + * found in the LICENSE file.
     89 + */
     90 +
     91 +#include "cairo.h"
     92 +#include "cairo-ft.h"
     93 +
     94 +#include "SkFontHost_FreeType_common.h"
     95 +
     96 +#include "SkAdvancedTypefaceMetrics.h"
     97 +#include "SkFontHost.h"
     98 +#include "SkPath.h"
     99 +#include "SkScalerContext.h"
    100 +#include "SkTypefaceCache.h"
    101 +
    102 +#include <ft2build.h>
    103 +#include FT_FREETYPE_H
    104 +
    105 +static cairo_user_data_key_t kSkTypefaceKey;
    106 +
    107 +class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
    108 +public:
    109 +    SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc);
    110 +    virtual ~SkScalerContext_CairoFT();
    111 +
    112 +protected:
    113 +    virtual unsigned generateGlyphCount() SK_OVERRIDE;
    114 +    virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE;
    115 +    virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
    116 +    virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
    117 +    virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
    118 +    virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
    119 +    virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
    120 +                                     SkPaint::FontMetrics* my) SK_OVERRIDE;
    121 +    virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
    122 +private:
    123 +    cairo_scaled_font_t* fScaledFont;
    124 +    uint32_t fLoadGlyphFlags;
    125 +};
    126 +
    127 +class CairoLockedFTFace {
    128 +public:
    129 +    CairoLockedFTFace(cairo_scaled_font_t* scaledFont)
    130 +        : fScaledFont(scaledFont)
    131 +        , fFace(cairo_ft_scaled_font_lock_face(scaledFont))
    132 +    {}
    133 +
    134 +    ~CairoLockedFTFace()
    135 +    {
    136 +        cairo_ft_scaled_font_unlock_face(fScaledFont);
    137 +    }
    138 +
    139 +    FT_Face getFace()
    140 +    {
    141 +        return fFace;
    142 +    }
    143 +
    144 +private:
    145 +    cairo_scaled_font_t* fScaledFont;
    146 +    FT_Face fFace;
    147 +};
    148 +
    149 +class SkCairoFTTypeface : public SkTypeface {
    150 +public:
    151 +    static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) {
    152 +        SkASSERT(fontFace != NULL);
    153 +        SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
    154 +
    155 +        SkFontID newId = SkTypefaceCache::NewFontID();
    156 +
    157 +        return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth));
    158 +    }
    159 +
    160 +    cairo_font_face_t* getFontFace() {
    161 +        return fFontFace;
    162 +    }
    163 +
    164 +    virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; }
    165 +
    166 +    virtual SkAdvancedTypefaceMetrics*
    167 +        onGetAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::PerGlyphInfo,
    168 +                                     const uint32_t*, uint32_t) const SK_OVERRIDE
    169 +    {
    170 +        SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetAdvancedTypefaceMetrics unimplemented\n"));
    171 +        return NULL;
    172 +    }
    173 +
    174 +    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE
    175 +    {
    176 +        return SkNEW_ARGS(SkScalerContext_CairoFT, (const_cast<SkCairoFTTypeface*>(this), desc));
    177 +    }
    178 +
    179 +    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE
    180 +    {
    181 +        SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onFilterRec unimplemented\n"));
    182 +    }
    183 +
    184 +    virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
    185 +    {
    186 +        SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetFontDescriptor unimplemented\n"));
    187 +    }
    188 +
    189 +
    190 +private:
    191 +
    192 +    SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth)
    193 +        : SkTypeface(style, id, isFixedWidth)
    194 +        , fFontFace(fontFace)
    195 +    {
    196 +        cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL);
    197 +        cairo_font_face_reference(fFontFace);
    198 +    }
    199 +
    200 +    ~SkCairoFTTypeface()
    201 +    {
    202 +        cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL);
    203 +        cairo_font_face_destroy(fFontFace);
    204 +    }
    205 +
    206 +    cairo_font_face_t* fFontFace;
    207 +};
    208 +
    209 +SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth)
    210 +{
    211 +    SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
    212 +
    213 +    if (typeface) {
    214 +        typeface->ref();
    215 +    } else {
    216 +        typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
    217 +        SkTypefaceCache::Add(typeface, style);
    218 +    }
    219 +
    220 +    return typeface;
    221 +}
    222 +
    223 +SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
    224 +                                     const char famillyName[],
    225 +                                     SkTypeface::Style style)
    226 +{
    227 +    SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented");
    228 +    return NULL;
    229 +}
    230 +
    231 +SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*)
    232 +{
    233 +    SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
    234 +    return NULL;
    235 +}
    236 +
    237 +SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
    238 +{
    239 +    SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
    240 +    return NULL;
    241 +}
    242 +
    243 +///////////////////////////////////////////////////////////////////////////////
    244 +
    245 +static bool isLCD(const SkScalerContext::Rec& rec) {
    246 +    switch (rec.fMaskFormat) {
    247 +        case SkMask::kLCD16_Format:
    248 +        case SkMask::kLCD32_Format:
    249 +            return true;
    250 +        default:
    251 +            return false;
    252 +    }
    253 +}
    254 +
    255 +///////////////////////////////////////////////////////////////////////////////
    256 +SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc)
    257 +    : SkScalerContext_FreeType_Base(typeface, desc)
    258 +{
    259 +    SkMatrix matrix;
    260 +    fRec.getSingleMatrix(&matrix);
    261 +
    262 +    cairo_font_face_t* fontFace = static_cast<SkCairoFTTypeface*>(typeface)->getFontFace();
    263 +
    264 +    cairo_matrix_t fontMatrix, ctMatrix;
    265 +    cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
    266 +    cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
    267 +
    268 +    // We need to ensure that the font options match for hinting, as generateMetrics()
    269 +    // uses the fScaledFont which uses these font options
    270 +    cairo_font_options_t *fontOptions = cairo_font_options_create();
    271 +
    272 +    FT_Int32 loadFlags = FT_LOAD_DEFAULT;
    273 +
    274 +    if (SkMask::kBW_Format == fRec.fMaskFormat) {
    275 +        // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
    276 +        loadFlags = FT_LOAD_TARGET_MONO;
    277 +        if (fRec.getHinting() == SkPaint::kNo_Hinting) {
    278 +            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
    279 +            loadFlags = FT_LOAD_NO_HINTING;
    280 +        }
    281 +    } else {
    282 +        switch (fRec.getHinting()) {
    283 +        case SkPaint::kNo_Hinting:
    284 +            loadFlags = FT_LOAD_NO_HINTING;
    285 +            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
    286 +            break;
    287 +        case SkPaint::kSlight_Hinting:
    288 +            loadFlags = FT_LOAD_TARGET_LIGHT;  // This implies FORCE_AUTOHINT
    289 +            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
    290 +            break;
    291 +        case SkPaint::kNormal_Hinting:
    292 +            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
    293 +            if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
    294 +                loadFlags = FT_LOAD_FORCE_AUTOHINT;
    295 +            }
    296 +            break;
    297 +        case SkPaint::kFull_Hinting:
    298 +            cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
    299 +            if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
    300 +                loadFlags = FT_LOAD_FORCE_AUTOHINT;
    301 +            }
    302 +            if (isLCD(fRec)) {
    303 +                if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
    304 +                    loadFlags = FT_LOAD_TARGET_LCD_V;
    305 +                } else {
    306 +                    loadFlags = FT_LOAD_TARGET_LCD;
    307 +                }
    308 +            }
    309 +            break;
    310 +        default:
    311 +            SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
    312 +            break;
    313 +        }
    314 +    }
    315 +
    316 +    fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
    317 +
    318 +    if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
    319 +        loadFlags |= FT_LOAD_NO_BITMAP;
    320 +    }
    321 +
    322 +    // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
    323 +    // advances, as fontconfig and cairo do.
    324 +    // See http://code.google.com/p/skia/issues/detail?id=222.
    325 +    loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
    326 +
    327 +    fLoadGlyphFlags = loadFlags;
    328 +}
    329 +
    330 +SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
    331 +{
    332 +    cairo_scaled_font_destroy(fScaledFont);
    333 +}
    334 +
    335 +unsigned SkScalerContext_CairoFT::generateGlyphCount()
    336 +{
    337 +    CairoLockedFTFace faceLock(fScaledFont);
    338 +    return faceLock.getFace()->num_glyphs;
    339 +}
    340 +
    341 +uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar)
    342 +{
    343 +    CairoLockedFTFace faceLock(fScaledFont);
    344 +    return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar));
    345 +}
    346 +
    347 +void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
    348 +{
    349 +    generateMetrics(glyph);
    350 +}
    351 +
    352 +void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
    353 +{
    354 +    SkASSERT(fScaledFont != NULL);
    355 +    cairo_text_extents_t extents;
    356 +    cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 };
    357 +    cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents);
    358 +
    359 +    glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance);
    360 +    glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance);
    361 +    glyph->fWidth = SkToU16(SkScalarCeil(extents.width));
    362 +    glyph->fHeight = SkToU16(SkScalarCeil(extents.height));
    363 +    glyph->fLeft = SkToS16(SkScalarCeil(extents.x_bearing));
    364 +    glyph->fTop = SkToS16(SkScalarCeil(extents.y_bearing));
    365 +    glyph->fLsbDelta = 0;
    366 +    glyph->fRsbDelta = 0;
    367 +}
    368 +
    369 +void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
    370 +{
    371 +    SkASSERT(fScaledFont != NULL);
    372 +    CairoLockedFTFace faceLock(fScaledFont);
    373 +    FT_Face face = faceLock.getFace();
    374 +
    375 +    FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
    376 +
    377 +    if (err != 0) {
    378 +        memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
    379 +        return;
    380 +    }
    381 +
    382 +    generateGlyphImage(face, glyph);
    383 +}
    384 +
    385 +void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path)
    386 +{
    387 +    SkASSERT(fScaledFont != NULL);
    388 +    CairoLockedFTFace faceLock(fScaledFont);
    389 +    FT_Face face = faceLock.getFace();
    390 +
    391 +    SkASSERT(&glyph && path);
    392 +
    393 +    uint32_t flags = fLoadGlyphFlags;
    394 +    flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
    395 +    flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
    396 +
    397 +    FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags);
    398 +
    399 +    if (err != 0) {
    400 +        path->reset();
    401 +        return;
    402 +    }
    403 +
    404 +    generateGlyphPath(face, path);
    405 +}
    406 +
    407 +void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx,
    408 +                                                  SkPaint::FontMetrics* my)
    409 +{
    410 +    SkDEBUGCODE(SkDebugf("SkScalerContext_CairoFT::generateFontMetrics unimplemented\n"));
    411 +}
    412 +
    413 +SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph)
    414 +{
    415 +    SkASSERT(fScaledFont != NULL);
    416 +    CairoLockedFTFace faceLock(fScaledFont);
    417 +    FT_Face face = faceLock.getFace();
    418 +
    419 +    FT_UInt glyphIndex;
    420 +    SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
    421 +    while (glyphIndex != 0) {
    422 +        if (glyphIndex == glyph) {
    423 +            return charCode;
    424 +        }
    425 +        charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
    426 +    }
    427 +
    428 +    return 0;
    429 +}
    430 +
    431 +#ifdef SK_BUILD_FOR_ANDROID
    432 +SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
    433 +                                         SkFontID origFontID) {
    434 +    return NULL;
    435 +}
    436 +#endif
    437 +
    438 +///////////////////////////////////////////////////////////////////////////////
    439 +
    440 +#include "SkFontMgr.h"
    441 +
    442 +SkFontMgr* SkFontMgr::Factory() {
    443 +    // todo
    444 +    return NULL;
    445 +}
    446 +
    447 -- 
    448 1.7.11.7