gfx/thebes/gfxPlatformMac.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "gfxPlatformMac.h"
michael@0 7
michael@0 8 #include "gfxImageSurface.h"
michael@0 9 #include "gfxQuartzSurface.h"
michael@0 10 #include "gfxQuartzImageSurface.h"
michael@0 11 #include "mozilla/gfx/2D.h"
michael@0 12
michael@0 13 #include "gfxMacPlatformFontList.h"
michael@0 14 #include "gfxMacFont.h"
michael@0 15 #include "gfxCoreTextShaper.h"
michael@0 16 #include "gfxUserFontSet.h"
michael@0 17
michael@0 18 #include "nsTArray.h"
michael@0 19 #include "mozilla/Preferences.h"
michael@0 20 #include "qcms.h"
michael@0 21 #include "gfx2DGlue.h"
michael@0 22
michael@0 23 #include <dlfcn.h>
michael@0 24
michael@0 25 #include "nsCocoaFeatures.h"
michael@0 26
michael@0 27 using namespace mozilla;
michael@0 28 using namespace mozilla::gfx;
michael@0 29
michael@0 30 // cribbed from CTFontManager.h
michael@0 31 enum {
michael@0 32 kAutoActivationDisabled = 1
michael@0 33 };
michael@0 34 typedef uint32_t AutoActivationSetting;
michael@0 35
michael@0 36 // bug 567552 - disable auto-activation of fonts
michael@0 37
michael@0 38 static void
michael@0 39 DisableFontActivation()
michael@0 40 {
michael@0 41 // get the main bundle identifier
michael@0 42 CFBundleRef mainBundle = ::CFBundleGetMainBundle();
michael@0 43 CFStringRef mainBundleID = nullptr;
michael@0 44
michael@0 45 if (mainBundle) {
michael@0 46 mainBundleID = ::CFBundleGetIdentifier(mainBundle);
michael@0 47 }
michael@0 48
michael@0 49 // bug 969388 and bug 922590 - mainBundlID as null is sometimes problematic
michael@0 50 if (!mainBundleID) {
michael@0 51 NS_WARNING("missing bundle ID, packaging set up incorrectly");
michael@0 52 return;
michael@0 53 }
michael@0 54
michael@0 55 // if possible, fetch CTFontManagerSetAutoActivationSetting
michael@0 56 void (*CTFontManagerSetAutoActivationSettingPtr)
michael@0 57 (CFStringRef, AutoActivationSetting);
michael@0 58 CTFontManagerSetAutoActivationSettingPtr =
michael@0 59 (void (*)(CFStringRef, AutoActivationSetting))
michael@0 60 dlsym(RTLD_DEFAULT, "CTFontManagerSetAutoActivationSetting");
michael@0 61
michael@0 62 // bug 567552 - disable auto-activation of fonts
michael@0 63 if (CTFontManagerSetAutoActivationSettingPtr) {
michael@0 64 CTFontManagerSetAutoActivationSettingPtr(mainBundleID,
michael@0 65 kAutoActivationDisabled);
michael@0 66 }
michael@0 67 }
michael@0 68
michael@0 69 gfxPlatformMac::gfxPlatformMac()
michael@0 70 {
michael@0 71 DisableFontActivation();
michael@0 72 mFontAntiAliasingThreshold = ReadAntiAliasingThreshold();
michael@0 73
michael@0 74 uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) |
michael@0 75 BackendTypeBit(BackendType::SKIA) |
michael@0 76 BackendTypeBit(BackendType::COREGRAPHICS);
michael@0 77 uint32_t contentMask = BackendTypeBit(BackendType::COREGRAPHICS);
michael@0 78 InitBackendPrefs(canvasMask, BackendType::COREGRAPHICS,
michael@0 79 contentMask, BackendType::COREGRAPHICS);
michael@0 80 }
michael@0 81
michael@0 82 gfxPlatformMac::~gfxPlatformMac()
michael@0 83 {
michael@0 84 gfxCoreTextShaper::Shutdown();
michael@0 85 }
michael@0 86
michael@0 87 gfxPlatformFontList*
michael@0 88 gfxPlatformMac::CreatePlatformFontList()
michael@0 89 {
michael@0 90 gfxPlatformFontList* list = new gfxMacPlatformFontList();
michael@0 91 if (NS_SUCCEEDED(list->InitFontList())) {
michael@0 92 return list;
michael@0 93 }
michael@0 94 gfxPlatformFontList::Shutdown();
michael@0 95 return nullptr;
michael@0 96 }
michael@0 97
michael@0 98 already_AddRefed<gfxASurface>
michael@0 99 gfxPlatformMac::CreateOffscreenSurface(const IntSize& size,
michael@0 100 gfxContentType contentType)
michael@0 101 {
michael@0 102 nsRefPtr<gfxASurface> newSurface =
michael@0 103 new gfxQuartzSurface(ThebesIntSize(size),
michael@0 104 OptimalFormatForContent(contentType));
michael@0 105 return newSurface.forget();
michael@0 106 }
michael@0 107
michael@0 108 already_AddRefed<gfxASurface>
michael@0 109 gfxPlatformMac::CreateOffscreenImageSurface(const gfxIntSize& aSize,
michael@0 110 gfxContentType aContentType)
michael@0 111 {
michael@0 112 nsRefPtr<gfxASurface> surface =
michael@0 113 CreateOffscreenSurface(aSize.ToIntSize(), aContentType);
michael@0 114 #ifdef DEBUG
michael@0 115 nsRefPtr<gfxImageSurface> imageSurface = surface->GetAsImageSurface();
michael@0 116 NS_ASSERTION(imageSurface, "Surface cannot be converted to a gfxImageSurface");
michael@0 117 #endif
michael@0 118 return surface.forget();
michael@0 119 }
michael@0 120
michael@0 121
michael@0 122 already_AddRefed<gfxASurface>
michael@0 123 gfxPlatformMac::OptimizeImage(gfxImageSurface *aSurface,
michael@0 124 gfxImageFormat format)
michael@0 125 {
michael@0 126 const gfxIntSize& surfaceSize = aSurface->GetSize();
michael@0 127 nsRefPtr<gfxImageSurface> isurf = aSurface;
michael@0 128
michael@0 129 if (format != aSurface->Format()) {
michael@0 130 isurf = new gfxImageSurface (surfaceSize, format);
michael@0 131 if (!isurf->CopyFrom (aSurface)) {
michael@0 132 // don't even bother doing anything more
michael@0 133 nsRefPtr<gfxASurface> ret = aSurface;
michael@0 134 return ret.forget();
michael@0 135 }
michael@0 136 }
michael@0 137
michael@0 138 return nullptr;
michael@0 139 }
michael@0 140
michael@0 141 TemporaryRef<ScaledFont>
michael@0 142 gfxPlatformMac::GetScaledFontForFont(DrawTarget* aTarget, gfxFont *aFont)
michael@0 143 {
michael@0 144 gfxMacFont *font = static_cast<gfxMacFont*>(aFont);
michael@0 145 return font->GetScaledFont(aTarget);
michael@0 146 }
michael@0 147
michael@0 148 nsresult
michael@0 149 gfxPlatformMac::ResolveFontName(const nsAString& aFontName,
michael@0 150 FontResolverCallback aCallback,
michael@0 151 void *aClosure, bool& aAborted)
michael@0 152 {
michael@0 153 nsAutoString resolvedName;
michael@0 154 if (!gfxPlatformFontList::PlatformFontList()->
michael@0 155 ResolveFontName(aFontName, resolvedName)) {
michael@0 156 aAborted = false;
michael@0 157 return NS_OK;
michael@0 158 }
michael@0 159 aAborted = !(*aCallback)(resolvedName, aClosure);
michael@0 160 return NS_OK;
michael@0 161 }
michael@0 162
michael@0 163 nsresult
michael@0 164 gfxPlatformMac::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
michael@0 165 {
michael@0 166 gfxPlatformFontList::PlatformFontList()->GetStandardFamilyName(aFontName, aFamilyName);
michael@0 167 return NS_OK;
michael@0 168 }
michael@0 169
michael@0 170 gfxFontGroup *
michael@0 171 gfxPlatformMac::CreateFontGroup(const nsAString &aFamilies,
michael@0 172 const gfxFontStyle *aStyle,
michael@0 173 gfxUserFontSet *aUserFontSet)
michael@0 174 {
michael@0 175 return new gfxFontGroup(aFamilies, aStyle, aUserFontSet);
michael@0 176 }
michael@0 177
michael@0 178 // these will move to gfxPlatform once all platforms support the fontlist
michael@0 179 gfxFontEntry*
michael@0 180 gfxPlatformMac::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
michael@0 181 const nsAString& aFontName)
michael@0 182 {
michael@0 183 return gfxPlatformFontList::PlatformFontList()->LookupLocalFont(aProxyEntry,
michael@0 184 aFontName);
michael@0 185 }
michael@0 186
michael@0 187 gfxFontEntry*
michael@0 188 gfxPlatformMac::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
michael@0 189 const uint8_t *aFontData, uint32_t aLength)
michael@0 190 {
michael@0 191 // Ownership of aFontData is received here, and passed on to
michael@0 192 // gfxPlatformFontList::MakePlatformFont(), which must ensure the data
michael@0 193 // is released with NS_Free when no longer needed
michael@0 194 return gfxPlatformFontList::PlatformFontList()->MakePlatformFont(aProxyEntry,
michael@0 195 aFontData,
michael@0 196 aLength);
michael@0 197 }
michael@0 198
michael@0 199 bool
michael@0 200 gfxPlatformMac::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
michael@0 201 {
michael@0 202 // check for strange format flags
michael@0 203 NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED),
michael@0 204 "strange font format hint set");
michael@0 205
michael@0 206 // accept supported formats
michael@0 207 if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_WOFF |
michael@0 208 gfxUserFontSet::FLAG_FORMAT_OPENTYPE |
michael@0 209 gfxUserFontSet::FLAG_FORMAT_TRUETYPE |
michael@0 210 gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT)) {
michael@0 211 return true;
michael@0 212 }
michael@0 213
michael@0 214 // reject all other formats, known and unknown
michael@0 215 if (aFormatFlags != 0) {
michael@0 216 return false;
michael@0 217 }
michael@0 218
michael@0 219 // no format hint set, need to look at data
michael@0 220 return true;
michael@0 221 }
michael@0 222
michael@0 223 // these will also move to gfxPlatform once all platforms support the fontlist
michael@0 224 nsresult
michael@0 225 gfxPlatformMac::GetFontList(nsIAtom *aLangGroup,
michael@0 226 const nsACString& aGenericFamily,
michael@0 227 nsTArray<nsString>& aListOfFonts)
michael@0 228 {
michael@0 229 gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup, aGenericFamily, aListOfFonts);
michael@0 230 return NS_OK;
michael@0 231 }
michael@0 232
michael@0 233 nsresult
michael@0 234 gfxPlatformMac::UpdateFontList()
michael@0 235 {
michael@0 236 gfxPlatformFontList::PlatformFontList()->UpdateFontList();
michael@0 237 return NS_OK;
michael@0 238 }
michael@0 239
michael@0 240 static const char kFontArialUnicodeMS[] = "Arial Unicode MS";
michael@0 241 static const char kFontAppleBraille[] = "Apple Braille";
michael@0 242 static const char kFontAppleColorEmoji[] = "Apple Color Emoji";
michael@0 243 static const char kFontAppleSymbols[] = "Apple Symbols";
michael@0 244 static const char kFontDevanagariSangamMN[] = "Devanagari Sangam MN";
michael@0 245 static const char kFontEuphemiaUCAS[] = "Euphemia UCAS";
michael@0 246 static const char kFontGeneva[] = "Geneva";
michael@0 247 static const char kFontGeezaPro[] = "Geeza Pro";
michael@0 248 static const char kFontGujaratiSangamMN[] = "Gujarati Sangam MN";
michael@0 249 static const char kFontGurmukhiMN[] = "Gurmukhi MN";
michael@0 250 static const char kFontHiraginoKakuGothic[] = "Hiragino Kaku Gothic ProN";
michael@0 251 static const char kFontHiraginoSansGB[] = "Hiragino Sans GB";
michael@0 252 static const char kFontKefa[] = "Kefa";
michael@0 253 static const char kFontKhmerMN[] = "Khmer MN";
michael@0 254 static const char kFontLaoMN[] = "Lao MN";
michael@0 255 static const char kFontLucidaGrande[] = "Lucida Grande";
michael@0 256 static const char kFontMenlo[] = "Menlo";
michael@0 257 static const char kFontMicrosoftTaiLe[] = "Microsoft Tai Le";
michael@0 258 static const char kFontMingLiUExtB[] = "MingLiU-ExtB";
michael@0 259 static const char kFontMyanmarMN[] = "Myanmar MN";
michael@0 260 static const char kFontPlantagenetCherokee[] = "Plantagenet Cherokee";
michael@0 261 static const char kFontSimSunExtB[] = "SimSun-ExtB";
michael@0 262 static const char kFontSongtiSC[] = "Songti SC";
michael@0 263 static const char kFontSTHeiti[] = "STHeiti";
michael@0 264 static const char kFontSTIXGeneral[] = "STIXGeneral";
michael@0 265 static const char kFontTamilMN[] = "Tamil MN";
michael@0 266
michael@0 267 void
michael@0 268 gfxPlatformMac::GetCommonFallbackFonts(const uint32_t aCh,
michael@0 269 int32_t aRunScript,
michael@0 270 nsTArray<const char*>& aFontList)
michael@0 271 {
michael@0 272 aFontList.AppendElement(kFontLucidaGrande);
michael@0 273
michael@0 274 if (!IS_IN_BMP(aCh)) {
michael@0 275 uint32_t p = aCh >> 16;
michael@0 276 uint32_t b = aCh >> 8;
michael@0 277 if (p == 1) {
michael@0 278 if (b >= 0x1f0 && b < 0x1f7) {
michael@0 279 aFontList.AppendElement(kFontAppleColorEmoji);
michael@0 280 } else {
michael@0 281 aFontList.AppendElement(kFontAppleSymbols);
michael@0 282 aFontList.AppendElement(kFontSTIXGeneral);
michael@0 283 aFontList.AppendElement(kFontGeneva);
michael@0 284 }
michael@0 285 } else if (p == 2) {
michael@0 286 // OSX installations with MS Office may have these fonts
michael@0 287 aFontList.AppendElement(kFontMingLiUExtB);
michael@0 288 aFontList.AppendElement(kFontSimSunExtB);
michael@0 289 }
michael@0 290 } else {
michael@0 291 uint32_t b = (aCh >> 8) & 0xff;
michael@0 292
michael@0 293 switch (b) {
michael@0 294 case 0x03:
michael@0 295 case 0x05:
michael@0 296 aFontList.AppendElement(kFontGeneva);
michael@0 297 break;
michael@0 298 case 0x07:
michael@0 299 aFontList.AppendElement(kFontGeezaPro);
michael@0 300 break;
michael@0 301 case 0x09:
michael@0 302 aFontList.AppendElement(kFontDevanagariSangamMN);
michael@0 303 break;
michael@0 304 case 0x0a:
michael@0 305 aFontList.AppendElement(kFontGurmukhiMN);
michael@0 306 aFontList.AppendElement(kFontGujaratiSangamMN);
michael@0 307 break;
michael@0 308 case 0x0b:
michael@0 309 aFontList.AppendElement(kFontTamilMN);
michael@0 310 break;
michael@0 311 case 0x0e:
michael@0 312 aFontList.AppendElement(kFontLaoMN);
michael@0 313 break;
michael@0 314 case 0x0f:
michael@0 315 aFontList.AppendElement(kFontSongtiSC);
michael@0 316 break;
michael@0 317 case 0x10:
michael@0 318 aFontList.AppendElement(kFontMenlo);
michael@0 319 aFontList.AppendElement(kFontMyanmarMN);
michael@0 320 break;
michael@0 321 case 0x13: // Cherokee
michael@0 322 aFontList.AppendElement(kFontPlantagenetCherokee);
michael@0 323 aFontList.AppendElement(kFontKefa);
michael@0 324 break;
michael@0 325 case 0x14: // Unified Canadian Aboriginal Syllabics
michael@0 326 case 0x15:
michael@0 327 case 0x16:
michael@0 328 aFontList.AppendElement(kFontEuphemiaUCAS);
michael@0 329 aFontList.AppendElement(kFontGeneva);
michael@0 330 break;
michael@0 331 case 0x18: // Mongolian, UCAS
michael@0 332 aFontList.AppendElement(kFontSTHeiti);
michael@0 333 aFontList.AppendElement(kFontEuphemiaUCAS);
michael@0 334 break;
michael@0 335 case 0x19: // Khmer
michael@0 336 aFontList.AppendElement(kFontKhmerMN);
michael@0 337 aFontList.AppendElement(kFontMicrosoftTaiLe);
michael@0 338 break;
michael@0 339 case 0x1d:
michael@0 340 case 0x1e:
michael@0 341 aFontList.AppendElement(kFontGeneva);
michael@0 342 break;
michael@0 343 case 0x20: // Symbol ranges
michael@0 344 case 0x21:
michael@0 345 case 0x22:
michael@0 346 case 0x23:
michael@0 347 case 0x24:
michael@0 348 case 0x25:
michael@0 349 case 0x26:
michael@0 350 case 0x27:
michael@0 351 case 0x29:
michael@0 352 case 0x2a:
michael@0 353 case 0x2b:
michael@0 354 case 0x2e:
michael@0 355 aFontList.AppendElement(kFontAppleSymbols);
michael@0 356 aFontList.AppendElement(kFontMenlo);
michael@0 357 aFontList.AppendElement(kFontSTIXGeneral);
michael@0 358 aFontList.AppendElement(kFontGeneva);
michael@0 359 aFontList.AppendElement(kFontHiraginoKakuGothic);
michael@0 360 aFontList.AppendElement(kFontAppleColorEmoji);
michael@0 361 break;
michael@0 362 case 0x2c:
michael@0 363 aFontList.AppendElement(kFontGeneva);
michael@0 364 break;
michael@0 365 case 0x2d:
michael@0 366 aFontList.AppendElement(kFontKefa);
michael@0 367 aFontList.AppendElement(kFontGeneva);
michael@0 368 break;
michael@0 369 case 0x28: // Braille
michael@0 370 aFontList.AppendElement(kFontAppleBraille);
michael@0 371 break;
michael@0 372 case 0x31:
michael@0 373 aFontList.AppendElement(kFontHiraginoSansGB);
michael@0 374 break;
michael@0 375 case 0x4d:
michael@0 376 aFontList.AppendElement(kFontAppleSymbols);
michael@0 377 break;
michael@0 378 case 0xa0: // Yi
michael@0 379 case 0xa1:
michael@0 380 case 0xa2:
michael@0 381 case 0xa3:
michael@0 382 case 0xa4:
michael@0 383 aFontList.AppendElement(kFontSTHeiti);
michael@0 384 break;
michael@0 385 case 0xa6:
michael@0 386 case 0xa7:
michael@0 387 aFontList.AppendElement(kFontGeneva);
michael@0 388 aFontList.AppendElement(kFontAppleSymbols);
michael@0 389 break;
michael@0 390 case 0xab:
michael@0 391 aFontList.AppendElement(kFontKefa);
michael@0 392 break;
michael@0 393 case 0xfc:
michael@0 394 case 0xff:
michael@0 395 aFontList.AppendElement(kFontAppleSymbols);
michael@0 396 break;
michael@0 397 default:
michael@0 398 break;
michael@0 399 }
michael@0 400 }
michael@0 401
michael@0 402 // Arial Unicode MS has lots of glyphs for obscure, use it as a last resort
michael@0 403 aFontList.AppendElement(kFontArialUnicodeMS);
michael@0 404 }
michael@0 405
michael@0 406 uint32_t
michael@0 407 gfxPlatformMac::ReadAntiAliasingThreshold()
michael@0 408 {
michael@0 409 uint32_t threshold = 0; // default == no threshold
michael@0 410
michael@0 411 // first read prefs flag to determine whether to use the setting or not
michael@0 412 bool useAntiAliasingThreshold = Preferences::GetBool("gfx.use_text_smoothing_setting", false);
michael@0 413
michael@0 414 // if the pref setting is disabled, return 0 which effectively disables this feature
michael@0 415 if (!useAntiAliasingThreshold)
michael@0 416 return threshold;
michael@0 417
michael@0 418 // value set via Appearance pref panel, "Turn off text smoothing for font sizes xxx and smaller"
michael@0 419 CFNumberRef prefValue = (CFNumberRef)CFPreferencesCopyAppValue(CFSTR("AppleAntiAliasingThreshold"), kCFPreferencesCurrentApplication);
michael@0 420
michael@0 421 if (prefValue) {
michael@0 422 if (!CFNumberGetValue(prefValue, kCFNumberIntType, &threshold)) {
michael@0 423 threshold = 0;
michael@0 424 }
michael@0 425 CFRelease(prefValue);
michael@0 426 }
michael@0 427
michael@0 428 return threshold;
michael@0 429 }
michael@0 430
michael@0 431 already_AddRefed<gfxASurface>
michael@0 432 gfxPlatformMac::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
michael@0 433 {
michael@0 434 if (aTarget->GetType() == BackendType::COREGRAPHICS_ACCELERATED) {
michael@0 435 RefPtr<SourceSurface> source = aTarget->Snapshot();
michael@0 436 RefPtr<DataSourceSurface> sourceData = source->GetDataSurface();
michael@0 437 unsigned char* data = sourceData->GetData();
michael@0 438 nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(data, ThebesIntSize(sourceData->GetSize()), sourceData->Stride(),
michael@0 439 gfxImageFormat::ARGB32);
michael@0 440 // We could fix this by telling gfxImageSurface it owns data.
michael@0 441 nsRefPtr<gfxImageSurface> cpy = new gfxImageSurface(ThebesIntSize(sourceData->GetSize()), gfxImageFormat::ARGB32);
michael@0 442 cpy->CopyFrom(surf);
michael@0 443 return cpy.forget();
michael@0 444 } else if (aTarget->GetType() == BackendType::COREGRAPHICS) {
michael@0 445 CGContextRef cg = static_cast<CGContextRef>(aTarget->GetNativeSurface(NativeSurfaceType::CGCONTEXT));
michael@0 446
michael@0 447 //XXX: it would be nice to have an implicit conversion from IntSize to gfxIntSize
michael@0 448 IntSize intSize = aTarget->GetSize();
michael@0 449 gfxIntSize size(intSize.width, intSize.height);
michael@0 450
michael@0 451 nsRefPtr<gfxASurface> surf =
michael@0 452 new gfxQuartzSurface(cg, size);
michael@0 453
michael@0 454 return surf.forget();
michael@0 455 }
michael@0 456
michael@0 457 return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
michael@0 458 }
michael@0 459
michael@0 460 bool
michael@0 461 gfxPlatformMac::UseAcceleratedCanvas()
michael@0 462 {
michael@0 463 // Lion or later is required
michael@0 464 return nsCocoaFeatures::OnLionOrLater() && Preferences::GetBool("gfx.canvas.azure.accelerated", false);
michael@0 465 }
michael@0 466
michael@0 467 bool
michael@0 468 gfxPlatformMac::SupportsOffMainThreadCompositing()
michael@0 469 {
michael@0 470 return true;
michael@0 471 }
michael@0 472
michael@0 473 void
michael@0 474 gfxPlatformMac::GetPlatformCMSOutputProfile(void* &mem, size_t &size)
michael@0 475 {
michael@0 476 mem = nullptr;
michael@0 477 size = 0;
michael@0 478
michael@0 479 CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
michael@0 480 if (!cspace) {
michael@0 481 cspace = ::CGColorSpaceCreateDeviceRGB();
michael@0 482 }
michael@0 483 if (!cspace) {
michael@0 484 return;
michael@0 485 }
michael@0 486
michael@0 487 CFDataRef iccp = ::CGColorSpaceCopyICCProfile(cspace);
michael@0 488
michael@0 489 ::CFRelease(cspace);
michael@0 490
michael@0 491 if (!iccp) {
michael@0 492 return;
michael@0 493 }
michael@0 494
michael@0 495 // copy to external buffer
michael@0 496 size = static_cast<size_t>(::CFDataGetLength(iccp));
michael@0 497 if (size > 0) {
michael@0 498 void *data = malloc(size);
michael@0 499 if (data) {
michael@0 500 memcpy(data, ::CFDataGetBytePtr(iccp), size);
michael@0 501 mem = data;
michael@0 502 } else {
michael@0 503 size = 0;
michael@0 504 }
michael@0 505 }
michael@0 506
michael@0 507 ::CFRelease(iccp);
michael@0 508 }

mercurial