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
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/
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
15 * The Original Code is Mozilla Foundation code.
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.
22 * Vladimir Vukicevic <vladimir@pobox.com>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "gfxPlatform.h"
41 #include "gfxWindowsPlatform.h"
42 #elif defined(XP_MACOSX)
43 #include "gfxPlatformMac.h"
44 #include "gfxQuartzFontCache.h"
45 #elif defined(MOZ_WIDGET_GTK2)
46 #include "gfxPlatformGtk.h"
47 #elif defined(XP_BEOS)
48 #include "gfxBeOSPlatform.h"
50 #include "gfxOS2Platform.h"
53 #include "gfxContext.h"
54 #include "gfxImageSurface.h"
55 #include "gfxTextRunCache.h"
56 #include "gfxTextRunWordCache.h"
59 #include "nsServiceManagerUtils.h"
61 #ifdef MOZ_ENABLE_GLITZ
68 #include "nsIPrefService.h"
69 #include "nsIPrefBranch.h"
71 gfxPlatform
*gPlatform
= nsnull
;
73 static cmsHPROFILE gCMSOutputProfile
= nsnull
;
74 static cmsHTRANSFORM gCMSRGBTransform
= nsnull
;
75 static cmsHTRANSFORM gCMSInverseRGBTransform
= nsnull
;
76 static cmsHTRANSFORM gCMSRGBATransform
= nsnull
;
79 gfxPlatform::GetPlatform()
87 NS_ASSERTION(!gPlatform
, "Already started???");
89 gPlatform
= new gfxWindowsPlatform
;
90 #elif defined(XP_MACOSX)
91 gPlatform
= new gfxPlatformMac
;
92 #elif defined(MOZ_WIDGET_GTK2)
93 gPlatform
= new gfxPlatformGtk
;
94 #elif defined(XP_BEOS)
95 gPlatform
= new gfxBeOSPlatform
;
97 gPlatform
= new gfxOS2Platform
;
100 return NS_ERROR_OUT_OF_MEMORY
;
104 #if defined(XP_MACOSX)
105 rv
= gfxQuartzFontCache::Init();
107 NS_ERROR("Could not initialize gfxQuartzFontCache");
113 rv
= gfxFontCache::Init();
115 NS_ERROR("Could not initialize gfxFontCache");
120 rv
= gfxTextRunWordCache::Init();
122 NS_ERROR("Could not initialize gfxTextRunWordCache");
127 rv
= gfxTextRunCache::Init();
129 NS_ERROR("Could not initialize gfxTextRunCache");
138 gfxPlatform::Shutdown()
140 // These may be called before the corresponding subsystems have actually
141 // started up. That's OK, they can handle it.
142 gfxTextRunCache::Shutdown();
143 gfxTextRunWordCache::Shutdown();
144 gfxFontCache::Shutdown();
145 #if defined(XP_MACOSX)
146 gfxQuartzFontCache::Shutdown();
152 gfxPlatform::~gfxPlatform()
154 // The cairo folks think we should only clean up in debug builds,
155 // but we're generally in the habit of trying to shut down as
156 // cleanly as possible even in production code, so call this
157 // cairo_debug_* function unconditionally.
159 // because cairo can assert and thus crash on shutdown, don't do this in release builds
160 #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(NS_TRACE_MALLOC)
161 cairo_debug_reset_static_data();
165 // It would be nice to do this (although it might need to be after
166 // the cairo shutdown that happens in ~gfxPlatform). It even looks
167 // idempotent. But it has fatal assertions that fire if stuff is
168 // leaked, and we hit them.
174 gfxPlatform::UseGlitz()
176 #ifdef MOZ_ENABLE_GLITZ
177 if (gGlitzState
== -1) {
178 if (getenv("MOZ_GLITZ"))
192 gfxPlatform::SetUseGlitz(PRBool use
)
194 gGlitzState
= (use
? 1 : 0);
197 already_AddRefed
<gfxASurface
>
198 gfxPlatform::OptimizeImage(gfxImageSurface
*aSurface
,
199 gfxASurface::gfxImageFormat format
)
201 const gfxIntSize
& surfaceSize
= aSurface
->GetSize();
203 nsRefPtr
<gfxASurface
> optSurface
= CreateOffscreenSurface(surfaceSize
, format
);
204 if (!optSurface
|| optSurface
->CairoStatus() != 0)
207 nsRefPtr
<gfxContext
> tmpCtx(new gfxContext(optSurface
));
208 tmpCtx
->SetOperator(gfxContext::OPERATOR_SOURCE
);
209 tmpCtx
->SetSource(aSurface
);
212 gfxASurface
*ret
= optSurface
;
218 gfxPlatform::GetFontList(const nsACString
& aLangGroup
,
219 const nsACString
& aGenericFamily
,
220 nsStringArray
& aListOfFonts
)
222 return NS_ERROR_NOT_IMPLEMENTED
;
226 gfxPlatform::UpdateFontList()
228 return NS_ERROR_NOT_IMPLEMENTED
;
232 AppendGenericFontFromPref(nsString
& aFonts
, const char *aLangGroup
, const char *aGenericName
)
236 nsCOMPtr
<nsIPref
> prefs(do_GetService(NS_PREF_CONTRACTID
));
240 nsCAutoString prefName
;
241 nsXPIDLString nameValue
, nameListValue
;
243 nsXPIDLString genericName
;
245 genericName
= NS_ConvertASCIItoUTF16(aGenericName
);
247 prefName
.AssignLiteral("font.default.");
248 prefName
.Append(aLangGroup
);
249 prefs
->CopyUnicharPref(prefName
.get(), getter_Copies(genericName
));
252 nsCAutoString genericDotLang
;
253 genericDotLang
.Assign(NS_ConvertUTF16toUTF8(genericName
));
254 genericDotLang
.AppendLiteral(".");
255 genericDotLang
.Append(aLangGroup
);
257 // fetch font.name.xxx value
258 prefName
.AssignLiteral("font.name.");
259 prefName
.Append(genericDotLang
);
260 rv
= prefs
->CopyUnicharPref(prefName
.get(), getter_Copies(nameValue
));
261 if (NS_SUCCEEDED(rv
)) {
262 if (!aFonts
.IsEmpty())
263 aFonts
.AppendLiteral(", ");
264 aFonts
.Append(nameValue
);
267 // fetch font.name-list.xxx value
268 prefName
.AssignLiteral("font.name-list.");
269 prefName
.Append(genericDotLang
);
270 rv
= prefs
->CopyUnicharPref(prefName
.get(), getter_Copies(nameListValue
));
271 if (NS_SUCCEEDED(rv
) && !nameListValue
.Equals(nameValue
)) {
272 if (!aFonts
.IsEmpty())
273 aFonts
.AppendLiteral(", ");
274 aFonts
.Append(nameListValue
);
279 gfxPlatform::GetPrefFonts(const char *aLangGroup
, nsString
& aFonts
, PRBool aAppendUnicode
)
283 AppendGenericFontFromPref(aFonts
, aLangGroup
, nsnull
);
285 AppendGenericFontFromPref(aFonts
, "x-unicode", nsnull
);
289 gfxPlatform::IsCMSEnabled()
291 static PRBool sEnabled
= -1;
292 if (sEnabled
== -1) {
294 nsCOMPtr
<nsIPrefBranch
> prefs
= do_GetService(NS_PREFSERVICE_CONTRACTID
);
298 prefs
->GetBoolPref("gfx.color_management.enabled", &enabled
);
299 if (NS_SUCCEEDED(rv
)) {
308 gfxPlatform::GetPlatformCMSOutputProfile()
314 gfxPlatform::GetCMSOutputProfile()
316 if (!gCMSOutputProfile
) {
317 /* Default lcms error action is to abort on error - change */
319 cmsErrorAction(LCMS_ERROR_SHOW
);
321 cmsErrorAction(LCMS_ERROR_IGNORE
);
324 nsCOMPtr
<nsIPrefBranch
> prefs
= do_GetService(NS_PREFSERVICE_CONTRACTID
);
326 nsXPIDLCString fname
;
328 prefs
->GetCharPref("gfx.color_management.display_profile",
329 getter_Copies(fname
));
330 if (NS_SUCCEEDED(rv
) && !fname
.IsEmpty()) {
331 gCMSOutputProfile
= cmsOpenProfileFromFile(fname
, "r");
333 if (gCMSOutputProfile
)
335 "ICM profile read from %s successfully\n",
341 if (!gCMSOutputProfile
) {
343 gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfile();
346 if (!gCMSOutputProfile
) {
347 gCMSOutputProfile
= cmsCreate_sRGBProfile();
351 return gCMSOutputProfile
;
355 gfxPlatform::GetCMSRGBTransform()
357 if (!gCMSRGBTransform
) {
358 cmsHPROFILE inProfile
, outProfile
;
359 outProfile
= GetCMSOutputProfile();
360 inProfile
= cmsCreate_sRGBProfile();
362 if (!inProfile
|| !outProfile
)
365 gCMSRGBTransform
= cmsCreateTransform(inProfile
, TYPE_RGB_8
,
366 outProfile
, TYPE_RGB_8
,
367 INTENT_PERCEPTUAL
, 0);
370 return gCMSRGBTransform
;
374 gfxPlatform::GetCMSInverseRGBTransform()
376 if (!gCMSInverseRGBTransform
) {
377 cmsHPROFILE inProfile
, outProfile
;
378 inProfile
= GetCMSOutputProfile();
379 outProfile
= cmsCreate_sRGBProfile();
381 if (!inProfile
|| !outProfile
)
384 gCMSInverseRGBTransform
= cmsCreateTransform(inProfile
, TYPE_RGB_8
,
385 outProfile
, TYPE_RGB_8
,
386 INTENT_PERCEPTUAL
, 0);
389 return gCMSInverseRGBTransform
;
393 gfxPlatform::GetCMSRGBATransform()
395 if (!gCMSRGBATransform
) {
396 cmsHPROFILE inProfile
, outProfile
;
397 outProfile
= GetCMSOutputProfile();
398 inProfile
= cmsCreate_sRGBProfile();
400 if (!inProfile
|| !outProfile
)
403 gCMSRGBATransform
= cmsCreateTransform(inProfile
, TYPE_RGBA_8
,
404 outProfile
, TYPE_RGBA_8
,
405 INTENT_PERCEPTUAL
, 0);
408 return gCMSRGBATransform
;