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