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.
2 /*
3 * Copyright 2012 Mozilla Foundation
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
9 #include "cairo.h"
10 #include "cairo-ft.h"
12 #include "SkFontHost_FreeType_common.h"
14 #include "SkAdvancedTypefaceMetrics.h"
15 #include "SkFontHost.h"
16 #include "SkPath.h"
17 #include "SkScalerContext.h"
18 #include "SkTypefaceCache.h"
20 #include <ft2build.h>
21 #include FT_FREETYPE_H
23 #ifndef SK_FONTHOST_CAIRO_STANDALONE
24 #define SK_FONTHOST_CAIRO_STANDALONE 1
25 #endif
27 static cairo_user_data_key_t kSkTypefaceKey;
29 class SkScalerContext_CairoFT : public SkScalerContext_FreeType_Base {
30 public:
31 SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc);
32 virtual ~SkScalerContext_CairoFT();
34 protected:
35 virtual unsigned generateGlyphCount() SK_OVERRIDE;
36 virtual uint16_t generateCharToGlyph(SkUnichar uniChar) SK_OVERRIDE;
37 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
38 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
39 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
40 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
41 virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
42 SkPaint::FontMetrics* my) SK_OVERRIDE;
43 virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
44 private:
45 cairo_scaled_font_t* fScaledFont;
46 uint32_t fLoadGlyphFlags;
47 };
49 class CairoLockedFTFace {
50 public:
51 CairoLockedFTFace(cairo_scaled_font_t* scaledFont)
52 : fScaledFont(scaledFont)
53 , fFace(cairo_ft_scaled_font_lock_face(scaledFont))
54 {}
56 ~CairoLockedFTFace()
57 {
58 cairo_ft_scaled_font_unlock_face(fScaledFont);
59 }
61 FT_Face getFace()
62 {
63 return fFace;
64 }
66 private:
67 cairo_scaled_font_t* fScaledFont;
68 FT_Face fFace;
69 };
71 class SkCairoFTTypeface : public SkTypeface {
72 public:
73 static SkTypeface* CreateTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth) {
74 SkASSERT(fontFace != NULL);
75 SkASSERT(cairo_font_face_get_type(fontFace) == CAIRO_FONT_TYPE_FT);
77 SkFontID newId = SkTypefaceCache::NewFontID();
79 return SkNEW_ARGS(SkCairoFTTypeface, (fontFace, style, newId, isFixedWidth));
80 }
82 cairo_font_face_t* getFontFace() {
83 return fFontFace;
84 }
86 virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; }
88 virtual SkAdvancedTypefaceMetrics*
89 onGetAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::PerGlyphInfo,
90 const uint32_t*, uint32_t) const SK_OVERRIDE
91 {
92 SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetAdvancedTypefaceMetrics unimplemented\n"));
93 return NULL;
94 }
96 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor* desc) const SK_OVERRIDE
97 {
98 return SkNEW_ARGS(SkScalerContext_CairoFT, (const_cast<SkCairoFTTypeface*>(this), desc));
99 }
101 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE
102 {
103 SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onFilterRec unimplemented\n"));
104 }
106 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
107 {
108 SkDEBUGCODE(SkDebugf("SkCairoFTTypeface::onGetFontDescriptor unimplemented\n"));
109 }
111 virtual int onCharsToGlyphs(void const*, SkTypeface::Encoding, uint16_t*, int) const SK_OVERRIDE
112 {
113 return 0;
114 }
116 virtual int onCountGlyphs() const SK_OVERRIDE
117 {
118 return 0;
119 }
121 virtual int onGetUPEM() const SK_OVERRIDE
122 {
123 return 0;
124 }
126 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE
127 {
128 return NULL;
129 }
131 virtual int onGetTableTags(SkFontTableTag*) const SK_OVERRIDE
132 {
133 return 0;
134 }
136 virtual size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const SK_OVERRIDE
137 {
138 return 0;
139 }
141 private:
143 SkCairoFTTypeface(cairo_font_face_t* fontFace, SkTypeface::Style style, SkFontID id, bool isFixedWidth)
144 : SkTypeface(style, id, isFixedWidth)
145 , fFontFace(fontFace)
146 {
147 cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL);
148 cairo_font_face_reference(fFontFace);
149 }
151 ~SkCairoFTTypeface()
152 {
153 cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL);
154 cairo_font_face_destroy(fFontFace);
155 }
157 cairo_font_face_t* fFontFace;
158 };
160 SkTypeface* SkCreateTypefaceFromCairoFont(cairo_font_face_t* fontFace, SkTypeface::Style style, bool isFixedWidth)
161 {
162 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(cairo_font_face_get_user_data(fontFace, &kSkTypefaceKey));
164 if (typeface) {
165 typeface->ref();
166 } else {
167 typeface = SkCairoFTTypeface::CreateTypeface(fontFace, style, isFixedWidth);
168 SkTypefaceCache::Add(typeface, style);
169 }
171 return typeface;
172 }
174 #if defined(SK_FONTHOST_DOES_NOT_USE_FONTMGR) && SK_FONTHOST_CAIRO_STANDALONE
175 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
176 const char famillyName[],
177 SkTypeface::Style style)
178 {
179 SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented");
180 return NULL;
181 }
183 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*)
184 {
185 SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
186 return NULL;
187 }
189 SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*)
190 {
191 SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
192 return NULL;
193 }
194 #endif
196 ///////////////////////////////////////////////////////////////////////////////
198 static bool isLCD(const SkScalerContext::Rec& rec) {
199 switch (rec.fMaskFormat) {
200 case SkMask::kLCD16_Format:
201 case SkMask::kLCD32_Format:
202 return true;
203 default:
204 return false;
205 }
206 }
208 ///////////////////////////////////////////////////////////////////////////////
209 SkScalerContext_CairoFT::SkScalerContext_CairoFT(SkTypeface* typeface, const SkDescriptor* desc)
210 : SkScalerContext_FreeType_Base(typeface, desc)
211 {
212 SkMatrix matrix;
213 fRec.getSingleMatrix(&matrix);
215 cairo_font_face_t* fontFace = static_cast<SkCairoFTTypeface*>(typeface)->getFontFace();
217 cairo_matrix_t fontMatrix, ctMatrix;
218 cairo_matrix_init(&fontMatrix, matrix.getScaleX(), matrix.getSkewY(), matrix.getSkewX(), matrix.getScaleY(), 0.0, 0.0);
219 cairo_matrix_init_scale(&ctMatrix, 1.0, 1.0);
221 // We need to ensure that the font options match for hinting, as generateMetrics()
222 // uses the fScaledFont which uses these font options
223 cairo_font_options_t *fontOptions = cairo_font_options_create();
225 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
227 if (SkMask::kBW_Format == fRec.fMaskFormat) {
228 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
229 loadFlags = FT_LOAD_TARGET_MONO;
230 if (fRec.getHinting() == SkPaint::kNo_Hinting) {
231 cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
232 loadFlags = FT_LOAD_NO_HINTING;
233 }
234 } else {
235 switch (fRec.getHinting()) {
236 case SkPaint::kNo_Hinting:
237 loadFlags = FT_LOAD_NO_HINTING;
238 cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_NONE);
239 break;
240 case SkPaint::kSlight_Hinting:
241 loadFlags = FT_LOAD_TARGET_LIGHT; // This implies FORCE_AUTOHINT
242 cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_SLIGHT);
243 break;
244 case SkPaint::kNormal_Hinting:
245 cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_MEDIUM);
246 if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
247 loadFlags = FT_LOAD_FORCE_AUTOHINT;
248 }
249 break;
250 case SkPaint::kFull_Hinting:
251 cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
252 if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
253 loadFlags = FT_LOAD_FORCE_AUTOHINT;
254 }
255 if (isLCD(fRec)) {
256 if (SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag)) {
257 loadFlags = FT_LOAD_TARGET_LCD_V;
258 } else {
259 loadFlags = FT_LOAD_TARGET_LCD;
260 }
261 }
262 break;
263 default:
264 SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting());
265 break;
266 }
267 }
269 fScaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctMatrix, fontOptions);
271 if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
272 loadFlags |= FT_LOAD_NO_BITMAP;
273 }
275 // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
276 // advances, as fontconfig and cairo do.
277 // See http://code.google.com/p/skia/issues/detail?id=222.
278 loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
280 fLoadGlyphFlags = loadFlags;
281 }
283 SkScalerContext_CairoFT::~SkScalerContext_CairoFT()
284 {
285 cairo_scaled_font_destroy(fScaledFont);
286 }
288 unsigned SkScalerContext_CairoFT::generateGlyphCount()
289 {
290 CairoLockedFTFace faceLock(fScaledFont);
291 return faceLock.getFace()->num_glyphs;
292 }
294 uint16_t SkScalerContext_CairoFT::generateCharToGlyph(SkUnichar uniChar)
295 {
296 CairoLockedFTFace faceLock(fScaledFont);
297 return SkToU16(FT_Get_Char_Index(faceLock.getFace(), uniChar));
298 }
300 void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph)
301 {
302 generateMetrics(glyph);
303 }
305 void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
306 {
307 SkASSERT(fScaledFont != NULL);
308 cairo_text_extents_t extents;
309 cairo_glyph_t cairoGlyph = { glyph->getGlyphID(fBaseGlyphCount), 0.0, 0.0 };
310 cairo_scaled_font_glyph_extents(fScaledFont, &cairoGlyph, 1, &extents);
312 glyph->fAdvanceX = SkDoubleToFixed(extents.x_advance);
313 glyph->fAdvanceY = SkDoubleToFixed(extents.y_advance);
314 glyph->fWidth = SkToU16(SkScalarCeilToInt(extents.width));
315 glyph->fHeight = SkToU16(SkScalarCeilToInt(extents.height));
316 glyph->fLeft = SkToS16(SkScalarCeilToInt(extents.x_bearing));
317 glyph->fTop = SkToS16(SkScalarCeilToInt(extents.y_bearing));
318 glyph->fLsbDelta = 0;
319 glyph->fRsbDelta = 0;
320 }
322 void SkScalerContext_CairoFT::generateImage(const SkGlyph& glyph)
323 {
324 SkASSERT(fScaledFont != NULL);
325 CairoLockedFTFace faceLock(fScaledFont);
326 FT_Face face = faceLock.getFace();
328 FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), fLoadGlyphFlags);
330 if (err != 0) {
331 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
332 return;
333 }
335 generateGlyphImage(face, glyph);
336 }
338 void SkScalerContext_CairoFT::generatePath(const SkGlyph& glyph, SkPath* path)
339 {
340 SkASSERT(fScaledFont != NULL);
341 CairoLockedFTFace faceLock(fScaledFont);
342 FT_Face face = faceLock.getFace();
344 SkASSERT(&glyph && path);
346 uint32_t flags = fLoadGlyphFlags;
347 flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
348 flags &= ~FT_LOAD_RENDER; // don't scan convert (we just want the outline)
350 FT_Error err = FT_Load_Glyph(face, glyph.getGlyphID(fBaseGlyphCount), flags);
352 if (err != 0) {
353 path->reset();
354 return;
355 }
357 generateGlyphPath(face, path);
358 }
360 void SkScalerContext_CairoFT::generateFontMetrics(SkPaint::FontMetrics* mx,
361 SkPaint::FontMetrics* my)
362 {
363 SkDEBUGCODE(SkDebugf("SkScalerContext_CairoFT::generateFontMetrics unimplemented\n"));
364 }
366 SkUnichar SkScalerContext_CairoFT::generateGlyphToChar(uint16_t glyph)
367 {
368 SkASSERT(fScaledFont != NULL);
369 CairoLockedFTFace faceLock(fScaledFont);
370 FT_Face face = faceLock.getFace();
372 FT_UInt glyphIndex;
373 SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
374 while (glyphIndex != 0) {
375 if (glyphIndex == glyph) {
376 return charCode;
377 }
378 charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
379 }
381 return 0;
382 }
384 ///////////////////////////////////////////////////////////////////////////////
386 #include "SkFontMgr.h"
388 SkFontMgr* SkFontMgr::Factory() {
389 // todo
390 return NULL;
391 }