mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Merge inbound to mozilla-central. a=merge on a CLOSED TREE
This commit is contained in:
commit
47cb352984
@ -1,4 +1,6 @@
|
||||
[DEFAULT]
|
||||
prefs =
|
||||
dom.animations-api.core.enabled=true
|
||||
support-files =
|
||||
head.js
|
||||
head_pageAction.js
|
||||
@ -210,3 +212,4 @@ tags = fullscreen
|
||||
skip-if = os == 'mac' # Fails when windows are randomly opened in fullscreen mode
|
||||
[browser_ext_windows_update.js]
|
||||
tags = fullscreen
|
||||
[browser_ext_contentscript_animate.js]
|
||||
|
@ -0,0 +1,95 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_animate() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["http://mochi.test/*"],
|
||||
"js": ["content-script.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
files: {
|
||||
"content-script.js": function() {
|
||||
let elem = document.getElementsByTagName("body")[0];
|
||||
elem.style.border = "2px solid red";
|
||||
|
||||
let anim = elem.animate({opacity: [1, 0]}, 2000);
|
||||
let frames = anim.effect.getKeyframes();
|
||||
browser.test.assertEq(frames.length, 2,
|
||||
"frames for Element.animate should be non-zero");
|
||||
browser.test.assertEq(frames[0].opacity, "1",
|
||||
"first frame opacity for Element.animate should be specified value");
|
||||
browser.test.assertEq(frames[0].computedOffset, 0,
|
||||
"first frame offset for Element.animate should be 0");
|
||||
browser.test.assertEq(frames[1].opacity, "0",
|
||||
"last frame opacity for Element.animate should be specified value");
|
||||
browser.test.assertEq(frames[1].computedOffset, 1,
|
||||
"last frame offset for Element.animate should be 1");
|
||||
|
||||
browser.test.notifyPass("contentScriptAnimate");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitFinish("contentScriptAnimate");
|
||||
await extension.unload();
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function test_KeyframeEffect() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["http://mochi.test/*"],
|
||||
"js": ["content-script.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
files: {
|
||||
"content-script.js": function() {
|
||||
let elem = document.getElementsByTagName("body")[0];
|
||||
elem.style.border = "2px solid red";
|
||||
|
||||
let effect = new KeyframeEffect(elem, [
|
||||
{opacity: 1, offset: 0},
|
||||
{opacity: 0, offset: 1},
|
||||
], {duration: 1000, fill: "forwards"});
|
||||
let frames = effect.getKeyframes();
|
||||
browser.test.assertEq(frames.length, 2,
|
||||
"frames for KeyframeEffect ctor should be non-zero");
|
||||
browser.test.assertEq(frames[0].opacity, "1",
|
||||
"first frame opacity for KeyframeEffect ctor should be specified value");
|
||||
browser.test.assertEq(frames[0].computedOffset, 0,
|
||||
"first frame offset for KeyframeEffect ctor should be 0");
|
||||
browser.test.assertEq(frames[1].opacity, "0",
|
||||
"last frame opacity for KeyframeEffect ctor should be specified value");
|
||||
browser.test.assertEq(frames[1].computedOffset, 1,
|
||||
"last frame offset for KeyframeEffect ctor should be 1");
|
||||
|
||||
let animation = new Animation(effect, document.timeline);
|
||||
animation.play();
|
||||
|
||||
browser.test.notifyPass("contentScriptKeyframeEffect");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitFinish("contentScriptKeyframeEffect");
|
||||
await extension.unload();
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
@ -49,6 +49,16 @@ AnimationUtils::GetCurrentRealmDocument(JSContext* aCx)
|
||||
return win->GetDoc();
|
||||
}
|
||||
|
||||
/* static */ nsIDocument*
|
||||
AnimationUtils::GetDocumentFromGlobal(JSObject* aGlobalObject)
|
||||
{
|
||||
nsGlobalWindowInner* win = xpc::WindowOrNull(aGlobalObject);
|
||||
if (!win) {
|
||||
return nullptr;
|
||||
}
|
||||
return win->GetDoc();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
AnimationUtils::IsOffscreenThrottlingEnabled()
|
||||
{
|
||||
|
@ -61,6 +61,14 @@ public:
|
||||
static nsIDocument*
|
||||
GetCurrentRealmDocument(JSContext* aCx);
|
||||
|
||||
/**
|
||||
* Get the document from the global object, or nullptr if the document has
|
||||
* no window, to use when constructing DOM object without entering the
|
||||
* target window's compartment (see KeyframeEffect constructor).
|
||||
*/
|
||||
static nsIDocument*
|
||||
GetDocumentFromGlobal(JSObject* aGlobalObject);
|
||||
|
||||
/**
|
||||
* Checks if offscreen animation throttling is enabled.
|
||||
*/
|
||||
|
@ -903,7 +903,17 @@ KeyframeEffectReadOnly::ConstructKeyframeEffect(
|
||||
const OptionsType& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsIDocument* doc = AnimationUtils::GetCurrentRealmDocument(aGlobal.Context());
|
||||
// We should get the document from `aGlobal` instead of the current Realm
|
||||
// to make this works in Xray case.
|
||||
//
|
||||
// In all non-Xray cases, `aGlobal` matches the current Realm, so this
|
||||
// matches the spec behavior.
|
||||
//
|
||||
// In Xray case, the new objects should be created using the document of
|
||||
// the target global, but KeyframeEffect and KeyframeEffectReadOnly
|
||||
// constructors are called in the caller's compartment to access
|
||||
// `aKeyframes` object.
|
||||
nsIDocument* doc = AnimationUtils::GetDocumentFromGlobal(aGlobal.Get());
|
||||
if (!doc) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
|
@ -8,6 +8,7 @@ support-files =
|
||||
[chrome/test_animate_xrays.html]
|
||||
# file_animate_xrays.html needs to go in mochitest.ini since it is served
|
||||
# over HTTP
|
||||
[chrome/test_keyframe_effect_xrays.html]
|
||||
[chrome/test_animation_observers_async.html]
|
||||
[chrome/test_animation_observers_sync.html]
|
||||
[chrome/test_animation_performance_warning.html]
|
||||
|
@ -6,10 +6,9 @@
|
||||
Element.prototype.animate = function() {
|
||||
throw 'Called animate() as defined in content document';
|
||||
}
|
||||
// Bug 1211783: Use KeyframeEffect (not KeyframeEffectReadOnly) here
|
||||
for (var obj of [KeyframeEffectReadOnly, Animation]) {
|
||||
obj = function() {
|
||||
throw 'Called overridden ' + String(obj) + ' constructor';
|
||||
for (let name of ["KeyframeEffect", "KeyframeEffectReadOnly", "Animation"]) {
|
||||
this[name] = function() {
|
||||
throw `Called overridden ${name} constructor`;
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
@ -6,8 +6,8 @@
|
||||
<script type="application/javascript" src="../testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1045994"
|
||||
target="_blank">Mozilla Bug 1045994</a>
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414674"
|
||||
target="_blank">Mozilla Bug 1414674</a>
|
||||
<div id="log"></div>
|
||||
<iframe id="iframe"
|
||||
src="http://example.org/tests/dom/animation/test/chrome/file_animate_xrays.html"></iframe>
|
||||
@ -19,10 +19,19 @@ var win = document.getElementById('iframe').contentWindow;
|
||||
async_test(function(t) {
|
||||
window.addEventListener('load', t.step_func(function() {
|
||||
var target = win.document.getElementById('target');
|
||||
var anim = target.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
|
||||
// In the x-ray case, the frames object will be given an opaque wrapper
|
||||
// so it won't be possible to fetch any frames from it.
|
||||
assert_equals(anim.effect.getKeyframes().length, 0);
|
||||
var anim = target.animate({opacity: [ 1, 0 ]}, 100 * MS_PER_SEC);
|
||||
// The frames object should be accessible via x-ray.
|
||||
var frames = anim.effect.getKeyframes();
|
||||
assert_equals(frames.length, 2,
|
||||
"frames for Element.animate should be non-zero");
|
||||
assert_equals(frames[0].opacity, "1",
|
||||
"first frame opacity for Element.animate should be specified value");
|
||||
assert_equals(frames[0].computedOffset, 0,
|
||||
"first frame offset for Element.animate should be 0");
|
||||
assert_equals(frames[1].opacity, "0",
|
||||
"last frame opacity for Element.animate should be specified value");
|
||||
assert_equals(frames[1].computedOffset, 1,
|
||||
"last frame offset for Element.animate should be 1");
|
||||
t.done();
|
||||
}));
|
||||
}, 'Calling animate() across x-rays');
|
||||
|
45
dom/animation/test/chrome/test_keyframe_effect_xrays.html
Normal file
45
dom/animation/test/chrome/test_keyframe_effect_xrays.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<script type="application/javascript" src="../testharness.js"></script>
|
||||
<script type="application/javascript" src="../testharnessreport.js"></script>
|
||||
<script type="application/javascript" src="../testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414674"
|
||||
target="_blank">Mozilla Bug 1414674</a>
|
||||
<div id="log"></div>
|
||||
<iframe id="iframe"
|
||||
src="http://example.org/tests/dom/animation/test/chrome/file_animate_xrays.html"></iframe>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
var win = document.getElementById('iframe').contentWindow;
|
||||
|
||||
async_test(function(t) {
|
||||
window.addEventListener('load', t.step_func(function() {
|
||||
var target = win.document.getElementById('target');
|
||||
var effect = new win.KeyframeEffect(target, [
|
||||
{opacity: 1, offset: 0},
|
||||
{opacity: 0, offset: 1},
|
||||
], {duration: 100 * MS_PER_SEC, fill: "forwards"});
|
||||
// The frames object should be accessible via x-ray.
|
||||
var frames = effect.getKeyframes();
|
||||
assert_equals(frames.length, 2,
|
||||
"frames for KeyframeEffect ctor should be non-zero");
|
||||
assert_equals(frames[0].opacity, "1",
|
||||
"first frame opacity for KeyframeEffect ctor should be specified value");
|
||||
assert_equals(frames[0].computedOffset, 0,
|
||||
"first frame offset for KeyframeEffect ctor should be 0");
|
||||
assert_equals(frames[1].opacity, "0",
|
||||
"last frame opacity for KeyframeEffect ctor should be specified value");
|
||||
assert_equals(frames[1].computedOffset, 1,
|
||||
"last frame offset for KeyframeEffect ctor should be 1");
|
||||
var animation = new win.Animation(effect, document.timeline);
|
||||
animation.play();
|
||||
t.done();
|
||||
}));
|
||||
}, 'Calling KeyframeEffect() ctor across x-rays');
|
||||
|
||||
</script>
|
||||
</body>
|
@ -3804,22 +3804,23 @@ Element::Animate(const Nullable<ElementOrCSSPseudoElement>& aTarget,
|
||||
GlobalObject global(aContext, ownerGlobal->GetGlobalJSObject());
|
||||
MOZ_ASSERT(!global.Failed());
|
||||
|
||||
// Wrap the aKeyframes object for the cross-compartment case.
|
||||
JS::Rooted<JSObject*> keyframes(aContext);
|
||||
keyframes = aKeyframes;
|
||||
// KeyframeEffect constructor doesn't follow the standard Xray calling
|
||||
// convention and needs to be called in caller's compartment.
|
||||
// This should match to RunConstructorInCallerCompartment attribute in
|
||||
// KeyframeEffect.webidl.
|
||||
RefPtr<KeyframeEffect> effect =
|
||||
KeyframeEffect::Constructor(global, aTarget, aKeyframes, aOptions,
|
||||
aError);
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Animation constructor follows the standard Xray calling convention and
|
||||
// needs to be called in the target element's compartment.
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
if (js::GetContextCompartment(aContext) !=
|
||||
js::GetObjectCompartment(ownerGlobal->GetGlobalJSObject())) {
|
||||
ac.emplace(aContext, ownerGlobal->GetGlobalJSObject());
|
||||
if (!JS_WrapObject(aContext, &keyframes)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<KeyframeEffect> effect =
|
||||
KeyframeEffect::Constructor(global, aTarget, keyframes, aOptions, aError);
|
||||
if (aError.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AnimationTimeline* timeline = referenceElement->OwnerDoc()->Timeline();
|
||||
|
@ -6394,7 +6394,7 @@ nsGlobalWindowInner::GetOrCreateServiceWorker(const ServiceWorkerDescriptor& aDe
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<ServiceWorker> ref;
|
||||
for (auto sw : mServiceWorkerList) {
|
||||
if (sw->MatchesDescriptor(aDescriptor)) {
|
||||
if (sw->Descriptor().Matches(aDescriptor)) {
|
||||
ref = sw;
|
||||
return ref.forget();
|
||||
}
|
||||
|
@ -7806,7 +7806,10 @@ class CGPerSignatureCall(CGThing):
|
||||
|
||||
needsUnwrap = False
|
||||
argsPost = []
|
||||
if isConstructor:
|
||||
runConstructorInCallerCompartment = \
|
||||
descriptor.interface.getExtendedAttribute(
|
||||
'RunConstructorInCallerCompartment')
|
||||
if isConstructor and not runConstructorInCallerCompartment:
|
||||
needsUnwrap = True
|
||||
needsUnwrappedVar = False
|
||||
unwrappedVar = "obj"
|
||||
|
@ -1743,6 +1743,7 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
||||
identifier == "LegacyEventInit" or
|
||||
identifier == "ProbablyShortLivingWrapper" or
|
||||
identifier == "LegacyUnenumerableNamedProperties" or
|
||||
identifier == "RunConstructorInCallerCompartment" or
|
||||
identifier == "NonOrdinaryGetPrototypeOf"):
|
||||
# Known extended attributes that do not take values
|
||||
if not attr.noArguments():
|
||||
|
@ -569,10 +569,9 @@ ClientSource::PostMessage(const ClientPostMessageArgs& aArgs)
|
||||
RefPtr<ServiceWorkerRegistrationInfo> reg =
|
||||
swm->GetRegistration(principal, source.Scope());
|
||||
if (reg) {
|
||||
RefPtr<ServiceWorkerInfo> serviceWorker = reg->GetByID(source.Id());
|
||||
if (serviceWorker) {
|
||||
RefPtr<ServiceWorker> instance =
|
||||
globalObject->GetOrCreateServiceWorker(source);
|
||||
RefPtr<ServiceWorker> instance =
|
||||
globalObject->GetOrCreateServiceWorker(source);
|
||||
if (instance) {
|
||||
init.mSource.SetValue().SetAsServiceWorker() = instance;
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ ServiceWorker::Create(nsIGlobalObject* aOwner,
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerInfo> info = reg->GetByID(aDescriptor.Id());
|
||||
RefPtr<ServiceWorkerInfo> info = reg->GetByDescriptor(aDescriptor);
|
||||
if (!info) {
|
||||
return ref.forget();
|
||||
}
|
||||
@ -141,15 +141,11 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
mInner->PostMessage(GetParentObject(), aCx, aMessage, aTransferable, aRv);
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorker::MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const
|
||||
|
||||
const ServiceWorkerDescriptor&
|
||||
ServiceWorker::Descriptor() const
|
||||
{
|
||||
// Compare everything in the descriptor except the state. That is mutable
|
||||
// and may not exactly match.
|
||||
return mDescriptor.PrincipalInfo() == aDescriptor.PrincipalInfo() &&
|
||||
mDescriptor.Scope() == aDescriptor.Scope() &&
|
||||
mDescriptor.ScriptURL() == aDescriptor.ScriptURL() &&
|
||||
mDescriptor.Id() == aDescriptor.Id();
|
||||
return mDescriptor;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -83,8 +83,8 @@ public:
|
||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
|
||||
|
||||
bool
|
||||
MatchesDescriptor(const ServiceWorkerDescriptor& aDescriptor) const;
|
||||
const ServiceWorkerDescriptor&
|
||||
Descriptor() const;
|
||||
|
||||
void
|
||||
DisconnectFromOwner() override;
|
||||
|
@ -119,6 +119,15 @@ ServiceWorkerDescriptor::SetState(ServiceWorkerState aState)
|
||||
mData->state() = aState;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerDescriptor::Matches(const ServiceWorkerDescriptor& aDescriptor) const
|
||||
{
|
||||
return Id() == aDescriptor.Id() &&
|
||||
Scope() == aDescriptor.Scope() &&
|
||||
ScriptURL() == aDescriptor.ScriptURL() &&
|
||||
PrincipalInfo() == aDescriptor.PrincipalInfo();
|
||||
}
|
||||
|
||||
const IPCServiceWorkerDescriptor&
|
||||
ServiceWorkerDescriptor::ToIPC() const
|
||||
{
|
||||
|
@ -81,6 +81,11 @@ public:
|
||||
void
|
||||
SetState(ServiceWorkerState aState);
|
||||
|
||||
// Try to determine if two workers match each other. This is less strict
|
||||
// than an operator==() call since it ignores mutable values like State().
|
||||
bool
|
||||
Matches(const ServiceWorkerDescriptor& aDescriptor) const;
|
||||
|
||||
// Expose the underlying IPC type so that it can be passed via IPC.
|
||||
const IPCServiceWorkerDescriptor&
|
||||
ToIPC() const;
|
||||
|
@ -990,6 +990,10 @@ ServiceWorkerRegistrationWorkerThread::ShowNotification(JSContext* aCx,
|
||||
const NotificationOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mWorkerPrivate) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Until Bug 1131324 exposes ServiceWorkerContainer on workers,
|
||||
// ShowPersistentNotification() checks for valid active worker while it is
|
||||
|
@ -492,18 +492,18 @@ ServiceWorkerRegistrationInfo::GetActive() const
|
||||
}
|
||||
|
||||
ServiceWorkerInfo*
|
||||
ServiceWorkerRegistrationInfo::GetByID(uint64_t aID) const
|
||||
ServiceWorkerRegistrationInfo::GetByDescriptor(const ServiceWorkerDescriptor& aDescriptor) const
|
||||
{
|
||||
if (mActiveWorker && mActiveWorker->ID() == aID) {
|
||||
if (mActiveWorker && mActiveWorker->Descriptor().Matches(aDescriptor)) {
|
||||
return mActiveWorker;
|
||||
}
|
||||
if (mWaitingWorker && mWaitingWorker->ID() == aID) {
|
||||
if (mWaitingWorker && mWaitingWorker->Descriptor().Matches(aDescriptor)) {
|
||||
return mWaitingWorker;
|
||||
}
|
||||
if (mInstallingWorker && mInstallingWorker->ID() == aID) {
|
||||
if (mInstallingWorker && mInstallingWorker->Descriptor().Matches(aDescriptor)) {
|
||||
return mInstallingWorker;
|
||||
}
|
||||
if (mEvaluatingWorker && mEvaluatingWorker->ID() == aID) {
|
||||
if (mEvaluatingWorker && mEvaluatingWorker->Descriptor().Matches(aDescriptor)) {
|
||||
return mEvaluatingWorker;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
GetActive() const;
|
||||
|
||||
ServiceWorkerInfo*
|
||||
GetByID(uint64_t aID) const;
|
||||
GetByDescriptor(const ServiceWorkerDescriptor& aDescriptor) const;
|
||||
|
||||
// Set the given worker as the evaluating service worker. The worker
|
||||
// state is not changed.
|
||||
|
@ -20,7 +20,10 @@ dictionary KeyframeEffectOptions : AnimationEffectTimingProperties {
|
||||
CompositeOperation composite = "replace";
|
||||
};
|
||||
|
||||
// KeyframeEffectReadOnly should run in the caller's compartment to do custom
|
||||
// processing on the `keyframes` object.
|
||||
[Func="nsDocument::IsWebAnimationsEnabled",
|
||||
RunConstructorInCallerCompartment,
|
||||
Constructor ((Element or CSSPseudoElement)? target,
|
||||
object? keyframes,
|
||||
optional (unrestricted double or KeyframeEffectOptions) options),
|
||||
@ -54,7 +57,10 @@ partial interface KeyframeEffectReadOnly {
|
||||
[ChromeOnly, Throws] sequence<AnimationPropertyDetails> getProperties();
|
||||
};
|
||||
|
||||
// KeyframeEffect should run in the caller's compartment to do custom
|
||||
// processing on the `keyframes` object.
|
||||
[Func="nsDocument::IsWebAnimationsEnabled",
|
||||
RunConstructorInCallerCompartment,
|
||||
Constructor ((Element or CSSPseudoElement)? target,
|
||||
object? keyframes,
|
||||
optional (unrestricted double or KeyframeEffectOptions) options),
|
||||
|
@ -981,7 +981,7 @@ public:
|
||||
, mType(aUnscaledFont->GetType())
|
||||
, mData(nullptr)
|
||||
{
|
||||
mGetFontFileDataSucceeded = aUnscaledFont->GetFontFileData(&FontDataProc, this);
|
||||
mGetFontFileDataSucceeded = aUnscaledFont->GetFontFileData(&FontDataProc, this) && mData;
|
||||
}
|
||||
|
||||
~RecordedFontData();
|
||||
@ -2685,11 +2685,12 @@ RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(S &aStream)
|
||||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mSize);
|
||||
ReadElement(aStream, mFormat);
|
||||
mData = (uint8_t*)new (fallible) char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
|
||||
size_t size = mSize.width * mSize.height * BytesPerPixel(mFormat);
|
||||
mData = new (fallible) uint8_t[size];
|
||||
if (!mData) {
|
||||
gfxWarning() << "RecordedSourceSurfaceCreation failed to allocate data";
|
||||
gfxCriticalNote << "RecordedSourceSurfaceCreation failed to allocate data of size " << size;
|
||||
} else {
|
||||
aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
|
||||
aStream.read((char*)mData, size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2934,6 +2935,10 @@ RecordedFontData::~RecordedFontData()
|
||||
inline bool
|
||||
RecordedFontData::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
if (!mData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<NativeFontResource> fontResource =
|
||||
Factory::CreateNativeFontResource(mData, mFontDetails.size,
|
||||
aTranslator->GetReferenceDrawTarget()->GetBackendType(),
|
||||
@ -2967,8 +2972,12 @@ RecordedFontData::OutputSimpleEventInfo(std::stringstream &aStringStream) const
|
||||
inline void
|
||||
RecordedFontData::SetFontData(const uint8_t *aData, uint32_t aSize, uint32_t aIndex)
|
||||
{
|
||||
mData = new uint8_t[aSize];
|
||||
memcpy(mData, aData, aSize);
|
||||
mData = new (fallible) uint8_t[aSize];
|
||||
if (!mData) {
|
||||
gfxCriticalNote << "RecordedFontData failed to allocate data for recording of size " << aSize;
|
||||
} else {
|
||||
memcpy(mData, aData, aSize);
|
||||
}
|
||||
mFontDetails.fontDataKey =
|
||||
SFNTData::GetUniqueKey(aData, aSize, 0, nullptr);
|
||||
mFontDetails.size = aSize;
|
||||
@ -2997,8 +3006,12 @@ RecordedFontData::RecordedFontData(S &aStream)
|
||||
ReadElement(aStream, mType);
|
||||
ReadElement(aStream, mFontDetails.fontDataKey);
|
||||
ReadElement(aStream, mFontDetails.size);
|
||||
mData = new uint8_t[mFontDetails.size];
|
||||
aStream.read((char*)mData, mFontDetails.size);
|
||||
mData = new (fallible) uint8_t[mFontDetails.size];
|
||||
if (!mData) {
|
||||
gfxCriticalNote << "RecordedFontData failed to allocate data for playback of size " << mFontDetails.size;
|
||||
} else {
|
||||
aStream.read((char*)mData, mFontDetails.size);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
|
Loading…
Reference in New Issue
Block a user