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 gCMSRGBATransform
= nsnull
;
78 gfxPlatform::GetPlatform()
86 NS_ASSERTION(!gPlatform
, "Already started???");
88 gPlatform
= new gfxWindowsPlatform
;
89 #elif defined(XP_MACOSX)
90 gPlatform
= new gfxPlatformMac
;
91 #elif defined(MOZ_WIDGET_GTK2)
92 gPlatform
= new gfxPlatformGtk
;
93 #elif defined(XP_BEOS)
94 gPlatform
= new gfxBeOSPlatform
;
96 gPlatform
= new gfxOS2Platform
;
99 return NS_ERROR_OUT_OF_MEMORY
;
103 #if defined(XP_MACOSX)
104 rv
= gfxQuartzFontCache::Init();
106 NS_ERROR("Could not initialize gfxQuartzFontCache");
112 rv
= gfxFontCache::Init();
114 NS_ERROR("Could not initialize gfxFontCache");
119 rv
= gfxTextRunWordCache::Init();
121 NS_ERROR("Could not initialize gfxTextRunWordCache");
126 rv
= gfxTextRunCache::Init();
128 NS_ERROR("Could not initialize gfxTextRunCache");
137 gfxPlatform::Shutdown()
139 // These may be called before the corresponding subsystems have actually
140 // started up. That's OK, they can handle it.
141 gfxTextRunCache::Shutdown();
142 gfxTextRunWordCache::Shutdown();
143 gfxFontCache::Shutdown();
144 #if defined(XP_MACOSX)
145 gfxQuartzFontCache::Shutdown();
151 gfxPlatform::~gfxPlatform()
153 // The cairo folks think we should only clean up in debug builds,
154 // but we're generally in the habit of trying to shut down as
155 // cleanly as possible even in production code, so call this
156 // cairo_debug_* function unconditionally.
157 cairo_debug_reset_static_data();
161 gfxPlatform::UseGlitz()
163 #ifdef MOZ_ENABLE_GLITZ
164 if (gGlitzState
== -1) {
165 if (getenv("MOZ_GLITZ"))
179 gfxPlatform::SetUseGlitz(PRBool use
)
181 gGlitzState
= (use
? 1 : 0);
185 gfxPlatform::DoesARGBImageDataHaveAlpha(PRUint8
* data
,
192 for (PRUint32 j
= 0; j
< height
; j
++) {
193 r
= (PRUint32
*) (data
+ stride
*j
);
194 for (PRUint32 i
= 0; i
< width
; i
++) {
195 if ((*r
++ & 0xff000000) != 0xff000000) {
204 already_AddRefed
<gfxASurface
>
205 gfxPlatform::OptimizeImage(gfxImageSurface
*aSurface
)
207 const gfxIntSize
& surfaceSize
= aSurface
->GetSize();
209 gfxASurface::gfxImageFormat realFormat
= aSurface
->Format();
211 if (realFormat
== gfxASurface::ImageFormatARGB32
) {
212 // this might not really need alpha; figure that out
213 if (!DoesARGBImageDataHaveAlpha(aSurface
->Data(),
218 realFormat
= gfxASurface::ImageFormatRGB24
;
222 nsRefPtr
<gfxASurface
> optSurface
= CreateOffscreenSurface(surfaceSize
, realFormat
);
227 nsRefPtr
<gfxContext
> tmpCtx(new gfxContext(optSurface
));
228 tmpCtx
->SetOperator(gfxContext::OPERATOR_SOURCE
);
229 tmpCtx
->SetSource(aSurface
);
232 gfxASurface
*ret
= optSurface
;
238 gfxPlatform::GetFontList(const nsACString
& aLangGroup
,
239 const nsACString
& aGenericFamily
,
240 nsStringArray
& aListOfFonts
)
242 return NS_ERROR_NOT_IMPLEMENTED
;
246 gfxPlatform::UpdateFontList()
248 return NS_ERROR_NOT_IMPLEMENTED
;
252 AppendGenericFontFromPref(nsString
& aFonts
, const char *aLangGroup
, const char *aGenericName
)
256 nsCOMPtr
<nsIPref
> prefs(do_GetService(NS_PREF_CONTRACTID
));
260 nsCAutoString prefName
;
263 nsXPIDLString genericName
;
265 genericName
= NS_ConvertASCIItoUTF16(aGenericName
);
267 prefName
.AssignLiteral("font.default.");
268 prefName
.Append(aLangGroup
);
269 prefs
->CopyUnicharPref(prefName
.get(), getter_Copies(genericName
));
272 nsCAutoString genericDotLang
;
273 genericDotLang
.Assign(NS_ConvertUTF16toUTF8(genericName
));
274 genericDotLang
.AppendLiteral(".");
275 genericDotLang
.Append(aLangGroup
);
277 prefName
.AssignLiteral("font.name.");
278 prefName
.Append(genericDotLang
);
279 rv
= prefs
->CopyUnicharPref(prefName
.get(), getter_Copies(value
));
280 if (NS_SUCCEEDED(rv
)) {
281 if (!aFonts
.IsEmpty())
282 aFonts
.AppendLiteral(", ");
283 aFonts
.Append(value
);
286 prefName
.AssignLiteral("font.name-list.");
287 prefName
.Append(genericDotLang
);
288 rv
= prefs
->CopyUnicharPref(prefName
.get(), getter_Copies(value
));
289 if (NS_SUCCEEDED(rv
)) {
290 if (!aFonts
.IsEmpty())
291 aFonts
.AppendLiteral(", ");
292 aFonts
.Append(value
);
297 gfxPlatform::GetPrefFonts(const char *aLangGroup
, nsString
& aFonts
, PRBool aAppendUnicode
)
301 AppendGenericFontFromPref(aFonts
, aLangGroup
, nsnull
);
303 AppendGenericFontFromPref(aFonts
, "x-unicode", nsnull
);
307 gfxPlatform::IsCMSEnabled()
309 static PRBool sEnabled
= -1;
310 if (sEnabled
== -1) {
312 nsCOMPtr
<nsIPrefBranch
> prefs
= do_GetService(NS_PREFSERVICE_CONTRACTID
);
316 prefs
->GetBoolPref("gfx.color_management.enabled", &enabled
);
317 if (NS_SUCCEEDED(rv
)) {
326 gfxPlatform::GetPlatformCMSOutputProfile()
332 gfxPlatform::GetCMSOutputProfile()
334 if (!gCMSOutputProfile
) {
335 /* Default lcms error action is to abort on error - change */
337 cmsErrorAction(LCMS_ERROR_SHOW
);
339 cmsErrorAction(LCMS_ERROR_IGNORE
);
342 nsCOMPtr
<nsIPrefBranch
> prefs
= do_GetService(NS_PREFSERVICE_CONTRACTID
);
344 nsXPIDLCString fname
;
346 prefs
->GetCharPref("gfx.color_management.display_profile",
347 getter_Copies(fname
));
348 if (NS_SUCCEEDED(rv
) && !fname
.IsEmpty()) {
349 gCMSOutputProfile
= cmsOpenProfileFromFile(fname
, "r");
351 if (gCMSOutputProfile
)
353 "ICM profile read from %s successfully\n",
359 if (!gCMSOutputProfile
) {
361 gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfile();
364 if (!gCMSOutputProfile
) {
365 gCMSOutputProfile
= cmsCreate_sRGBProfile();
369 return gCMSOutputProfile
;
373 gfxPlatform::GetCMSRGBTransform()
375 if (!gCMSRGBTransform
) {
376 cmsHPROFILE inProfile
, outProfile
;
377 outProfile
= GetCMSOutputProfile();
378 inProfile
= cmsCreate_sRGBProfile();
380 if (!inProfile
|| !outProfile
)
383 gCMSRGBTransform
= cmsCreateTransform(inProfile
, TYPE_RGB_8
,
384 outProfile
, TYPE_RGB_8
,
385 INTENT_PERCEPTUAL
, 0);
388 return gCMSRGBTransform
;
392 gfxPlatform::GetCMSRGBATransform()
394 if (!gCMSRGBATransform
) {
395 cmsHPROFILE inProfile
, outProfile
;
396 outProfile
= GetCMSOutputProfile();
397 inProfile
= cmsCreate_sRGBProfile();
399 if (!inProfile
|| !outProfile
)
402 gCMSRGBATransform
= cmsCreateTransform(inProfile
, TYPE_RGBA_8
,
403 outProfile
, TYPE_RGBA_8
,
404 INTENT_PERCEPTUAL
, 0);
407 return gCMSRGBATransform
;