summaryrefslogtreecommitdiffstats
path: root/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch449
1 files changed, 449 insertions, 0 deletions
diff --git a/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch b/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch
new file mode 100644
index 0000000000..cd2f67131c
--- /dev/null
+++ b/gfx/skia/patches/archive/0005-Bug-736276-Add-a-new-SkFontHost-that-takes-a-cairo_s.patch
@@ -0,0 +1,449 @@
+From: George Wright <george@mozilla.com>
+Date: Wed, 1 Aug 2012 16:43:15 -0400
+Subject: Bug 736276 - Add a new SkFontHost that takes a cairo_scaled_font_t r=karl
+
+
+diff --git a/gfx/skia/include/ports/SkTypeface_cairo.h b/gfx/skia/include/ports/SkTypeface_cairo.h
+new file mode 100644
+index 0000000..7e44f04
+--- /dev/null
++++ b/gfx/skia/include/ports/SkTypeface_cairo.h
+@@ -0,0 +1,11 @@
++#ifndef SkTypeface_cairo_DEFINED
++#define SkTypeface_cairo_DEFINED
++
++#include <cairo.h>
++
++#include "SkTypeface.h"
++
++SK_API extern SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth);
++
++#endif
++
+diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build
+index 9ceba59..66efd52 100644
+--- a/gfx/skia/moz.build
++++ b/gfx/skia/moz.build
+@@ -171,10 +171,12 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+ 'SkTime_win.cpp',
+ ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
++ EXPORTS.skia += [
++ 'include/ports/SkTypeface_cairo.h',
++ ]
+ CPP_SOURCES += [
+- 'SkFontHost_FreeType.cpp',
++ 'SkFontHost_cairo.cpp',
+ 'SkFontHost_FreeType_common.cpp',
+- 'SkFontHost_linux.cpp',
+ 'SkThread_pthread.cpp',
+ 'SkThreadUtils_pthread.cpp',
+ 'SkThreadUtils_pthread_linux.cpp',
+@@ -183,14 +185,15 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk2':
+ ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
+ CPP_SOURCES += [
+- 'SkFontHost_FreeType.cpp',
++ 'SkFontHost_cairo.cpp',
+ 'SkFontHost_FreeType_common.cpp',
+ 'SkOSFile.cpp',
+ ]
+ if CONFIG['OS_TARGET'] == 'Linux':
++ EXPORTS.skia += [
++ 'include/ports/SkTypeface_cairo.h',
++ ]
+ CPP_SOURCES += [
+- 'SkFontHost_linux.cpp',
+- 'SkFontHost_tables.cpp',
+ 'SkThread_pthread.cpp',
+ 'SkThreadUtils_pthread.cpp',
+ 'SkThreadUtils_pthread_linux.cpp',
+@@ -204,11 +207,13 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+ # Separate 'if' from above, since the else below applies to all != 'android'
+ # toolkits.
+ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
++ EXPORTS.skia += [
++ 'include/ports/SkTypeface_cairo.h',
++ ]
+ CPP_SOURCES += [
+ 'ashmem.cpp',
+ 'SkDebug_android.cpp',
+- 'SkFontHost_android_old.cpp',
+- 'SkFontHost_FreeType.cpp',
++ 'SkFontHost_cairo.cpp',
+ 'SkFontHost_FreeType_common.cpp',
+ 'SkImageRef_ashmem.cpp',
+ 'SkTime_Unix.cpp',
+diff --git a/gfx/skia/src/ports/SkFontHost_cairo.cpp b/gfx/skia/src/ports/SkFontHost_cairo.cpp
+new file mode 100644
+index 0000000..bb5b778
+--- /dev/null
++++ b/gfx/skia/src/ports/SkFontHost_cairo.cpp
+@@ -0,0 +1,364 @@
++
++/*
++ * Copyright 2012 Mozilla Foundation
++ *
++ * Use of this source code is governed by a BSD-style license that can be
++ * found in the LICENSE file.
++ */
++
++#include "cairo.h"
++#include "cairo-ft.h"
++
++#include "SkFontHost_FreeType_common.h"
++
++#include "SkAdvancedTypefaceMetrics.h"
++#include "SkFontHost.h"
++#include "SkPath.h"
++#include "SkScalerContext.h"
++#include "SkTypefaceCache.h"
++
++#include <ft2build.h>
++#include FT_FREETYPE_H
++
++static cairo_user_data_key_t kSkTypefaceKey;
++
++class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
++public:
++ SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc);
++ virtual ~SkScalerContext_CairoFT();
++
++protected:
++ virtual unsigned generateGlyphCount() SK_OVERRIDE;
++ virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE;
++ virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
++ virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
++ virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
++ virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
++ virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
++ SkPaint::FontMetrics* my) SK_OVERRIDE;
++ virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
++private:
++ cairo_scaled_font_t* fScaledFont;
++ uint32_t fLoadGlyphFlags;
++};
++
++class CairoLockedFTFace {
++public:
++ CairoLockedFTFace(cairo_scaled_font_t* scaledFont)
++ : fScaledFont(scaledFont)
++ , fFace(cairo_ft_scaled_font_lock_face(scaledFont))
++ {}
++
++ ~CairoLockedFTFace()
++ {
++ cairo_ft_scaled_font_unlock_face(fScaledFont);
++ }
++
++ FT_Face getFace()
++ {
++ return fFace;
++ }
++
++private:
++ cairo_scaled_font_t* fScaledFont;
++ FT_Face fFace;
++};
++
++class SkCairoFTTypeface : public SkTypeface {
++public:
++ static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) {
++ SkASSERT(fontFace != NULL);
++ SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
++
++ SkFontID newId = SkTypefaceCache::NewFontID();
++
++ return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth));
++ }
++
++ cairo_font_face_t* getFontFace() {
++ return fFontFace;
++ }
++
++ virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; }
++
++ virtual SkAdvancedTypefaceMetrics*
++ onGetAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::PerGlyphInfo,
++ const uint32_t*, uint32_t) const SK_OVERRIDE
++ {
++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetAdvancedTypefaceMetrics unimplemented\n"));
++ return NULL;
++ }
++
++ virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE
++ {
++ return SkNEW_ARGS(SkScalerContext_CairoFT, (const_cast<SkCairoFTTypeface*>(this), desc));
++ }
++
++ virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE
++ {
++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onFilterRec unimplemented\n"));
++ }
++
++ virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
++ {
++ SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetFontDescriptor unimplemented\n"));
++ }
++
++
++private:
++
++ SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth)
++ : SkTypeface(style, id, isFixedWidth)
++ , fFontFace(fontFace)
++ {
++ cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL);
++ cairo_font_face_reference(fFontFace);
++ }
++
++ ~SkCairoFTTypeface()
++ {
++ cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL);
++ cairo_font_face_destroy(fFontFace);
++ }
++
++ cairo_font_face_t* fFontFace;
++};
++
++SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth)
++{
++ SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
++
++ if (typeface) {
++ typeface->ref();
++ } else {
++ typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
++ SkTypefaceCache::Add(typeface, style);
++ }
++
++ return typeface;
++}
++
++SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
++ const char famillyName[],
++ SkTypeface::Style style)
++{
++ SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented");
++ return NULL;
++}
++
++SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*)
++{
++ SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
++ return NULL;
++}
++
++SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
++{
++ SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
++ return NULL;
++}
++
++///////////////////////////////////////////////////////////////////////////////
++
++static bool isLCD(const SkScalerContext::Rec& rec) {
++ switch (rec.fMaskFormat) {
++ case SkMask::kLCD16_Format:
++ case SkMask::kLCD32_Format:
++ return true;
++ default:
++ return false;
++ }
++}
++
++///////////////////////////////////////////////////////////////////////////////
++SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc)
++ : SkScalerContext_FreeType_Base(typeface, desc)
++{
++ SkMatrix matrix;
++ fRec.getSingleMatrix(&matrix);
++
++ cairo_font_face_t* fontFace = static_cast<SkCairoFTTypeface*>(typeface)->getFontFace();
++
++ cairo_matrix_t fontMatrix, ctMatrix;
++ cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
++ cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
++
++ // We need to ensure that the font options match for hinting, as generateMetrics()
++ // uses the fScaledFont which uses these font options
++ cairo_font_options_t *fontOptions = cairo_font_options_create();
++
++ FT_Int32 loadFlags = FT_LOAD_DEFAULT;
++
++ if (SkMask::kBW_Format == fRec.fMaskFormat) {
++ // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
++ loadFlags = FT_LOAD_TARGET_MONO;
++ if (fRec.getHinting() == SkPaint::kNo_Hinting) {
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
++ loadFlags = FT_LOAD_NO_HINTING;
++ }
++ } else {
++ switch (fRec.getHinting()) {
++ case SkPaint::kNo_Hinting:
++ loadFlags = FT_LOAD_NO_HINTING;
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
++ break;
++ case SkPaint::kSlight_Hinting:
++ loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
++ break;
++ case SkPaint::kNormal_Hinting:
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
++ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
++ loadFlags = FT_LOAD_FORCE_AUTOHINT;
++ }
++ break;
++ case SkPaint::kFull_Hinting:
++ cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
++ if (fRec.fFlags & SkScalerContext::kAutohinting_Flag) {
++ loadFlags = FT_LOAD_FORCE_AUTOHINT;
++ }
++ if (isLCD(fRec)) {
++ if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
++ loadFlags = FT_LOAD_TARGET_LCD_V;
++ } else {
++ loadFlags = FT_LOAD_TARGET_LCD;
++ }
++ }
++ break;
++ default:
++ SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
++ break;
++ }
++ }
++
++ fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
++
++ if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
++ loadFlags |= FT_LOAD_NO_BITMAP;
++ }
++
++ // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
++ // advances, as fontconfig and cairo do.
++ // See http://code.google.com/p/skia/issues/detail?id=222.
++ loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
++
++ fLoadGlyphFlags = loadFlags;
++}
++
++SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
++{
++ cairo_scaled_font_destroy(fScaledFont);
++}
++
++unsigned SkScalerContext_CairoFT::generateGlyphCount()
++{
++ CairoLockedFTFace faceLock(fScaledFont);
++ return faceLock.getFace()->num_glyphs;
++}
++
++uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar)
++{
++ CairoLockedFTFace faceLock(fScaledFont);
++ return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar));
++}
++
++void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
++{
++ generateMetrics(glyph);
++}
++
++void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
++{
++ SkASSERT(fScaledFont != NULL);
++ cairo_text_extents_t extents;
++ cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 };
++ cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents);
++
++ glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance);
++ glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance);
++ glyph->fWidth = SkToU16(SkScalarCeil(extents.width));
++ glyph->fHeight = SkToU16(SkScalarCeil(extents.height));
++ glyph->fLeft = SkToS16(SkScalarCeil(extents.x_bearing));
++ glyph->fTop = SkToS16(SkScalarCeil(extents.y_bearing));
++ glyph->fLsbDelta = 0;
++ glyph->fRsbDelta = 0;
++}
++
++void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
++{
++ SkASSERT(fScaledFont != NULL);
++ CairoLockedFTFace faceLock(fScaledFont);
++ FT_Face face = faceLock.getFace();
++
++ FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
++
++ if (err != 0) {
++ memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
++ return;
++ }
++
++ generateGlyphImage(face, glyph);
++}
++
++void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path)
++{
++ SkASSERT(fScaledFont != NULL);
++ CairoLockedFTFace faceLock(fScaledFont);
++ FT_Face face = faceLock.getFace();
++
++ SkASSERT(&glyph && path);
++
++ uint32_t flags = fLoadGlyphFlags;
++ flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
++ flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
++
++ FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags);
++
++ if (err != 0) {
++ path->reset();
++ return;
++ }
++
++ generateGlyphPath(face, path);
++}
++
++void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx,
++ SkPaint::FontMetrics* my)
++{
++ SkDEBUGCODE(SkDebugf("SkScalerContext_CairoFT::generateFontMetrics unimplemented\n"));
++}
++
++SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph)
++{
++ SkASSERT(fScaledFont != NULL);
++ CairoLockedFTFace faceLock(fScaledFont);
++ FT_Face face = faceLock.getFace();
++
++ FT_UInt glyphIndex;
++ SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
++ while (glyphIndex != 0) {
++ if (glyphIndex == glyph) {
++ return charCode;
++ }
++ charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
++ }
++
++ return 0;
++}
++
++#ifdef SK_BUILD_FOR_ANDROID
++SkTypeface* SkAndroidNextLogicalTypeface(SkFontID currFontID,
++ SkFontID origFontID) {
++ return NULL;
++}
++#endif
++
++///////////////////////////////////////////////////////////////////////////////
++
++#include "SkFontMgr.h"
++
++SkFontMgr* SkFontMgr::Factory() {
++ // todo
++ return NULL;
++}
++
+--
+1.7.11.7
+