1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Foundation code.
16 : *
17 : * The Initial Developer of the Original Code is Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2005
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Vladimir Vukicevic <vladimir@pobox.com>
23 : * Masayuki Nakano <masayuki@d-toybox.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef GFX_PLATFORM_H
40 : #define GFX_PLATFORM_H
41 :
42 : #include "prtypes.h"
43 : #include "prlog.h"
44 : #include "nsTArray.h"
45 : #include "nsStringGlue.h"
46 : #include "nsIObserver.h"
47 :
48 : #include "gfxTypes.h"
49 : #include "gfxASurface.h"
50 : #include "gfxColor.h"
51 :
52 : #include "qcms.h"
53 :
54 : #include "gfx2DGlue.h"
55 : #include "mozilla/RefPtr.h"
56 : #include "GfxInfoCollector.h"
57 :
58 : #ifdef XP_OS2
59 : #undef OS2EMX_PLAIN_CHAR
60 : #endif
61 :
62 : class gfxImageSurface;
63 : class gfxFont;
64 : class gfxFontGroup;
65 : struct gfxFontStyle;
66 : class gfxUserFontSet;
67 : class gfxFontEntry;
68 : class gfxProxyFontEntry;
69 : class gfxPlatformFontList;
70 : class gfxTextRun;
71 : class nsIURI;
72 : class nsIAtom;
73 :
74 : extern mozilla::gfx::UserDataKey kThebesSurfaceKey;
75 : void DestroyThebesSurface(void *data);
76 :
77 : extern cairo_user_data_key_t kDrawTarget;
78 :
79 : // pref lang id's for font prefs
80 : // !!! needs to match the list of pref font.default.xx entries listed in all.js !!!
81 : // !!! don't use as bit mask, this may grow larger !!!
82 :
83 : enum eFontPrefLang {
84 : eFontPrefLang_Western = 0,
85 : eFontPrefLang_CentEuro = 1,
86 : eFontPrefLang_Japanese = 2,
87 : eFontPrefLang_ChineseTW = 3,
88 : eFontPrefLang_ChineseCN = 4,
89 : eFontPrefLang_ChineseHK = 5,
90 : eFontPrefLang_Korean = 6,
91 : eFontPrefLang_Cyrillic = 7,
92 : eFontPrefLang_Baltic = 8,
93 : eFontPrefLang_Greek = 9,
94 : eFontPrefLang_Turkish = 10,
95 : eFontPrefLang_Thai = 11,
96 : eFontPrefLang_Hebrew = 12,
97 : eFontPrefLang_Arabic = 13,
98 : eFontPrefLang_Devanagari = 14,
99 : eFontPrefLang_Tamil = 15,
100 : eFontPrefLang_Armenian = 16,
101 : eFontPrefLang_Bengali = 17,
102 : eFontPrefLang_Canadian = 18,
103 : eFontPrefLang_Ethiopic = 19,
104 : eFontPrefLang_Georgian = 20,
105 : eFontPrefLang_Gujarati = 21,
106 : eFontPrefLang_Gurmukhi = 22,
107 : eFontPrefLang_Khmer = 23,
108 : eFontPrefLang_Malayalam = 24,
109 : eFontPrefLang_Oriya = 25,
110 : eFontPrefLang_Telugu = 26,
111 : eFontPrefLang_Kannada = 27,
112 : eFontPrefLang_Sinhala = 28,
113 : eFontPrefLang_Tibetan = 29,
114 :
115 : eFontPrefLang_LangCount = 30, // except Others and UserDefined.
116 :
117 : eFontPrefLang_Others = 30, // x-unicode
118 : eFontPrefLang_UserDefined = 31,
119 :
120 : eFontPrefLang_CJKSet = 32, // special code for CJK set
121 : eFontPrefLang_AllCount = 33
122 : };
123 :
124 : enum eCMSMode {
125 : eCMSMode_Off = 0, // No color management
126 : eCMSMode_All = 1, // Color manage everything
127 : eCMSMode_TaggedOnly = 2, // Color manage tagged Images Only
128 : eCMSMode_AllCount = 3
129 : };
130 :
131 : enum eGfxLog {
132 : // all font enumerations, localized names, fullname/psnames, cmap loads
133 : eGfxLog_fontlist = 0,
134 : // timing info on font initialization
135 : eGfxLog_fontinit = 1,
136 : // dump text runs, font matching, system fallback for content
137 : eGfxLog_textrun = 2,
138 : // dump text runs, font matching, system fallback for chrome
139 : eGfxLog_textrunui = 3,
140 : // dump cmap coverage data as they are loaded
141 : eGfxLog_cmapdata = 4
142 : };
143 :
144 : // when searching through pref langs, max number of pref langs
145 : const PRUint32 kMaxLenPrefLangList = 32;
146 :
147 : #define UNINITIALIZED_VALUE (-1)
148 :
149 : typedef gfxASurface::gfxImageFormat gfxImageFormat;
150 :
151 : inline const char*
152 : GetBackendName(mozilla::gfx::BackendType aBackend)
153 : {
154 : switch (aBackend) {
155 : case mozilla::gfx::BACKEND_DIRECT2D:
156 : return "direct2d";
157 : case mozilla::gfx::BACKEND_COREGRAPHICS:
158 : return "quartz";
159 : case mozilla::gfx::BACKEND_CAIRO:
160 : return "cairo";
161 : case mozilla::gfx::BACKEND_SKIA:
162 : return "skia";
163 : case mozilla::gfx::BACKEND_NONE:
164 : return "none";
165 : }
166 : MOZ_NOT_REACHED("Incomplet switch");
167 : }
168 :
169 : class THEBES_API gfxPlatform {
170 : public:
171 : /**
172 : * Return a pointer to the current active platform.
173 : * This is a singleton; it contains mostly convenience
174 : * functions to obtain platform-specific objects.
175 : */
176 : static gfxPlatform *GetPlatform();
177 :
178 : /**
179 : * Start up Thebes.
180 : */
181 : static void Init();
182 :
183 : /**
184 : * Shut down Thebes.
185 : * Init() arranges for this to be called at an appropriate time.
186 : */
187 : static void Shutdown();
188 :
189 : /**
190 : * Create an offscreen surface of the given dimensions
191 : * and image format.
192 : */
193 : virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
194 : gfxASurface::gfxContentType contentType) = 0;
195 :
196 :
197 : virtual already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
198 : gfxASurface::gfxImageFormat format);
199 :
200 : virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
201 : CreateDrawTargetForSurface(gfxASurface *aSurface);
202 :
203 : virtual mozilla::RefPtr<mozilla::gfx::SourceSurface>
204 : GetSourceSurfaceForSurface(mozilla::gfx::DrawTarget *aTarget, gfxASurface *aSurface);
205 :
206 : virtual mozilla::RefPtr<mozilla::gfx::ScaledFont>
207 : GetScaledFontForFont(gfxFont *aFont);
208 :
209 : virtual already_AddRefed<gfxASurface>
210 : GetThebesSurfaceForDrawTarget(mozilla::gfx::DrawTarget *aTarget);
211 :
212 : virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
213 : CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
214 :
215 : virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend) { return false; }
216 :
217 : void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
218 : mozilla::gfx::BackendType backend;
219 : if (SupportsAzure(backend)) {
220 : aObj.DefineProperty("AzureBackend", GetBackendName(backend));
221 : }
222 : }
223 :
224 : /*
225 : * Font bits
226 : */
227 :
228 : virtual void SetupClusterBoundaries(gfxTextRun *aTextRun, const PRUnichar *aString);
229 :
230 : /**
231 : * Fill aListOfFonts with the results of querying the list of font names
232 : * that correspond to the given language group or generic font family
233 : * (or both, or neither).
234 : */
235 : virtual nsresult GetFontList(nsIAtom *aLangGroup,
236 : const nsACString& aGenericFamily,
237 : nsTArray<nsString>& aListOfFonts);
238 :
239 : /**
240 : * Rebuilds the any cached system font lists
241 : */
242 : virtual nsresult UpdateFontList();
243 :
244 : /**
245 : * Create the platform font-list object (gfxPlatformFontList concrete subclass).
246 : * This function is responsible to create the appropriate subclass of
247 : * gfxPlatformFontList *and* to call its InitFontList() method.
248 : */
249 : virtual gfxPlatformFontList *CreatePlatformFontList() {
250 : NS_NOTREACHED("oops, this platform doesn't have a gfxPlatformFontList implementation");
251 : return nsnull;
252 : }
253 :
254 : /**
255 : * Font name resolver, this returns actual font name(s) by the callback
256 : * function. If the font doesn't exist, the callback function is not called.
257 : * If the callback function returns false, the aAborted value is set to
258 : * true, otherwise, false.
259 : */
260 : typedef bool (*FontResolverCallback) (const nsAString& aName,
261 : void *aClosure);
262 : virtual nsresult ResolveFontName(const nsAString& aFontName,
263 : FontResolverCallback aCallback,
264 : void *aClosure,
265 : bool& aAborted) = 0;
266 :
267 : /**
268 : * Resolving a font name to family name. The result MUST be in the result of GetFontList().
269 : * If the name doesn't in the system, aFamilyName will be empty string, but not failed.
270 : */
271 : virtual nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) = 0;
272 :
273 : /**
274 : * Create the appropriate platform font group
275 : */
276 : virtual gfxFontGroup *CreateFontGroup(const nsAString& aFamilies,
277 : const gfxFontStyle *aStyle,
278 : gfxUserFontSet *aUserFontSet) = 0;
279 :
280 :
281 : /**
282 : * Look up a local platform font using the full font face name.
283 : * (Needed to support @font-face src local().)
284 : * Ownership of the returned gfxFontEntry is passed to the caller,
285 : * who must either AddRef() or delete.
286 : */
287 : virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
288 : const nsAString& aFontName)
289 : { return nsnull; }
290 :
291 : /**
292 : * Activate a platform font. (Needed to support @font-face src url().)
293 : * aFontData is a NS_Malloc'ed block that must be freed by this function
294 : * (or responsibility passed on) when it is no longer needed; the caller
295 : * will NOT free it.
296 : * Ownership of the returned gfxFontEntry is passed to the caller,
297 : * who must either AddRef() or delete.
298 : */
299 : virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
300 : const PRUint8 *aFontData,
301 : PRUint32 aLength);
302 :
303 : /**
304 : * Whether to allow downloadable fonts via @font-face rules
305 : */
306 : bool DownloadableFontsEnabled();
307 :
308 : /**
309 : * Whether to sanitize downloaded fonts using the OTS library
310 : */
311 : bool SanitizeDownloadedFonts();
312 :
313 : /**
314 : * True when hinting should be enabled. This setting shouldn't
315 : * change per gecko process, while the process is live. If so the
316 : * results are not defined.
317 : *
318 : * NB: this bit is only honored by the FT2 backend, currently.
319 : */
320 : virtual bool FontHintingEnabled() { return true; }
321 :
322 : /**
323 : * Whether to check all font cmaps during system font fallback
324 : */
325 : bool UseCmapsDuringSystemFallback();
326 :
327 : #ifdef MOZ_GRAPHITE
328 : /**
329 : * Whether to use the SIL Graphite rendering engine
330 : * (for fonts that include Graphite tables)
331 : */
332 : bool UseGraphiteShaping();
333 : #endif
334 :
335 : /**
336 : * Whether to use the harfbuzz shaper (depending on script complexity).
337 : *
338 : * This allows harfbuzz to be enabled selectively via the preferences.
339 : */
340 : bool UseHarfBuzzForScript(PRInt32 aScriptCode);
341 :
342 : // check whether format is supported on a platform or not (if unclear, returns true)
343 : virtual bool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags) { return false; }
344 :
345 : void GetPrefFonts(nsIAtom *aLanguage, nsString& array, bool aAppendUnicode = true);
346 :
347 : // in some situations, need to make decisions about ambiguous characters, may need to look at multiple pref langs
348 : void GetLangPrefs(eFontPrefLang aPrefLangs[], PRUint32 &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang);
349 :
350 : /**
351 : * Iterate over pref fonts given a list of lang groups. For a single lang
352 : * group, multiple pref fonts are possible. If error occurs, returns false,
353 : * true otherwise. Callback returns false to abort process.
354 : */
355 : typedef bool (*PrefFontCallback) (eFontPrefLang aLang, const nsAString& aName,
356 : void *aClosure);
357 : static bool ForEachPrefFont(eFontPrefLang aLangArray[], PRUint32 aLangArrayLen,
358 : PrefFontCallback aCallback,
359 : void *aClosure);
360 :
361 : // convert a lang group to enum constant (i.e. "zh-TW" ==> eFontPrefLang_ChineseTW)
362 : static eFontPrefLang GetFontPrefLangFor(const char* aLang);
363 :
364 : // convert a lang group atom to enum constant
365 : static eFontPrefLang GetFontPrefLangFor(nsIAtom *aLang);
366 :
367 : // convert a enum constant to lang group string (i.e. eFontPrefLang_ChineseTW ==> "zh-TW")
368 : static const char* GetPrefLangName(eFontPrefLang aLang);
369 :
370 : // map a Unicode range (based on char code) to a font language for Preferences
371 : static eFontPrefLang GetFontPrefLangFor(PRUint8 aUnicodeRange);
372 :
373 : // returns true if a pref lang is CJK
374 : static bool IsLangCJK(eFontPrefLang aLang);
375 :
376 : // helper method to add a pref lang to an array, if not already in array
377 : static void AppendPrefLang(eFontPrefLang aPrefLangs[], PRUint32& aLen, eFontPrefLang aAddLang);
378 :
379 : // returns a list of commonly used fonts for a given character
380 : // these are *possible* matches, no cmap-checking is done at this level
381 : virtual void GetCommonFallbackFonts(const PRUint32 /*aCh*/,
382 : PRInt32 /*aRunScript*/,
383 : nsTArray<const char*>& /*aFontList*/)
384 : {
385 : // platform-specific override, by default do nothing
386 : }
387 :
388 : // helper method to indicate if we want to use Azure content drawing
389 : static bool UseAzureContentDrawing();
390 :
391 : /**
392 : * Are we going to try color management?
393 : */
394 : static eCMSMode GetCMSMode();
395 :
396 : /**
397 : * Determines the rendering intent for color management.
398 : *
399 : * If the value in the pref gfx.color_management.rendering_intent is a
400 : * valid rendering intent as defined in gfx/qcms/qcms.h, that
401 : * value is returned. Otherwise, -1 is returned and the embedded intent
402 : * should be used.
403 : *
404 : * See bug 444014 for details.
405 : */
406 : static int GetRenderingIntent();
407 :
408 : /**
409 : * Convert a pixel using a cms transform in an endian-aware manner.
410 : *
411 : * Sets 'out' to 'in' if transform is NULL.
412 : */
413 : static void TransformPixel(const gfxRGBA& in, gfxRGBA& out, qcms_transform *transform);
414 :
415 : /**
416 : * Return the output device ICC profile.
417 : */
418 : static qcms_profile* GetCMSOutputProfile();
419 :
420 : /**
421 : * Return the sRGB ICC profile.
422 : */
423 : static qcms_profile* GetCMSsRGBProfile();
424 :
425 : /**
426 : * Return sRGB -> output device transform.
427 : */
428 : static qcms_transform* GetCMSRGBTransform();
429 :
430 : /**
431 : * Return output -> sRGB device transform.
432 : */
433 : static qcms_transform* GetCMSInverseRGBTransform();
434 :
435 : /**
436 : * Return sRGBA -> output device transform.
437 : */
438 : static qcms_transform* GetCMSRGBATransform();
439 :
440 : virtual void FontsPrefsChanged(const char *aPref);
441 :
442 : PRInt32 GetBidiNumeralOption();
443 :
444 : /**
445 : * Returns a 1x1 surface that can be used to create graphics contexts
446 : * for measuring text etc as if they will be rendered to the screen
447 : */
448 0 : gfxASurface* ScreenReferenceSurface() { return mScreenReferenceSurface; }
449 :
450 : virtual gfxImageFormat GetOffscreenFormat()
451 : { return gfxASurface::FormatFromContent(gfxASurface::CONTENT_COLOR); }
452 :
453 : /**
454 : * Returns a logger if one is available and logging is enabled
455 : */
456 : static PRLogModuleInfo* GetLog(eGfxLog aWhichLog);
457 :
458 : protected:
459 : gfxPlatform();
460 : virtual ~gfxPlatform();
461 :
462 : void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], PRUint32 &aLen,
463 : eFontPrefLang aCharLang, eFontPrefLang aPageLang);
464 :
465 : PRInt8 mAllowDownloadableFonts;
466 : PRInt8 mDownloadableFontsSanitize;
467 : #ifdef MOZ_GRAPHITE
468 : PRInt8 mGraphiteShapingEnabled;
469 : #endif
470 :
471 : PRInt8 mBidiNumeralOption;
472 :
473 : // whether to always search font cmaps globally
474 : // when doing system font fallback
475 : PRInt8 mFallbackUsesCmaps;
476 :
477 : // which scripts should be shaped with harfbuzz
478 : PRInt32 mUseHarfBuzzScripts;
479 :
480 : // The preferred draw target backend to use
481 : mozilla::gfx::BackendType mPreferredDrawTargetBackend;
482 :
483 : private:
484 : virtual qcms_profile* GetPlatformCMSOutputProfile();
485 :
486 : nsRefPtr<gfxASurface> mScreenReferenceSurface;
487 : nsTArray<PRUint32> mCJKPrefLangs;
488 : nsCOMPtr<nsIObserver> mSRGBOverrideObserver;
489 : nsCOMPtr<nsIObserver> mFontPrefsObserver;
490 : mozilla::widget::GfxInfoCollector<gfxPlatform> mAzureBackendCollector;
491 : };
492 :
493 : #endif /* GFX_PLATFORM_H */
|