merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-09-25 14:22:30 +02:00
Родитель 930046f14c cda9c17f4b
Коммит 996fc54b8d
109 изменённых файлов: 2637 добавлений и 872 удалений

Просмотреть файл

@ -460,7 +460,7 @@ TextAttrsMgr::FontFamilyTextAttr::
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
gfxFont* font = fontGroup->GetFontAt(0);
gfxFont* font = fontGroup->GetFirstValidFont();
gfxFontEntry* fontEntry = font->GetFontEntry();
aFamily = fontEntry->FamilyName();
return true;
@ -618,7 +618,7 @@ TextAttrsMgr::FontWeightTextAttr::
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
gfxFont *font = fontGroup->GetFontAt(0);
gfxFont *font = fontGroup->GetFirstValidFont();
// When there doesn't exist a bold font in the family and so the rendering of
// a non-bold font face is changed so that the user sees what looks like a

Просмотреть файл

@ -57,7 +57,7 @@
#include "nsImageFrame.h"
#include "nsIObserverService.h"
#include "nsLayoutUtils.h"
#include "nsObjectFrame.h"
#include "nsPluginFrame.h"
#include "nsSVGPathGeometryFrame.h"
#include "nsTreeBodyFrame.h"
#include "nsTreeColumns.h"
@ -263,11 +263,11 @@ NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback)
#endif
already_AddRefed<Accessible>
nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame,
nsAccessibilityService::CreatePluginAccessible(nsPluginFrame* aFrame,
nsIContent* aContent,
Accessible* aContext)
{
// nsObjectFrame means a plugin, so we need to use the accessibility support
// nsPluginFrame means a plugin, so we need to use the accessibility support
// of the plugin.
if (aFrame->GetRect().IsEmpty())
return nullptr;
@ -1619,8 +1619,8 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
newAcc = new OuterDocAccessible(aContent, document);
break;
case ePluginType: {
nsObjectFrame* objectFrame = do_QueryFrame(aFrame);
newAcc = CreatePluginAccessible(objectFrame, aContent, aContext);
nsPluginFrame* pluginFrame = do_QueryFrame(aFrame);
newAcc = CreatePluginAccessible(pluginFrame, aContent, aContext);
break;
}
case eTextLeafType:

Просмотреть файл

@ -15,7 +15,7 @@
#include "nsIObserver.h"
class nsImageFrame;
class nsObjectFrame;
class nsPluginFrame;
class nsITreeView;
namespace mozilla {
@ -63,7 +63,7 @@ public:
virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
bool aCanCreate);
already_AddRefed<Accessible>
CreatePluginAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent,
Accessible* aContext);
/**

Просмотреть файл

@ -24,7 +24,7 @@ class nsINode;
class nsIContent;
class nsIFrame;
class nsIPresShell;
class nsObjectFrame;
class nsPluginFrame;
// 10ff6dca-b219-4b64-9a4c-67a62b86edce
#define NS_IACCESSIBILITYSERVICE_IID \

Просмотреть файл

@ -182,7 +182,8 @@ sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily)
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName();
const nsString& name =
fm->GetThebesFontGroup()->GetFirstValidFont()->GetName();
if (name.IsEmpty())
return S_FALSE;

Просмотреть файл

@ -48,14 +48,14 @@ class MachCommands(MachCommandBase):
dirs_to_files = {}
for path, dirs, files in os.walk(js_src_dir):
js_files = [f for f in files if f.endswith(('.js', '.jsm'))]
js_files = [f for f in files if f.endswith(('.js', '.jsm', '.html'))]
if not js_files:
continue
relative = mozpath.relpath(path, js_src_dir)
dirs_to_files[relative] = js_files
moz_build = """# AUTOMATICALLY GENERATED FROM moz.build.in AND mach. DO NOT EDIT.
moz_build = """# AUTOMATICALLY GENERATED FROM mozbuild.template AND mach. DO NOT EDIT.
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -399,6 +399,7 @@ EXTRA_JS_MODULES.commonjs.sdk.ui.button.view += [
EXTRA_JS_MODULES.commonjs.sdk.ui.frame += [
'source/lib/sdk/ui/frame/model.js',
'source/lib/sdk/ui/frame/view.html',
'source/lib/sdk/ui/frame/view.js',
]

Просмотреть файл

@ -8,8 +8,11 @@ BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
JETPACK_PACKAGE_MANIFESTS += ['source/test/jetpack-package.ini']
JETPACK_ADDON_MANIFESTS += ['source/test/addons/jetpack-addon.ini']
DIRS += ["source/modules/system"]
EXTRA_JS_MODULES.sdk += [
'source/app-extension/bootstrap.js',
]
EXTRA_JS_MODULES.sdk.system += [
'source/modules/system/Startup.js',
'source/modules/system/XulApp.js',
]

Просмотреть файл

@ -744,14 +744,14 @@ pref("hal.processPriorityManager.gonk.LowCPUNice", 18);
// priority can be enabled by setting this pref to a value between 1 and 99.
// Note that audio processing currently runs at RT priority 2 or 3 at most.
//
// If RT priority is disabled, then the compositor nice value is used. The
// code will default to ANDROID_PRIORITY_URGENT_DISPLAY which is -8. Per gfx
// request we are keeping the compositor at nice level 0 until we can complete
// the investigation in bug 982972.
// If RT priority is disabled, then the compositor nice value is used. We prefer
// to use a nice value of -4, which matches Android's preferences. Setting a preference
// of RT priority 1 would mean it is higher than audio, which is -16. The compositor
// priority must be below the audio thread.
//
// Do not change these values without gfx team review.
pref("hal.gonk.COMPOSITOR.rt_priority", 0);
pref("hal.gonk.COMPOSITOR.nice", 0);
pref("hal.gonk.COMPOSITOR.nice", -4);
// Fire a memory pressure event when the system has less than Xmb of memory
// remaining. You should probably set this just above Y.KillUnderKB for

Просмотреть файл

@ -305,6 +305,8 @@ nsInProcessTabChildGlobal::PreHandleEvent(EventChainPreVisitor& aVisitor)
nsresult
nsInProcessTabChildGlobal::InitTabChildGlobal()
{
// If you change this, please change GetCompartmentName() in XPCJSRuntime.cpp
// accordingly.
nsAutoCString id;
id.AssignLiteral("inProcessTabChildGlobal");
nsIURI* uri = mOwner->OwnerDoc()->GetDocumentURI();

Просмотреть файл

@ -68,7 +68,7 @@
#include "nsIChannelPolicy.h"
#include "nsChannelPolicy.h"
#include "GeckoProfiler.h"
#include "nsObjectFrame.h"
#include "nsPluginFrame.h"
#include "nsDOMClassInfo.h"
#include "nsWrapperCacheInlines.h"
#include "nsDOMJSUtils.h"
@ -860,7 +860,7 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
// dangling. (Bug 854082)
nsIFrame* frame = thisContent->GetPrimaryFrame();
if (frame && mInstanceOwner) {
mInstanceOwner->SetFrame(static_cast<nsObjectFrame*>(frame));
mInstanceOwner->SetFrame(static_cast<nsPluginFrame*>(frame));
// Bug 870216 - Adobe Reader renders with incorrect dimensions until it gets
// a second SetWindow call. This is otherwise redundant.
@ -1296,7 +1296,7 @@ nsObjectLoadingContent::HasNewFrame(nsIObjectFrame* aFrame)
// Otherwise, we're just changing frames
// Set up relationship between instance owner and frame.
nsObjectFrame *objFrame = static_cast<nsObjectFrame*>(aFrame);
nsPluginFrame *objFrame = static_cast<nsPluginFrame*>(aFrame);
mInstanceOwner->SetFrame(objFrame);
return NS_OK;
@ -2718,13 +2718,13 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
return eType_Null;
}
nsObjectFrame*
nsPluginFrame*
nsObjectLoadingContent::GetExistingFrame()
{
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
nsIFrame* frame = thisContent->GetPrimaryFrame();
nsIObjectFrame* objFrame = do_QueryFrame(frame);
return static_cast<nsObjectFrame*>(objFrame);
return static_cast<nsPluginFrame*>(objFrame);
}
void
@ -3576,7 +3576,7 @@ nsObjectLoadingContent::GetPluginJSObject(JSContext *cx,
JS::MutableHandle<JSObject*> plugin_proto)
{
// NB: We need an AutoEnterCompartment because we can be called from
// nsObjectFrame when the plugin loads after the JS object for our content
// nsPluginFrame when the plugin loads after the JS object for our content
// node has been created.
JSAutoCompartment ac(cx, obj);

Просмотреть файл

@ -26,7 +26,7 @@
class nsAsyncInstantiateEvent;
class nsStopPluginRunnable;
class AutoSetInstantiatingToFalse;
class nsObjectFrame;
class nsPluginFrame;
class nsFrameLoader;
class nsXULElement;
class nsPluginInstanceOwner;
@ -502,7 +502,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
* Gets the frame that's associated with this content node.
* Does not flush.
*/
nsObjectFrame* GetExistingFrame();
nsPluginFrame* GetExistingFrame();
// Helper class for SetupProtoChain
class SetupProtoChainRunner MOZ_FINAL : public nsIRunnable

Просмотреть файл

@ -12,11 +12,11 @@ EXPORTS += [
UNIFIED_SOURCES += [
'BlankDecoderModule.cpp',
'MP4Decoder.cpp',
'PlatformDecoderModule.cpp',
]
SOURCES += [
'MP4Decoder.cpp',
'MP4Reader.cpp',
]

Просмотреть файл

@ -22,6 +22,8 @@
#include "nsITimer.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "VideoUtils.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/dom/WakeLock.h"
#include <binder/IPCThreadState.h>
#include <stagefright/foundation/ADebug.h>
@ -215,6 +217,7 @@ status_t AudioOffloadPlayer::ChangeState(MediaDecoder::PlayState aState)
static void ResetCallback(nsITimer* aTimer, void* aClosure)
{
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __FUNCTION__));
AudioOffloadPlayer* player = static_cast<AudioOffloadPlayer*>(aClosure);
if (player) {
player->Reset();
@ -227,6 +230,8 @@ void AudioOffloadPlayer::Pause(bool aPlayPendingSamples)
if (mStarted) {
CHECK(mAudioSink.get());
WakeLockCreate();
if (aPlayPendingSamples) {
mAudioSink->Stop();
} else {
@ -252,6 +257,7 @@ status_t AudioOffloadPlayer::Play()
if (mResetTimer) {
mResetTimer->Cancel();
mResetTimer = nullptr;
WakeLockRelease();
}
status_t err = OK;
@ -281,6 +287,7 @@ status_t AudioOffloadPlayer::Play()
void AudioOffloadPlayer::Reset()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mStarted) {
return;
}
@ -323,6 +330,8 @@ void AudioOffloadPlayer::Reset()
mStarted = false;
mPlaying = false;
mStartPosUs = 0;
WakeLockRelease();
}
status_t AudioOffloadPlayer::SeekTo(int64_t aTimeUs, bool aDispatchSeekEvents)
@ -711,4 +720,30 @@ void AudioOffloadPlayer::SetVolume(double aVolume)
mAudioSink->SetVolume((float) aVolume);
}
void AudioOffloadPlayer::WakeLockCreate()
{
MOZ_ASSERT(NS_IsMainThread());
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __FUNCTION__));
if (!mWakeLock) {
nsRefPtr<dom::power::PowerManagerService> pmService =
dom::power::PowerManagerService::GetInstance();
NS_ENSURE_TRUE_VOID(pmService);
ErrorResult rv;
mWakeLock = pmService->NewWakeLock(NS_LITERAL_STRING("cpu"), nullptr, rv);
}
}
void AudioOffloadPlayer::WakeLockRelease()
{
MOZ_ASSERT(NS_IsMainThread());
AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("%s", __FUNCTION__));
if (mWakeLock) {
ErrorResult rv;
mWakeLock->Unlock(rv);
NS_WARN_IF_FALSE(!rv.Failed(), "Failed to unlock the wakelock.");
mWakeLock = nullptr;
}
}
} // namespace mozilla

Просмотреть файл

@ -33,6 +33,10 @@
namespace mozilla {
namespace dom {
class WakeLock;
}
/**
* AudioOffloadPlayer adds support for audio tunneling to a digital signal
* processor (DSP) in the device chipset. With tunneling, audio decoding is
@ -193,6 +197,10 @@ private:
// OFFLOAD_PAUSE_MAX_USECS. Used only from main thread so no lock is needed.
nsCOMPtr<nsITimer> mResetTimer;
// To avoid device suspend when mResetTimer is going to be triggered.
// Used only from main thread so no lock is needed.
nsRefPtr<mozilla::dom::WakeLock> mWakeLock;
int64_t GetMediaTimeUs();
// Provide the playback position in microseconds from total number of
@ -240,6 +248,9 @@ private:
nsresult StartTimeUpdate();
nsresult StopTimeUpdate();
void WakeLockCreate();
void WakeLockRelease();
// Notify end of stream by sending PlaybackEnded event to observer
// (i.e.MediaDecoder)
void NotifyAudioEOS();

Просмотреть файл

@ -114,12 +114,8 @@ Animation::GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
bool isEndOfFinalIteration = false;
// Get the normalized time within the active interval.
TimeDuration activeTime;
// FIXME: The following check that the active duration is not equal to Forever
// is a temporary workaround to avoid overflow and should be removed once
// bug 1039924 is fixed.
if (result.mActiveDuration != TimeDuration::Forever() &&
localTime >= aTiming.mDelay + result.mActiveDuration) {
StickyTimeDuration activeTime;
if (localTime >= aTiming.mDelay + result.mActiveDuration) {
result.mPhase = ComputedTiming::AnimationPhase_After;
if (!aTiming.FillsForwards()) {
// The animation isn't active or filling at this time.
@ -148,10 +144,10 @@ Animation::GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
}
// Get the position within the current iteration.
TimeDuration iterationTime;
StickyTimeDuration iterationTime;
if (aTiming.mIterationDuration != zeroDuration) {
iterationTime = isEndOfFinalIteration
? aTiming.mIterationDuration
? StickyTimeDuration(aTiming.mIterationDuration)
: activeTime % aTiming.mIterationDuration;
} /* else, iterationTime is zero */
@ -215,19 +211,20 @@ Animation::GetComputedTimingAt(const Nullable<TimeDuration>& aLocalTime,
return result;
}
TimeDuration
StickyTimeDuration
Animation::ActiveDuration(const AnimationTiming& aTiming)
{
if (aTiming.mIterationCount == mozilla::PositiveInfinity<float>()) {
// An animation that repeats forever has an infinite active duration
// unless its iteration duration is zero, in which case it has a zero
// active duration.
const TimeDuration zeroDuration;
const StickyTimeDuration zeroDuration;
return aTiming.mIterationDuration == zeroDuration
? zeroDuration
: TimeDuration::Forever();
: StickyTimeDuration::Forever();
}
return aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount);
return StickyTimeDuration(
aTiming.mIterationDuration.MultDouble(aTiming.mIterationCount));
}
bool

Просмотреть файл

@ -11,6 +11,7 @@
#include "nsIDocument.h"
#include "nsWrapperCache.h"
#include "mozilla/Attributes.h"
#include "mozilla/StickyTimeDuration.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/Nullable.h"
@ -61,8 +62,9 @@ struct ComputedTiming
static const double kNullTimeFraction;
// The total duration of the animation including all iterations.
// Will equal TimeDuration::Forever() if the animation repeats indefinitely.
TimeDuration mActiveDuration;
// Will equal StickyTimeDuration::Forever() if the animation repeats
// indefinitely.
StickyTimeDuration mActiveDuration;
// Will be kNullTimeFraction if the animation is neither animating nor
// filling at the sampled time.
@ -205,7 +207,8 @@ public:
}
// Return the duration of the active interval for the given timing parameters.
static TimeDuration ActiveDuration(const AnimationTiming& aTiming);
static StickyTimeDuration
ActiveDuration(const AnimationTiming& aTiming);
// After transitions finish they need to be retained for one throttle-able
// cycle (for reasons see explanation in

Просмотреть файл

@ -41,6 +41,11 @@ nsPerformanceTiming::nsPerformanceTiming(nsPerformance* aPerformance,
{
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
SetIsDOMBinding();
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
mZeroTime = 0;
}
// The aHttpChannel argument is null if this nsPerformanceTiming object
// is being used for the navigation timing (document) and has a non-null
// value for the resource timing (any resources within the page).

Просмотреть файл

@ -51,7 +51,7 @@ GetCameraLog()
return sLog;
}
WindowTable* nsDOMCameraManager::sActiveWindows = nullptr;
::WindowTable* nsDOMCameraManager::sActiveWindows = nullptr;
nsDOMCameraManager::nsDOMCameraManager(nsPIDOMWindow* aWindow)
: mWindowId(aWindow->WindowID())
@ -109,7 +109,7 @@ nsDOMCameraManager::CreateInstance(nsPIDOMWindow* aWindow)
{
// Initialize the shared active window tracker
if (!sActiveWindows) {
sActiveWindows = new WindowTable();
sActiveWindows = new ::WindowTable();
}
nsRefPtr<nsDOMCameraManager> cameraManager =

Просмотреть файл

@ -13,7 +13,7 @@ EXPORTS += [
'DOMCameraManager.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'CameraControlImpl.cpp',
'CameraPreferences.cpp',
'CameraPreviewMediaStream.cpp',
@ -38,7 +38,7 @@ if CONFIG['MOZ_B2G_CAMERA']:
'TestGonkCameraHardware.cpp',
]
else:
SOURCES += [
UNIFIED_SOURCES += [
'FallbackCameraControl.cpp',
'FallbackCameraManager.cpp',
]

Просмотреть файл

@ -3103,7 +3103,7 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
virtual void SetText(const char16_t* text, int32_t length, nsBidiDirection direction)
{
mFontgrp->UpdateFontList(); // ensure user font generation is current
mFontgrp->UpdateUserFonts(); // ensure user font generation is current
mTextRun = mFontgrp->MakeTextRun(text,
length,
mThebes,
@ -3455,9 +3455,9 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
processor.mPt.x -= anchorX * totalWidth;
// offset pt.y based on text baseline
processor.mFontgrp->UpdateFontList(); // ensure user font generation is current
NS_ASSERTION(processor.mFontgrp->FontListLength()>0, "font group contains no fonts");
const gfxFont::Metrics& fontMetrics = processor.mFontgrp->GetFontAt(0)->GetMetrics();
processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current
const gfxFont::Metrics& fontMetrics =
processor.mFontgrp->GetFirstValidFont()->GetMetrics();
gfxFloat anchorY;

Просмотреть файл

@ -3,6 +3,8 @@ support-files =
webgl-mochitest/driver-info.js
webgl-mochitest/webgl-util.js
[webgl-mochitest/test-backbuffer-channels.html]
[webgl-mochitest/test-hidden-alpha.html]
[webgl-mochitest/test_depth_readpixels.html]
[webgl-mochitest/test_draw.html]
[webgl-mochitest/test_fb_param.html]

Просмотреть файл

@ -31,22 +31,29 @@ def ReadLocalFile(include):
kSimpleTestReplacement = '''\n
<script>
// SimpleTest.js replacement
function ok(val, text) {
function debug(text) {
var elem = document.getElementById('mochi-to-testcase-output');
elem.innerHTML += '\\n<br/>\\n' + text;
}
function ok(val, text) {
var status = val ? 'Test <font color=\\'green\\'>passed</font>: '
: 'Test <font color=\\'red\\' >FAILED</font>: ';
elem.innerHTML += '\\n<br/>\\n' + status + text;
debug(status + text);
}
function todo(val, text) {
ok(!val, 'Todo: ' + text);
var status = val ? 'Test <font color=\\'orange\\'>UNEXPECTED PASS</font>: '
: 'Test <font color=\\'blue\\' >todo</font>: ';
debug(status + text);
}
</script>
<div id='mochi-to-testcase-output'></div>
\n'''
fin = open(mochiPath, 'r')
fout = open(testPath, 'w')
fin = open(mochiPath, 'rb')
fout = open(testPath, 'wb')
includePattern = re.compile('<script\\s*src=[\'"](.*)\\.js[\'"]>\\s*</script>')
cssPattern = re.compile('<link\\s*rel=[\'"]stylesheet[\'"]\\s*href=[\'"]([^=>]*)[\'"]>')
for line in fin:

Просмотреть файл

@ -0,0 +1,111 @@
<!DOCTYPE HTML>
<title>WebGL test: bug 958723</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script src="driver-info.js"></script>
<script src="webgl-util.js"></script>
<body>
<script>
function TestAttribs(attribs) {
debug('Testing attribs: ' + JSON.stringify(attribs));
var canvas = document.createElement('canvas');
var gl = canvas.getContext('experimental-webgl', attribs);
ok(gl, 'No tested attribs should result in failure to create a context');
if (!gl)
return;
var actual = gl.getContextAttributes();
ok(actual.alpha == attribs.alpha,
'Resulting `alpha` should match request.');
ok(actual.premultipliedAlpha == attribs.premultipliedAlpha,
'Resulting `premultipliedAlpha` should match request.');
ok(actual.preserveDrawingBuffer == attribs.preserveDrawingBuffer,
'Resulting `preserveDrawingBuffer` should match request.');
// "The depth, stencil and antialias attributes, when set to true, are
// requests, not requirements."
if (!attribs.antialias) {
ok(!actual.antialias, 'No `antialias` if not requested.');
}
if (!attribs.depth) {
ok(!actual.depth, 'No `depth` if not requested.');
}
if (!attribs.stencil) {
ok(!actual.stencil, 'No `stencil` if not requested.');
}
var hasAlpha = !!gl.getParameter(gl.ALPHA_BITS);
var hasDepth = !!gl.getParameter(gl.DEPTH_BITS);
var hasStencil = !!gl.getParameter(gl.STENCIL_BITS);
var hasAntialias = !!gl.getParameter(gl.SAMPLES);
ok(hasAlpha == actual.alpha, 'Bits should match `alpha` attrib.');
ok(hasAntialias == actual.antialias, 'Bits should match `antialias` attrib.');
ok(hasDepth == actual.depth, 'Bits should match `depth` attrib.');
ok(hasStencil == actual.stencil, 'Bits should match `stencil` attrib.');
}
function CloneAttribs(attribs) {
return {
alpha: attribs.alpha,
antialias: attribs.antialias,
depth: attribs.depth,
premultipliedAlpha: attribs.premultipliedAlpha,
preserveDrawingBuffer: attribs.preserveDrawingBuffer,
stencil: attribs.stencil,
};
}
function SplitForAttrib(list, attrib) {
var ret = [];
for (var i in list) {
var cur = list[i];
if (cur[attrib])
throw 'Attrib is already true.';
var clone = CloneAttribs(cur);
clone[attrib] = true;
ret.push(cur);
ret.push(clone);
}
return ret;
}
function GenAttribList() {
var base = {
alpha: false,
antialias: false,
depth: false,
premultipliedAlpha: false,
preserveDrawingBuffer: false,
stencil: false,
};
var list = [base];
list = SplitForAttrib(list, 'alpha');
list = SplitForAttrib(list, 'antialias');
list = SplitForAttrib(list, 'depth');
list = SplitForAttrib(list, 'premultipliedAlpha');
list = SplitForAttrib(list, 'preserveDrawingBuffer');
list = SplitForAttrib(list, 'stencil');
if (list.length != 1<<6)
throw 'Attribs list length wrong: ' + list.length;
return list;
}
var list = GenAttribList();
for (var i in list) {
var attribs = list[i];
TestAttribs(attribs);
}
ok(true, 'Test complete.');
</script>

Просмотреть файл

@ -0,0 +1,153 @@
<!DOCTYPE HTML>
<title>WebGL test: Hidden alpha on no-alpha contexts</title>
<script src='/tests/SimpleTest/SimpleTest.js'></script>
<link rel='stylesheet' href='/tests/SimpleTest/test.css'>
<script src='driver-info.js'></script>
<script src='webgl-util.js'></script>
<body>
<script id='vs' type='x-shader/x-vertex'>
attribute vec2 aPosCoord;
void main(void) {
gl_Position = vec4(aPosCoord, 0.0, 1.0);
}
</script>
<script id='fs' type='x-shader/x-fragment'>
precision mediump float;
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<canvas id='canvas' style='border: none;' width='100' height='100'></canvas>
<script>
var posCoords_arr = new Float32Array(2 * 4);
var posCoords_buff = null;
function DrawQuad(gl, prog, x0, y0, x1, y1) {
gl.useProgram(prog);
if (!posCoords_buff) {
posCoords_buff = gl.createBuffer();
}
gl.bindBuffer(gl.ARRAY_BUFFER, posCoords_buff);
posCoords_arr[0] = x0;
posCoords_arr[1] = y0;
posCoords_arr[2] = x1;
posCoords_arr[3] = y0;
posCoords_arr[4] = x0;
posCoords_arr[5] = y1;
posCoords_arr[6] = x1;
posCoords_arr[7] = y1;
gl.bufferData(gl.ARRAY_BUFFER, posCoords_arr, gl.STREAM_DRAW);
gl.enableVertexAttribArray(prog.aPosCoord);
gl.vertexAttribPointer(prog.aPosCoord, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
function DrawSquare(gl, prog, size) {
DrawQuad(gl, prog, -size, -size, size, size);
}
function Reset(gl) {
gl.canvas.width += 1;
gl.canvas.width -= 1;
}
function ReadCenterPixel(gl) {
var w = gl.drawingbufferWidth;
var h = gl.drawingbufferHeight;
var ret = new Uint8Array(4);
gl.readPixels(w/2, h/2, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ret);
return ret;
}
function Test(gl, prog) {
gl.enable(gl.BLEND);
gl.blendFunc(gl.ZERO, gl.DST_ALPHA);
var iColor = 64;
var fColor = iColor / 255.0;
//////////////////
debug('clear(R,G,B,0)');
Reset(gl);
gl.clearColor(fColor, fColor, fColor, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
var dataURL_pre = gl.canvas.toDataURL();
//console.log('Before blending: ' + dataURL_pre);
DrawSquare(gl, prog, 0.7);
var pixel = ReadCenterPixel(gl);
ok(pixel[0] == iColor &&
pixel[1] == iColor &&
pixel[2] == iColor, 'Color should be the same.');
ok(pixel[3] == 255, 'No-alpha should always readback as 1.0 alpha.');
var dataURL_post = gl.canvas.toDataURL();
//console.log('After blending: ' + dataURL_post);
ok(dataURL_post == dataURL_pre,
'toDataURL should be unchanged after blending.');
//////////////////
debug('mask(R,G,B,0), clear(R,G,B,1)');
Reset(gl);
gl.colorMask(true, true, true, false);
gl.clearColor(fColor, fColor, fColor, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.colorMask(true, true, true, true);
dataURL_pre = gl.canvas.toDataURL();
//console.log('Before blending: ' + dataURL_pre);
DrawSquare(gl, prog, 0.7);
var pixel = ReadCenterPixel(gl);
ok(pixel[0] == iColor &&
pixel[1] == iColor &&
pixel[2] == iColor, 'Color should be the same.');
ok(pixel[3] == 255, 'No-alpha should always readback as 1.0 alpha.');
ok(gl.getError() == 0, 'Should have no errors.');
dataURL_post = gl.canvas.toDataURL();
//console.log('After blending: ' + dataURL_post);
ok(dataURL_post == dataURL_pre,
'toDataURL should be unchanged after blending.');
ok(true, 'Test complete.');
}
(function(){
var canvas = document.getElementById('canvas');
var attribs = {
alpha: false,
antialias: false,
premultipliedAlpha: false,
};
var gl = canvas.getContext('experimental-webgl', attribs);
ok(gl, 'WebGL should work.');
ok(gl.getParameter(gl.ALPHA_BITS) == 0, 'Shouldn\'t have alpha bits.');
var prog = WebGLUtil.createProgramByIds(gl, 'vs', 'fs');
ok(prog, 'Program should link.');
prog.aPosCoord = gl.getAttribLocation(prog, 'aPosCoord');
setTimeout(function(){ Test(gl, prog); }, 500);
})();
</script>
</body>

Просмотреть файл

@ -23,7 +23,7 @@ using mozilla::DefaultXDisplay;
#include "nsDisplayList.h"
#include "ImageLayers.h"
#include "GLImages.h"
#include "nsObjectFrame.h"
#include "nsPluginFrame.h"
#include "nsIPluginDocument.h"
#include "nsIStringStream.h"
#include "nsNetUtil.h"
@ -222,7 +222,7 @@ nsPluginInstanceOwner::GetImageContainer()
// NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render
// into, set y-flip flags, etc, so we do this at the beginning.
gfxSize resolution = mObjectFrame->PresContext()->PresShell()->GetCumulativeResolution();
gfxSize resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution();
ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution.width, resolution.height)).Size();
mInstance->NotifySize(nsIntSize(screenSize.width, screenSize.height));
@ -322,7 +322,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
else
mPluginWindow = nullptr;
mObjectFrame = nullptr;
mPluginFrame = nullptr;
mContent = nullptr;
mWidgetCreationComplete = false;
#ifdef XP_MACOSX
@ -365,7 +365,7 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
NS_DispatchToMainThread(event);
}
mObjectFrame = nullptr;
mPluginFrame = nullptr;
PLUG_DeletePluginNativeWindow(mPluginWindow);
mPluginWindow = nullptr;
@ -543,10 +543,10 @@ NS_IMETHODIMP nsPluginInstanceOwner::ShowStatus(const char16_t *aStatusMsg)
{
nsresult rv = NS_ERROR_FAILURE;
if (!mObjectFrame) {
if (!mPluginFrame) {
return rv;
}
nsCOMPtr<nsIDocShellTreeItem> docShellItem = mObjectFrame->PresContext()->GetDocShell();
nsCOMPtr<nsIDocShellTreeItem> docShellItem = mPluginFrame->PresContext()->GetDocShell();
if (NS_FAILED(rv) || !docShellItem) {
return rv;
}
@ -582,7 +582,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
{
// If our object frame has gone away, we won't be able to determine
// up-to-date-ness, so just fire off the event.
if (mWaitingForPaint && (!mObjectFrame || IsUpToDate())) {
if (mWaitingForPaint && (!mPluginFrame || IsUpToDate())) {
// We don't care when the event is dispatched as long as it's "soon",
// since whoever needs it will be waiting for it.
nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, true);
@ -590,7 +590,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
mWaitingForPaint = false;
}
if (!mObjectFrame || !invalidRect || !mWidgetVisible)
if (!mPluginFrame || !invalidRect || !mWidgetVisible)
return NS_ERROR_FAILURE;
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
@ -621,7 +621,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
double scaleFactor = 1.0;
GetContentsScaleFactor(&scaleFactor);
rect.ScaleRoundOut(scaleFactor);
mObjectFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect);
mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN, &rect);
return NS_OK;
}
@ -633,22 +633,22 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion)
NS_IMETHODIMP
nsPluginInstanceOwner::RedrawPlugin()
{
if (mObjectFrame) {
mObjectFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN);
if (mPluginFrame) {
mPluginFrame->InvalidateLayer(nsDisplayItem::TYPE_PLUGIN);
}
return NS_OK;
}
NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
{
if (!mObjectFrame) {
if (!mPluginFrame) {
NS_WARNING("plugin owner has no owner in getting doc's window handle");
return NS_ERROR_FAILURE;
}
#if defined(XP_WIN)
void** pvalue = (void**)value;
nsViewManager* vm = mObjectFrame->PresContext()->GetPresShell()->GetViewManager();
nsViewManager* vm = mPluginFrame->PresContext()->GetPresShell()->GetViewManager();
if (!vm)
return NS_ERROR_FAILURE;
#if defined(XP_WIN)
@ -680,7 +680,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
// fixing both the caret and ability to interact issues for a windowless control in a non document aligned windw
// does not seem to be possible without a change to the flash plugin
nsIWidget* win = mObjectFrame->GetNearestWidget();
nsIWidget* win = mPluginFrame->GetNearestWidget();
if (win) {
nsView *view = nsView::GetViewFor(win);
NS_ASSERTION(view, "No view for widget");
@ -708,7 +708,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value)
return NS_OK;
#elif (defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)) && defined(MOZ_X11)
// X11 window managers want the toplevel window for WM_TRANSIENT_FOR.
nsIWidget* win = mObjectFrame->GetNearestWidget();
nsIWidget* win = mPluginFrame->GetNearestWidget();
if (!win)
return NS_ERROR_FAILURE;
*static_cast<Window*>(value) = (long unsigned int)win->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW);
@ -1127,8 +1127,8 @@ GetOffsetRootContent(nsIFrame* aFrame)
LayoutDeviceRect nsPluginInstanceOwner::GetPluginRect()
{
// Get the offset of the content relative to the page
nsRect bounds = mObjectFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mObjectFrame);
LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mObjectFrame->PresContext()->AppUnitsPerDevPixel());
nsRect bounds = mPluginFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mPluginFrame);
LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mPluginFrame->PresContext()->AppUnitsPerDevPixel());
return LayoutDeviceRect(rect);
}
@ -1350,7 +1350,7 @@ nsPluginInstanceOwner::ProcessMouseDown(nsIDOMEvent* aMouseEvent)
// if the plugin is windowless, we need to set focus ourselves
// otherwise, we might not get key events
if (mObjectFrame && mPluginWindow &&
if (mPluginFrame && mPluginWindow &&
mPluginWindow->type == NPWindowTypeDrawable) {
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
@ -1482,7 +1482,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
{
nsEventStatus rv = nsEventStatus_eIgnore;
if (!mInstance || !mObjectFrame) // if mInstance is null, we shouldn't be here
if (!mInstance || !mPluginFrame) // if mInstance is null, we shouldn't be here
return nsEventStatus_eIgnore;
#ifdef XP_MACOSX
@ -1503,9 +1503,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
NPCocoaEvent synthCocoaEvent;
const NPCocoaEvent* event = static_cast<const NPCocoaEvent*>(anEvent.mPluginEvent);
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsPresContext* presContext = mObjectFrame->PresContext();
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPresContext* presContext = mPluginFrame->PresContext();
// Plugin event coordinates need to be translated from device pixels
// into "display pixels" in HiDPI modes.
double scaleFactor = 1.0;
@ -1521,9 +1521,9 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
{
// Ignore mouse-moved events that happen as part of a dragging
// operation that started over another frame. See bug 525078.
nsRefPtr<nsFrameSelection> frameselection = mObjectFrame->GetFrameSelection();
nsRefPtr<nsFrameSelection> frameselection = mPluginFrame->GetFrameSelection();
if (!frameselection->GetDragState() ||
(nsIPresShell::GetCapturingContent() == mObjectFrame->GetContent())) {
(nsIPresShell::GetCapturingContent() == mPluginFrame->GetContent())) {
synthCocoaEvent.type = NPCocoaEventMouseMoved;
synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
@ -1542,7 +1542,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
// convert it into a mouse-entered event (in the Cocoa Event Model).
// See bug 525078.
if (anEvent.AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
(nsIPresShell::GetCapturingContent() != mObjectFrame->GetContent())) {
(nsIPresShell::GetCapturingContent() != mPluginFrame->GetContent())) {
synthCocoaEvent.type = NPCocoaEventMouseEntered;
synthCocoaEvent.data.mouse.pluginX = static_cast<double>(ptPx.x);
synthCocoaEvent.data.mouse.pluginY = static_cast<double>(ptPx.y);
@ -1652,12 +1652,12 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
anEvent.message == NS_MOUSE_MOVE,
"Incorrect event type for coordinate translation");
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsPresContext* presContext = mObjectFrame->PresContext();
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsPresContext* presContext = mPluginFrame->PresContext();
nsIntPoint ptPx(presContext->AppUnitsToDevPixels(pt.x),
presContext->AppUnitsToDevPixels(pt.y));
nsIntPoint widgetPtPx = ptPx + mObjectFrame->GetWindowOriginInPixels(true);
nsIntPoint widgetPtPx = ptPx + mPluginFrame->GetWindowOriginInPixels(true);
const_cast<NPEvent*>(pPluginEvent)->lParam = MAKELPARAM(widgetPtPx.x, widgetPtPx.y);
}
}
@ -1680,7 +1680,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
if (pPluginEvent && !pPluginEvent->event) {
// Don't send null events to plugins.
NS_WARNING("nsObjectFrame ProcessEvent: trying to send null event to plugin.");
NS_WARNING("nsPluginFrame ProcessEvent: trying to send null event to plugin.");
return rv;
}
@ -1712,10 +1712,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
}
// Get reference point relative to plugin origin.
const nsPresContext* presContext = mObjectFrame->PresContext();
const nsPresContext* presContext = mPluginFrame->PresContext();
nsPoint appPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
presContext->AppUnitsToDevPixels(appPoint.y));
const WidgetMouseEvent& mouseEvent = *anEvent.AsMouseEvent();
@ -1913,10 +1913,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
}
// Get reference point relative to plugin origin.
const nsPresContext* presContext = mObjectFrame->PresContext();
const nsPresContext* presContext = mPluginFrame->PresContext();
nsPoint appPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mObjectFrame) -
mObjectFrame->GetContentRectRelativeToSelf().TopLeft();
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
presContext->AppUnitsToDevPixels(appPoint.y));
@ -2045,7 +2045,7 @@ nsPluginInstanceOwner::Destroy()
#ifdef XP_MACOSX
void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgContext)
{
if (!mInstance || !mObjectFrame)
if (!mInstance || !mPluginFrame)
return;
gfxRect dirtyRectCopy = aDirtyRect;
@ -2067,7 +2067,7 @@ void nsPluginInstanceOwner::Paint(const gfxRect& aDirtyRect, CGContextRef cgCont
void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext)
{
if (!mInstance || !mObjectFrame)
if (!mInstance || !mPluginFrame)
return;
// The context given here is only valid during the HandleEvent call.
@ -2087,7 +2087,7 @@ void nsPluginInstanceOwner::DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGCon
#ifdef XP_WIN
void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
{
if (!mInstance || !mObjectFrame)
if (!mInstance || !mPluginFrame)
return;
NPEvent pluginEvent;
@ -2104,7 +2104,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect)
{
if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState || mFullScreen)
if (!mInstance || !mPluginFrame || !mPluginDocumentActiveState || mFullScreen)
return;
int32_t model = mInstance->GetANPDrawingModel();
@ -2169,7 +2169,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect)
{
if (!mInstance || !mObjectFrame)
if (!mInstance || !mPluginFrame)
return;
// to provide crisper and faster drawing.
@ -2372,7 +2372,7 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
// done at a higher level than this (content).
nsIFrame* frame = aContent->GetPrimaryFrame();
nsIObjectFrame* iObjFrame = do_QueryFrame(frame);
nsObjectFrame* objFrame = static_cast<nsObjectFrame*>(iObjFrame);
nsPluginFrame* objFrame = static_cast<nsPluginFrame*>(iObjFrame);
if (objFrame) {
SetFrame(objFrame);
// Some plugins require a specific sequence of shutdown and startup when
@ -2524,9 +2524,9 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
#endif
}
if (mObjectFrame) {
if (mPluginFrame) {
// nullptr widget is fine, will result in windowless setup.
mObjectFrame->PrepForDrawing(mWidget);
mPluginFrame->PrepForDrawing(mWidget);
}
if (windowless) {
@ -2573,21 +2573,21 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
void* nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState)
{
if (!mWidget || !mPluginWindow || !mInstance || !mObjectFrame)
if (!mWidget || !mPluginWindow || !mInstance || !mPluginFrame)
return nullptr;
nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
if (!pluginWidget)
return nullptr;
// If we've already set up a CGContext in nsObjectFrame::PaintPlugin(), we
// If we've already set up a CGContext in nsPluginFrame::PaintPlugin(), we
// don't want calls to SetPluginPortAndDetectChange() to step on our work.
if (mInCGPaintLevel < 1) {
SetPluginPortAndDetectChange();
}
// We'll need the top-level Cocoa window for the Cocoa event model.
nsIWidget* widget = mObjectFrame->GetNearestWidget();
nsIWidget* widget = mPluginFrame->GetNearestWidget();
if (!widget)
return nullptr;
void *cocoaTopLevelWindow = widget->GetNativeData(NS_NATIVE_WINDOW);
@ -2722,7 +2722,7 @@ void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(bool aSetWindow)
const NPWindow oldWindow = *mPluginWindow;
bool windowless = (mPluginWindow->type == NPWindowTypeDrawable);
nsIntPoint origin = mObjectFrame->GetWindowOriginInPixels(windowless);
nsIntPoint origin = mPluginFrame->GetWindowOriginInPixels(windowless);
mPluginWindow->x = origin.x;
mPluginWindow->y = origin.y;
@ -2786,8 +2786,8 @@ nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
NS_IMETHODIMP
nsPluginInstanceOwner::CallSetWindow()
{
if (mObjectFrame) {
mObjectFrame->CallSetWindow(false);
if (mPluginFrame) {
mPluginFrame->CallSetWindow(false);
} else if (mInstance) {
if (UseAsyncRendering()) {
mInstance->AsyncSetWindow(mPluginWindow);
@ -2818,32 +2818,32 @@ nsPluginInstanceOwner::GetContentsScaleFactor(double *result)
return NS_OK;
}
void nsPluginInstanceOwner::SetFrame(nsObjectFrame *aFrame)
void nsPluginInstanceOwner::SetFrame(nsPluginFrame *aFrame)
{
// Don't do anything if the frame situation hasn't changed.
if (mObjectFrame == aFrame) {
if (mPluginFrame == aFrame) {
return;
}
// If we already have a frame that is changing or going away...
if (mObjectFrame) {
if (mPluginFrame) {
// Make sure the old frame isn't holding a reference to us.
mObjectFrame->SetInstanceOwner(nullptr);
mPluginFrame->SetInstanceOwner(nullptr);
}
// Swap in the new frame (or no frame)
mObjectFrame = aFrame;
mPluginFrame = aFrame;
// Set up a new frame
if (mObjectFrame) {
mObjectFrame->SetInstanceOwner(this);
if (mPluginFrame) {
mPluginFrame->SetInstanceOwner(this);
// Can only call PrepForDrawing on an object frame once. Don't do it here unless
// widget creation is complete. Doesn't matter if we actually have a widget.
if (mWidgetCreationComplete) {
mObjectFrame->PrepForDrawing(mWidget);
mPluginFrame->PrepForDrawing(mWidget);
}
mObjectFrame->FixupWindow(mObjectFrame->GetContentRectRelativeToSelf().Size());
mObjectFrame->InvalidateFrame();
mPluginFrame->FixupWindow(mPluginFrame->GetContentRectRelativeToSelf().Size());
mPluginFrame->InvalidateFrame();
nsFocusManager* fm = nsFocusManager::GetFocusManager();
const nsIContent* content = aFrame->GetContent();
@ -2853,9 +2853,9 @@ void nsPluginInstanceOwner::SetFrame(nsObjectFrame *aFrame)
}
}
nsObjectFrame* nsPluginInstanceOwner::GetFrame()
nsPluginFrame* nsPluginInstanceOwner::GetFrame()
{
return mObjectFrame;
return mPluginFrame;
}
NS_IMETHODIMP nsPluginInstanceOwner::PrivateModeChanged(bool aEnabled)

Просмотреть файл

@ -26,7 +26,7 @@
class nsIInputStream;
struct nsIntRect;
class nsPluginDOMContextMenuListener;
class nsObjectFrame;
class nsPluginFrame;
class nsDisplayListBuilder;
namespace mozilla {
@ -143,9 +143,9 @@ public:
// changed, and SetWindow() needs to be called again.
void* SetPluginPortAndDetectChange();
// Flag when we've set up a Thebes (and CoreGraphics) context in
// nsObjectFrame::PaintPlugin(). We need to know this in
// nsPluginFrame::PaintPlugin(). We need to know this in
// FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has
// been called from nsObjectFrame::PaintPlugin() when we're using the
// been called from nsPluginFrame::PaintPlugin() when we're using the
// CoreGraphics drawing model).
void BeginCGPaint();
void EndCGPaint();
@ -155,8 +155,8 @@ public:
void UpdateDocumentActiveState(bool aIsActive);
#endif // XP_MACOSX
void SetFrame(nsObjectFrame *aFrame);
nsObjectFrame* GetFrame();
void SetFrame(nsPluginFrame *aFrame);
nsPluginFrame* GetFrame();
uint32_t GetLastEventloopNestingLevel() const {
return mLastEventloopNestingLevel;
@ -276,7 +276,7 @@ private:
nsPluginNativeWindow *mPluginWindow;
nsRefPtr<nsNPAPIPluginInstance> mInstance;
nsObjectFrame *mObjectFrame;
nsPluginFrame *mPluginFrame;
nsIContent *mContent; // WEAK, content owns us
nsCString mDocumentBase;
bool mWidgetCreationComplete;

Просмотреть файл

@ -145,7 +145,7 @@ nsresult nsPluginNativeWindowGtk::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance>
// Make sure to resize and re-place the window if required.
SetAllocation();
// Need to reset "window" each time as nsObjectFrame::DidReflow sets it
// Need to reset "window" each time as nsPluginFrame::DidReflow sets it
// to the ancestor window.
#if (MOZ_WIDGET_GTK == 2)
if (GTK_IS_XTBIN(mSocketWidget)) {
@ -225,7 +225,7 @@ nsresult nsPluginNativeWindowGtk::CreateXEmbedWindow(bool aEnableXtFocus) {
SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget)));
// Fill out the ws_info structure.
// (The windowless case is done in nsObjectFrame.cpp.)
// (The windowless case is done in nsPluginFrame.cpp.)
GdkWindow *gdkWindow = gdk_x11_window_lookup_for_display(display, GetWindow());
if(!gdkWindow)
return NS_ERROR_FAILURE;

Просмотреть файл

@ -1948,7 +1948,7 @@ PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
break;
case RENDER_BACK_ONE:
// Handle a double pass render used in alpha extraction for transparent
// plugins. (See nsObjectFrame and gfxWindowsNativeDrawing for details.)
// plugins. (See nsPluginFrame and gfxWindowsNativeDrawing for details.)
// We render twice, once to the shared dib, and once to a cache which
// we copy back on a second paint. These paints can't be spread across
// multiple rpc messages as delays cause animation frame changes.

Просмотреть файл

@ -367,7 +367,7 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
if (drawingModel == NPDrawingModelCoreAnimation ||
drawingModel == NPDrawingModelInvalidatingCoreAnimation) {
// We need to request CoreGraphics otherwise
// the nsObjectFrame will try to draw a CALayer
// the nsPluginFrame will try to draw a CALayer
// that can not be shared across process.
mDrawingModel = drawingModel;
*result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
@ -1231,7 +1231,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
case WM_WINDOWPOSCHANGED:
{
// We send this in nsObjectFrame just before painting
// We send this in nsPluginFrame just before painting
return SendWindowPosChanged(npremoteevent);
}
break;

Просмотреть файл

@ -100,7 +100,7 @@ pluginDoSetWindow(InstanceData* instanceData, NPWindow* newWindow)
{
// Ugh. Due to a terrible Gecko bug, we have to ignore position changes
// when the clip rect doesn't change; the position can be wrong
// when set by a path other than nsObjectFrame::FixUpPluginWindow.
// when set by a path other than nsPluginFrame::FixUpPluginWindow.
int32_t oldX = instanceData->window.x;
int32_t oldY = instanceData->window.y;
bool clipChanged =

Просмотреть файл

@ -32,6 +32,7 @@ support-files =
res7.resource^headers^
res8.resource
res8.resource^headers^
resource_timing.js
[test_497898.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || toolkit == 'android' #Bug 931116, b2g desktop specific, initial triage

Просмотреть файл

Просмотреть файл

@ -86,6 +86,10 @@ function firstCheck() {
ok(!!entries[0], "redirected res8.resource is missing from entries");
checkRedirectCrossOriginResourceSameOrigin(entries[0]);
entries = window.performance.getEntriesByName("http://mochi.test:8888/tests/dom/tests/mochitest/general/resource_timing.js");
ok(!!entries[0], "same origin resource_timing.js is missing from entries");
checkSameOrigin(entries[0]);
is(bufferFullCounter, expectedBufferFullEvents, "Buffer full was called");
finishTests();
}
@ -176,6 +180,7 @@ function finishTests() {
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res6.resource"> <!-- cross origin, Timing-Allow-Origin: "" (empty string) -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res7.resource"> <!-- cross origin, Timing-Allow-Origin: http://mochi.test:8888 http://test1.com header -->
<object data="http://test1.example.com/tests/dom/tests/mochitest/general/res8.resource"> <!-- double cross origin redirect -->
<script type="text/javascript" src="http://mochi.test:8888/tests/dom/tests/mochitest/general/resource_timing.js"></script> <!-- same origin script -->
</div>
</body>

Просмотреть файл

@ -6,7 +6,7 @@ support-files =
[test_notification_basics.html]
[test_notification_storage.html]
skip-if = (toolkit == 'gonk' && debug) #debug-only timeout
skip-if = (toolkit == 'gonk')
[test_bug931307.html]
skip-if = (toolkit == 'gonk' && debug) #debug-only timeout
[test_notification_resend.html]

Просмотреть файл

@ -95,6 +95,7 @@ static const char *sExtensionNames[] = {
"GL_ARB_texture_float",
"GL_ARB_texture_non_power_of_two",
"GL_ARB_texture_rectangle",
"GL_ARB_texture_storage",
"GL_ARB_transform_feedback2",
"GL_ARB_uniform_buffer_object",
"GL_ARB_vertex_array_object",
@ -930,6 +931,22 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
}
}
if (IsSupported(GLFeature::texture_storage)) {
SymLoadStruct coreSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fTexStorage2D, { "TexStorage2D", nullptr } },
{ (PRFuncPtr*) &mSymbols.fTexStorage3D, { "TexStorage3D", nullptr } },
END_SYMBOLS
};
if (!LoadSymbols(coreSymbols, trygl, prefix)) {
NS_ERROR("GL supports texture storage without supplying its functions.");
MarkUnsupported(GLFeature::texture_storage);
MarkExtensionUnsupported(ARB_texture_storage);
ClearSymbols(coreSymbols);
}
}
// ARB_transform_feedback2/NV_transform_feedback2 is a
// superset of EXT_transform_feedback/NV_transform_feedback
// and adds glPauseTransformFeedback &

Просмотреть файл

@ -118,6 +118,7 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature)
texture_half_float,
texture_half_float_linear,
texture_non_power_of_two,
texture_storage,
transform_feedback2,
uniform_buffer_object,
uniform_matrix_nonsquare,
@ -374,6 +375,7 @@ public:
ARB_texture_float,
ARB_texture_non_power_of_two,
ARB_texture_rectangle,
ARB_texture_storage,
ARB_transform_feedback2,
ARB_uniform_buffer_object,
ARB_vertex_array_object,
@ -3066,6 +3068,23 @@ public:
AFTER_GL_CALL;
}
// -----------------------------------------------------------------------------
// Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fTexStorage2D);
mSymbols.fTexStorage2D(target, levels, internalformat, width, height);
AFTER_GL_CALL;
}
void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
BEFORE_GL_CALL;
ASSERT_SYMBOL_PRESENT(fTexStorage3D);
mSymbols.fTexStorage3D(target, levels, internalformat, width, height, depth);
AFTER_GL_CALL;
}
// -----------------------------------------------------------------------------
// 3D Textures

Просмотреть файл

@ -508,6 +508,20 @@ static const FeatureInfo sFeatureInfoArr[] = {
GLContext::Extensions_End
}
},
{
"texture_storage",
420, // OpenGL version
300, // OpenGL ES version
GLContext::ARB_texture_storage,
{
/*
* Not including GL_EXT_texture_storage here because it
* doesn't guarantee glTexStorage3D, which is required for
* WebGL 2.
*/
GLContext::Extensions_End
}
},
{
"transform_feedback2",
400, // OpenGL version

Просмотреть файл

@ -580,6 +580,12 @@ struct GLContextSymbols
typedef void (GLAPIENTRY * PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
PFNGLGETSAMPLERPARAMETERFVPROC fGetSamplerParameterfv;
// texture_storage
typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
PFNGLTEXSTORAGE2DPROC fTexStorage2D;
typedef void (GLAPIENTRY * PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
PFNGLTEXSTORAGE3DPROC fTexStorage3D;
// uniform_buffer_object
typedef void (GLAPIENTRY * PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount,
const GLchar* const* uniformNames, GLuint* uniformIndices);

Просмотреть файл

@ -11,6 +11,73 @@
namespace mozilla {
namespace gl {
// Returns `EGL_NO_SURFACE` (`0`) on error.
static EGLSurface
CreatePBufferSurface(GLLibraryEGL* egl,
EGLDisplay display,
EGLConfig config,
const gfx::IntSize& size)
{
auto width = size.width;
auto height = size.height;
EGLint attribs[] = {
LOCAL_EGL_WIDTH, width,
LOCAL_EGL_HEIGHT, height,
LOCAL_EGL_NONE
};
DebugOnly<EGLint> preCallErr = egl->fGetError();
MOZ_ASSERT(preCallErr == LOCAL_EGL_SUCCESS);
EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs);
EGLint err = egl->fGetError();
if (err != LOCAL_EGL_SUCCESS)
return 0;
return surface;
}
/*static*/ UniquePtr<SharedSurface_ANGLEShareHandle>
SharedSurface_ANGLEShareHandle::Create(GLContext* gl,
EGLContext context, EGLConfig config,
const gfx::IntSize& size, bool hasAlpha)
{
GLLibraryEGL* egl = &sEGLLibrary;
MOZ_ASSERT(egl);
MOZ_ASSERT(egl->IsExtensionSupported(
GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle));
if (!context || !config)
return nullptr;
EGLDisplay display = egl->Display();
EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size);
if (!pbuffer)
return nullptr;
// Declare everything before 'goto's.
HANDLE shareHandle = nullptr;
bool ok = egl->fQuerySurfacePointerANGLE(display,
pbuffer,
LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
&shareHandle);
if (!ok) {
egl->fDestroySurface(egl->Display(), pbuffer);
return nullptr;
}
GLuint fence = 0;
if (gl->IsExtensionSupported(GLContext::NV_fence)) {
gl->MakeCurrent();
gl->fGenFences(1, &fence);
}
typedef SharedSurface_ANGLEShareHandle ptrT;
UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, context,
pbuffer, shareHandle, fence) );
return Move(ret);
}
EGLDisplay
SharedSurface_ANGLEShareHandle::Display()
{
@ -114,6 +181,9 @@ SharedSurface_ANGLEShareHandle::PollSync_ContentThread_Impl()
return PollSync();
}
////////////////////////////////////////////////////////////////////////////////
// Factory
static void
FillPBufferAttribs_ByBits(nsTArray<EGLint>& aAttrs,
int redBits, int greenBits,
@ -169,15 +239,25 @@ FillPBufferAttribs_BySizes(nsTArray<EGLint>& attribs,
alpha = 8;
}
FillPBufferAttribs_ByBits(attribs,
red, green, blue, alpha,
depthBits, stencilBits);
FillPBufferAttribs_ByBits(attribs, red, green, blue, alpha, depthBits,
stencilBits);
}
static bool
DoesAttribBitsMatchCapBool(GLLibraryEGL* egl, EGLConfig config, EGLint attrib,
bool capBool)
{
EGLint bits = 0;
egl->fGetConfigAttrib(egl->Display(), config, attrib, &bits);
MOZ_ASSERT(egl->fGetError() == LOCAL_EGL_SUCCESS);
bool hasBits = !!bits;
return hasBits == capBool;
}
static EGLConfig
ChooseConfig(GLContext* gl,
GLLibraryEGL* egl,
const SurfaceCaps& caps)
ChooseConfig(GLContext* gl, GLLibraryEGL* egl, const SurfaceCaps& caps)
{
MOZ_ASSERT(egl);
MOZ_ASSERT(caps.color);
@ -188,28 +268,43 @@ ChooseConfig(GLContext* gl,
// Ok, now we have everything.
nsTArray<EGLint> attribs(32);
FillPBufferAttribs_BySizes(attribs,
caps.bpp16, caps.alpha,
depthBits, stencilBits);
FillPBufferAttribs_BySizes(attribs, caps.bpp16, caps.alpha, depthBits,
stencilBits);
// Time to try to get this config:
EGLConfig configs[64];
int numConfigs = sizeof(configs)/sizeof(EGLConfig);
int foundConfigs = 0;
if (!egl->fChooseConfig(egl->Display(),
attribs.Elements(),
configs, numConfigs,
&foundConfigs) ||
if (!egl->fChooseConfig(egl->Display(), attribs.Elements(), configs,
numConfigs, &foundConfigs) ||
!foundConfigs)
{
NS_WARNING("No configs found for the requested formats.");
return EGL_NO_CONFIG;
}
// TODO: Pick a config progamatically instead of hoping that
// the first config will be minimally matching our request.
EGLConfig config = configs[0];
// The requests passed to ChooseConfig are treated as minimums. If you ask
// for 0 bits of alpha, we might still get 8 bits.
EGLConfig config = EGL_NO_CONFIG;
for (int i = 0; i < foundConfigs; i++) {
EGLConfig cur = configs[0];
if (DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_ALPHA_SIZE,
caps.alpha) &&
DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_DEPTH_SIZE,
caps.depth) &&
DoesAttribBitsMatchCapBool(egl, cur, LOCAL_EGL_STENCIL_SIZE,
caps.stencil))
{
config = cur;
break;
}
}
if (config == EGL_NO_CONFIG) {
NS_WARNING("No acceptable EGLConfig found.");
return EGL_NO_CONFIG;
}
if (gl->DebugMode()) {
egl->DumpEGLConfig(config);
@ -218,73 +313,6 @@ ChooseConfig(GLContext* gl,
return config;
}
// Returns `EGL_NO_SURFACE` (`0`) on error.
static EGLSurface
CreatePBufferSurface(GLLibraryEGL* egl,
EGLDisplay display,
EGLConfig config,
const gfx::IntSize& size)
{
auto width = size.width;
auto height = size.height;
EGLint attribs[] = {
LOCAL_EGL_WIDTH, width,
LOCAL_EGL_HEIGHT, height,
LOCAL_EGL_NONE
};
DebugOnly<EGLint> preCallErr = egl->fGetError();
MOZ_ASSERT(preCallErr == LOCAL_EGL_SUCCESS);
EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs);
EGLint err = egl->fGetError();
if (err != LOCAL_EGL_SUCCESS)
return 0;
return surface;
}
/*static*/ UniquePtr<SharedSurface_ANGLEShareHandle>
SharedSurface_ANGLEShareHandle::Create(GLContext* gl,
EGLContext context, EGLConfig config,
const gfx::IntSize& size, bool hasAlpha)
{
GLLibraryEGL* egl = &sEGLLibrary;
MOZ_ASSERT(egl);
MOZ_ASSERT(egl->IsExtensionSupported(
GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle));
if (!context || !config)
return nullptr;
EGLDisplay display = egl->Display();
EGLSurface pbuffer = CreatePBufferSurface(egl, display, config, size);
if (!pbuffer)
return nullptr;
// Declare everything before 'goto's.
HANDLE shareHandle = nullptr;
bool ok = egl->fQuerySurfacePointerANGLE(display,
pbuffer,
LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
&shareHandle);
if (!ok) {
egl->fDestroySurface(egl->Display(), pbuffer);
return nullptr;
}
GLuint fence = 0;
if (gl->IsExtensionSupported(GLContext::NV_fence)) {
gl->MakeCurrent();
gl->fGenFences(1, &fence);
}
typedef SharedSurface_ANGLEShareHandle ptrT;
UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, context,
pbuffer, shareHandle, fence) );
return Move(ret);
}
/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
const SurfaceCaps& caps)
@ -295,25 +323,36 @@ SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle;
if (!egl->IsExtensionSupported(ext))
{
return nullptr;
}
bool success;
typedef SurfaceFactory_ANGLEShareHandle ptrT;
UniquePtr<ptrT> ret( new ptrT(gl, egl, caps) );
UniquePtr<ptrT> ret( new ptrT(gl, egl, caps, &success) );
if (!success)
return nullptr;
return Move(ret);
}
SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
GLLibraryEGL* egl,
const SurfaceCaps& caps)
const SurfaceCaps& caps,
bool* const out_success)
: SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
, mProdGL(gl)
, mEGL(egl)
{
mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps);
MOZ_ASSERT(out_success);
*out_success = false;
mContext = GLContextEGL::Cast(mProdGL)->GetEGLContext();
mConfig = ChooseConfig(mProdGL, mEGL, mReadCaps);
if (mConfig == EGL_NO_CONFIG)
return;
MOZ_ASSERT(mConfig && mContext);
*out_success = true;
}
} /* namespace gl */

Просмотреть файл

@ -88,7 +88,8 @@ public:
protected:
SurfaceFactory_ANGLEShareHandle(GLContext* gl,
GLLibraryEGL* egl,
const SurfaceCaps& caps);
const SurfaceCaps& caps,
bool* const out_success);
virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
bool hasAlpha = mReadCaps.alpha;

Просмотреть файл

@ -143,7 +143,7 @@ nsFontCache::GetMetricsFor(const nsFont& aFont, nsIAtom* aLanguage,
mFontMetrics.RemoveElementAt(i);
mFontMetrics.AppendElement(fm);
}
fm->GetThebesFontGroup()->UpdateFontList();
fm->GetThebesFontGroup()->UpdateUserFonts();
NS_ADDREF(aMetrics = fm);
return NS_OK;
}

Просмотреть файл

@ -132,9 +132,6 @@ nsFontMetrics::Init(const nsFont& aFont, nsIAtom* aLanguage,
mFontGroup = gfxPlatform::GetPlatform()->
CreateFontGroup(aFont.fontlist, &style, aUserFontSet);
mFontGroup->SetTextPerfMetrics(aTextPerf);
if (mFontGroup->FontListLength() < 1)
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
@ -150,7 +147,7 @@ nsFontMetrics::Destroy()
const gfxFont::Metrics& nsFontMetrics::GetMetrics() const
{
return mFontGroup->GetFontAt(0)->GetMetrics();
return mFontGroup->GetFirstValidFont()->GetMetrics();
}
nscoord

Просмотреть файл

@ -126,12 +126,6 @@ public:
*/
static int32_t FormatStrideForWidth(gfxImageFormat format, int32_t width);
/* Return the default set of context flags for this surface; these are
* hints to the context about any special rendering considerations. See
* gfxContext::SetFlag for documentation.
*/
virtual int32_t GetDefaultContextFlags() const { return 0; }
static gfxContentType ContentFromFormat(gfxImageFormat format);
void SetSubpixelAntialiasingEnabled(bool aEnabled);

Просмотреть файл

@ -34,13 +34,6 @@ public:
return gfxIntSize(mSize.width, mSize.height);
}
virtual int32_t GetDefaultContextFlags() const
{
return gfxContext::FLAG_SIMPLIFY_OPERATORS |
gfxContext::FLAG_DISABLE_SNAPPING |
gfxContext::FLAG_DISABLE_COPY_BACKGROUND;
}
private:
nsCOMPtr<nsIOutputStream> mStream;
double mXDPI;

Просмотреть файл

@ -41,12 +41,6 @@ public:
return mSize;
}
virtual int32_t GetDefaultContextFlags() const
{
return gfxContext::FLAG_SIMPLIFY_OPERATORS |
gfxContext::FLAG_DISABLE_SNAPPING;
}
private:
nsCOMPtr<nsIOutputStream> mStream;
double mXDPI;

Просмотреть файл

@ -813,7 +813,7 @@ FindFontPatterns(gfxUserFontSet *mUserFontSet,
gfxFontFamily *family = mUserFontSet->LookupFamily(utf16Family);
if (family) {
gfxUserFontEntry* userFontEntry =
mUserFontSet->FindUserFontEntry(family, style, needsBold,
mUserFontSet->FindUserFontEntryAndLoad(family, style, needsBold,
aWaitForUserFont);
if (userFontEntry) {
fontEntry = static_cast<gfxUserFcFontEntry*>
@ -826,7 +826,8 @@ FindFontPatterns(gfxUserFontSet *mUserFontSet,
// and probably never use it
if (!fontEntry && aStyle != NS_FONT_STYLE_NORMAL) {
style.style = NS_FONT_STYLE_NORMAL;
userFontEntry = mUserFontSet->FindUserFontEntry(family, style,
userFontEntry =
mUserFontSet->FindUserFontEntryAndLoad(family, style,
needsBold,
aWaitForUserFont);
if (userFontEntry) {
@ -1308,16 +1309,22 @@ gfxPangoFontGroup::GetBaseFont()
return static_cast<gfxFcFont*>(mFonts[0].Font());
}
gfxFont*
gfxPangoFontGroup::GetFirstValidFont()
{
return GetFontAt(0);
}
gfxFont *
gfxPangoFontGroup::GetFontAt(int32_t i)
{
// If it turns out to be hard for all clients that cache font
// groups to call UpdateFontList at appropriate times, we could
// instead consider just calling UpdateFontList from someplace
// groups to call UpdateUserFonts at appropriate times, we could
// instead consider just calling UpdateUserFonts from someplace
// more central (such as here).
NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
"Whoever was caching this font group should have "
"called UpdateFontList on it");
"called UpdateUserFonts on it");
NS_PRECONDITION(i == 0, "Only have one font");
@ -1325,7 +1332,7 @@ gfxPangoFontGroup::GetFontAt(int32_t i)
}
void
gfxPangoFontGroup::UpdateFontList()
gfxPangoFontGroup::UpdateUserFonts()
{
uint64_t newGeneration = GetGeneration();
if (newGeneration == mCurrGeneration)

Просмотреть файл

@ -30,9 +30,11 @@ public:
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
virtual gfxFont* GetFirstValidFont();
virtual gfxFont *GetFontAt(int32_t i);
virtual void UpdateFontList();
virtual void UpdateUserFonts();
virtual already_AddRefed<gfxFont>
FindFontForChar(uint32_t aCh, uint32_t aPrevCh, int32_t aRunScript,

Просмотреть файл

@ -15,9 +15,8 @@ gfxQuartzSurface::MakeInvalid()
mSize = gfxIntSize(-1, -1);
}
gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat format,
bool aForPrinting)
: mCGContext(nullptr), mSize(desiredSize), mForPrinting(aForPrinting)
gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat format)
: mCGContext(nullptr), mSize(desiredSize)
{
gfxIntSize size((unsigned int) floor(desiredSize.width),
(unsigned int) floor(desiredSize.height));
@ -41,9 +40,8 @@ gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat fo
}
gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
const gfxSize& desiredSize,
bool aForPrinting)
: mCGContext(context), mSize(desiredSize), mForPrinting(aForPrinting)
const gfxSize& desiredSize)
: mCGContext(context), mSize(desiredSize)
{
gfxIntSize size((unsigned int) floor(desiredSize.width),
(unsigned int) floor(desiredSize.height));
@ -66,9 +64,8 @@ gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
}
gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
const gfxIntSize& size,
bool aForPrinting)
: mCGContext(context), mSize(size), mForPrinting(aForPrinting)
const gfxIntSize& size)
: mCGContext(context), mSize(size)
{
if (!CheckSurfaceSize(size))
MakeInvalid();
@ -89,9 +86,8 @@ gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
}
gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf,
const gfxIntSize& aSize,
bool aForPrinting) :
mSize(aSize), mForPrinting(aForPrinting)
const gfxIntSize& aSize) :
mSize(aSize)
{
mCGContext = cairo_quartz_surface_get_cg_context (csurf);
CGContextRetain (mCGContext);
@ -102,9 +98,8 @@ gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf,
gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
const gfxSize& desiredSize,
long stride,
gfxImageFormat format,
bool aForPrinting)
: mCGContext(nullptr), mSize(desiredSize), mForPrinting(aForPrinting)
gfxImageFormat format)
: mCGContext(nullptr), mSize(desiredSize)
{
gfxIntSize size((unsigned int) floor(desiredSize.width),
(unsigned int) floor(desiredSize.height));
@ -130,9 +125,8 @@ gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
const gfxIntSize& aSize,
long stride,
gfxImageFormat format,
bool aForPrinting)
: mCGContext(nullptr), mSize(aSize.width, aSize.height), mForPrinting(aForPrinting)
gfxImageFormat format)
: mCGContext(nullptr), mSize(aSize.width, aSize.height)
{
if (!CheckSurfaceSize(aSize))
MakeInvalid();
@ -173,15 +167,6 @@ gfxQuartzSurface::GetCGContextWithClip(gfxContext *ctx)
return cairo_quartz_get_cg_context_with_clip(ctx->GetCairo());
}
int32_t gfxQuartzSurface::GetDefaultContextFlags() const
{
if (mForPrinting)
return gfxContext::FLAG_DISABLE_SNAPPING |
gfxContext::FLAG_DISABLE_COPY_BACKGROUND;
return 0;
}
already_AddRefed<gfxImageSurface> gfxQuartzSurface::GetAsImageSurface()
{
cairo_surface_t *surface = cairo_quartz_surface_get_image(mSurface);

Просмотреть файл

@ -17,12 +17,12 @@ class gfxImageSurface;
class gfxQuartzSurface : public gfxASurface {
public:
gfxQuartzSurface(const gfxSize& size, gfxImageFormat format, bool aForPrinting = false);
gfxQuartzSurface(CGContextRef context, const gfxSize& size, bool aForPrinting = false);
gfxQuartzSurface(CGContextRef context, const gfxIntSize& size, bool aForPrinting = false);
gfxQuartzSurface(cairo_surface_t *csurf, const gfxIntSize& aSize, bool aForPrinting = false);
gfxQuartzSurface(unsigned char *data, const gfxSize& size, long stride, gfxImageFormat format, bool aForPrinting = false);
gfxQuartzSurface(unsigned char *data, const gfxIntSize& size, long stride, gfxImageFormat format, bool aForPrinting = false);
gfxQuartzSurface(const gfxSize& size, gfxImageFormat format);
gfxQuartzSurface(CGContextRef context, const gfxSize& size);
gfxQuartzSurface(CGContextRef context, const gfxIntSize& size);
gfxQuartzSurface(cairo_surface_t *csurf, const gfxIntSize& aSize);
gfxQuartzSurface(unsigned char *data, const gfxSize& size, long stride, gfxImageFormat format);
gfxQuartzSurface(unsigned char *data, const gfxIntSize& size, long stride, gfxImageFormat format);
virtual ~gfxQuartzSurface();
@ -35,8 +35,6 @@ public:
CGContextRef GetCGContextWithClip(gfxContext *ctx);
virtual int32_t GetDefaultContextFlags() const;
already_AddRefed<gfxImageSurface> GetAsImageSurface();
protected:
@ -44,7 +42,6 @@ protected:
CGContextRef mCGContext;
gfxSize mSize;
bool mForPrinting;
};
#endif /* GFX_QUARTZSURFACE_H */

Просмотреть файл

@ -1469,11 +1469,15 @@ gfxFontGroup::gfxFontGroup(const FontFamilyList& aFontFamilyList,
, mSkipDrawing(false)
{
// We don't use SetUserFontSet() here, as we want to unconditionally call
// BuildFontList() rather than only do UpdateFontList() if it changed.
// BuildFontList() rather than only do UpdateUserFonts() if it changed.
mCurrGeneration = GetGeneration();
BuildFontList();
}
gfxFontGroup::~gfxFontGroup()
{
}
void
gfxFontGroup::FindGenericFonts(FontFamilyType aGenericType,
nsIAtom *aLanguage,
@ -1611,77 +1615,7 @@ gfxFontGroup::BuildFontList()
{
// gfxPangoFontGroup behaves differently, so this method is a no-op on that platform
#if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID)
EnumerateFontList(mStyle.language);
// at this point, fontlist should have been filled in
// get a default font if none exists
if (mFonts.Length() == 0) {
bool needsBold;
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
gfxFontFamily *defaultFamily = pfl->GetDefaultFont(&mStyle);
NS_ASSERTION(defaultFamily,
"invalid default font returned by GetDefaultFont");
if (defaultFamily) {
gfxFontEntry *fe = defaultFamily->FindFontForStyle(mStyle,
needsBold);
if (fe) {
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle,
needsBold);
if (font) {
mFonts.AppendElement(FamilyFace(defaultFamily, font));
}
}
}
if (mFonts.Length() == 0) {
// Try for a "font of last resort...."
// Because an empty font list would be Really Bad for later code
// that assumes it will be able to get valid metrics for layout,
// just look for the first usable font and put in the list.
// (see bug 554544)
nsAutoTArray<nsRefPtr<gfxFontFamily>,200> families;
pfl->GetFontFamilyList(families);
uint32_t count = families.Length();
for (uint32_t i = 0; i < count; ++i) {
gfxFontEntry *fe = families[i]->FindFontForStyle(mStyle,
needsBold);
if (fe) {
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle,
needsBold);
if (font) {
mFonts.AppendElement(FamilyFace(families[i], font));
break;
}
}
}
}
if (mFonts.Length() == 0) {
// an empty font list at this point is fatal; we're not going to
// be able to do even the most basic layout operations
char msg[256]; // CHECK buffer length if revising message below
nsAutoString families;
mFamilyList.ToString(families);
sprintf(msg, "unable to find a usable font (%.220s)",
NS_ConvertUTF16toUTF8(families).get());
NS_RUNTIMEABORT(msg);
}
}
if (!mStyle.systemFont) {
uint32_t count = mFonts.Length();
for (uint32_t i = 0; i < count; ++i) {
gfxFont* font = mFonts[i].Font();
if (font->GetFontEntry()->mIsBadUnderlineFont) {
gfxFloat first = mFonts[0].Font()->GetMetrics().underlineOffset;
gfxFloat bad = font->GetMetrics().underlineOffset;
mUnderlineOffset = std::min(first, bad);
break;
}
}
}
#endif
}
@ -1700,21 +1634,11 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
// font of the same name, even if we fail to actually get a fontEntry
// here; we'll fall back to the next name in the CSS font-family list.
if (mUserFontSet) {
// If the fontSet matches the family, but the font has not yet finished
// loading (nor has its load timeout fired), the fontGroup should wait
// for the download, and not actually draw its text yet.
// add the userfont to the fontlist whether it's already been loaded
// or not. loading is initiated during font matching.
family = mUserFontSet->LookupFamily(aName);
if (family) {
bool waitForUserFont = false;
gfxUserFontEntry* userFontEntry =
mUserFontSet->FindUserFontEntry(family, mStyle, needsBold,
waitForUserFont);
if (userFontEntry) {
fe = userFontEntry->GetPlatformFontEntry();
}
if (!fe && waitForUserFont) {
mSkipDrawing = true;
}
fe = mUserFontSet->FindUserFontEntry(family, mStyle, needsBold);
}
}
}
@ -1730,10 +1654,7 @@ gfxFontGroup::FindPlatformFont(const nsAString& aName,
// add to the font group, unless it's already there
if (fe && !HasFont(fe)) {
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
if (font) {
mFonts.AppendElement(FamilyFace(family, font));
}
mFonts.AppendElement(FamilyFace(family, fe, needsBold));
}
}
@ -1742,15 +1663,142 @@ gfxFontGroup::HasFont(const gfxFontEntry *aFontEntry)
{
uint32_t count = mFonts.Length();
for (uint32_t i = 0; i < count; ++i) {
if (mFonts[i].Font()->GetFontEntry() == aFontEntry)
if (mFonts[i].FontEntry() == aFontEntry) {
return true;
}
}
return false;
}
gfxFontGroup::~gfxFontGroup()
gfxFont*
gfxFontGroup::GetFontAt(int32_t i)
{
mFonts.Clear();
if (uint32_t(i) >= mFonts.Length()) {
return nullptr;
}
FamilyFace& ff = mFonts[i];
if (ff.IsInvalid() || ff.IsLoading()) {
return nullptr;
}
nsRefPtr<gfxFont> font = ff.Font();
if (!font) {
gfxFontEntry *fe = mFonts[i].FontEntry();
if (fe->mIsUserFontContainer) {
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe);
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED) {
ufe->Load();
if (ufe->WaitForUserFont()) {
mSkipDrawing = true;
}
}
fe = ufe->GetPlatformFontEntry();
if (!fe) {
return nullptr;
}
}
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold());
if (font && !font->Valid()) {
ff.SetInvalid();
return nullptr;
}
mFonts[i].SetFont(font);
}
return font.get();
}
gfxFont*
gfxFontGroup::GetDefaultFont()
{
if (mDefaultFont) {
return mDefaultFont.get();
}
bool needsBold;
gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
gfxFontFamily *defaultFamily = pfl->GetDefaultFont(&mStyle);
NS_ASSERTION(defaultFamily,
"invalid default font returned by GetDefaultFont");
if (defaultFamily) {
gfxFontEntry *fe = defaultFamily->FindFontForStyle(mStyle,
needsBold);
if (fe) {
mDefaultFont = fe->FindOrMakeFont(&mStyle, needsBold);
}
}
if (!mDefaultFont) {
// Try for a "font of last resort...."
// Because an empty font list would be Really Bad for later code
// that assumes it will be able to get valid metrics for layout,
// just look for the first usable font and put in the list.
// (see bug 554544)
nsAutoTArray<nsRefPtr<gfxFontFamily>,200> families;
pfl->GetFontFamilyList(families);
uint32_t count = families.Length();
for (uint32_t i = 0; i < count; ++i) {
gfxFontEntry *fe = families[i]->FindFontForStyle(mStyle,
needsBold);
if (fe) {
mDefaultFont = fe->FindOrMakeFont(&mStyle, needsBold);
}
}
}
if (!mDefaultFont) {
// an empty font list at this point is fatal; we're not going to
// be able to do even the most basic layout operations
char msg[256]; // CHECK buffer length if revising message below
nsAutoString families;
mFamilyList.ToString(families);
sprintf(msg, "unable to find a usable font (%.220s)",
NS_ConvertUTF16toUTF8(families).get());
NS_RUNTIMEABORT(msg);
}
return mDefaultFont.get();
}
gfxFont*
gfxFontGroup::GetFirstValidFont()
{
uint32_t count = mFonts.Length();
for (uint32_t i = 0; i < count; ++i) {
FamilyFace& ff = mFonts[i];
if (ff.IsInvalid()) {
continue;
}
// already have a font?
gfxFont* font = ff.Font();
if (font) {
return font;
}
// need to build a font, loading userfont if not loaded
if (ff.IsUserFont()) {
gfxUserFontEntry* ufe =
static_cast<gfxUserFontEntry*>(mFonts[i].FontEntry());
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED) {
ufe->Load();
if (ufe->WaitForUserFont()) {
mSkipDrawing = true;
}
}
if (ufe->LoadState() != gfxUserFontEntry::STATUS_LOADED) {
continue;
}
}
font = GetFontAt(i);
if (font) {
return font;
}
}
return GetDefaultFont();
}
gfxFont *
@ -1759,7 +1807,7 @@ gfxFontGroup::GetFirstMathFont()
uint32_t count = mFonts.Length();
for (uint32_t i = 0; i < count; ++i) {
gfxFont* font = GetFontAt(i);
if (font->GetFontEntry()->TryGetMathTable()) {
if (font && font->GetFontEntry()->TryGetMathTable()) {
return font;
}
}
@ -1818,7 +1866,7 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, uint32_t aFlags)
orientation = TEXT_ORIENT_VERTICAL_UPRIGHT;
}
gfxFont *font = GetFontAt(0);
gfxFont *font = GetFirstValidFont();
if (MOZ_UNLIKELY(GetStyle()->size == 0)) {
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
// them, and always create at least size 1 fonts, i.e. they still
@ -1864,7 +1912,7 @@ gfxFontGroup::MakeBlankTextRun(uint32_t aLength,
if (orientation == TEXT_ORIENT_VERTICAL_MIXED) {
orientation = TEXT_ORIENT_VERTICAL_UPRIGHT;
}
textRun->AddGlyphRun(GetFontAt(0), gfxTextRange::kFontGroup, 0, false,
textRun->AddGlyphRun(GetFirstValidFont(), gfxTextRange::kFontGroup, 0, false,
orientation);
return textRun;
}
@ -1876,8 +1924,8 @@ gfxFontGroup::MakeHyphenTextRun(gfxContext *aCtx, uint32_t aAppUnitsPerDevUnit)
// it's better to use ASCII '-' from the primary font than to fall back to
// U+2010 from some other, possibly poorly-matching face
static const char16_t hyphen = 0x2010;
gfxFont *font = GetFontAt(0);
if (font && font->HasCharacter(hyphen)) {
gfxFont *font = GetFirstValidFont();
if (font->HasCharacter(hyphen)) {
return MakeTextRun(&hyphen, 1, aCtx, aAppUnitsPerDevUnit,
gfxFontGroup::TEXT_IS_PERSISTENT);
}
@ -2147,7 +2195,15 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
NS_ASSERTION(aTextRun->GetShapingState() != gfxTextRun::eShapingState_Aborted,
"don't call InitScriptRun with aborted shaping state");
gfxFont *mainFont = GetFontAt(0);
#if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID)
// non-linux platforms build the fontlist lazily and include userfonts
// so need to confirm the load state of userfonts in the list
if (mUserFontSet && mCurrGeneration != mUserFontSet->GetGeneration()) {
UpdateUserFonts();
}
#endif
gfxFont *mainFont = GetFirstValidFont();
uint32_t runStart = 0;
nsAutoTArray<gfxTextRange,3> fontRanges;
@ -2353,7 +2409,7 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
// Use a Unicode ellipsis if the font supports it,
// otherwise use three ASCII periods as fallback.
gfxFont* firstFont = GetFontAt(0);
gfxFont* firstFont = GetFirstValidFont();
nsString ellipsis = firstFont->HasCharacter(kEllipsisChar[0])
? nsDependentString(kEllipsisChar,
ArrayLength(kEllipsisChar) - 1)
@ -2376,27 +2432,62 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
}
already_AddRefed<gfxFont>
gfxFontGroup::TryAllFamilyMembers(gfxFontFamily* aFamily, uint32_t aCh)
gfxFontGroup::FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh)
{
NS_ASSERTION(mStyle.style != NS_FONT_STYLE_NORMAL,
"should only be called in the italic/oblique case");
if (!aFamily->TestCharacterMap(aCh)) {
return nullptr;
}
// Note that we don't need the actual runScript in matchData for
// gfxFontFamily::SearchAllFontsForChar, it's only used for the
// system-fallback case. So we can just set it to 0 here.
GlobalFontMatch matchData(aCh, 0, &mStyle);
aFamily->SearchAllFontsForChar(&matchData);
gfxFontEntry *fe = matchData.mBestMatch;
if (!fe) {
gfxFontStyle regularStyle = mStyle;
regularStyle.style = NS_FONT_STYLE_NORMAL;
bool needsBold;
gfxFontEntry *fe = aFamily->FindFontForStyle(regularStyle, needsBold);
NS_ASSERTION(!fe->mIsUserFontContainer,
"should only be searching platform fonts");
if (!fe->HasCharacter(aCh)) {
return nullptr;
}
bool needsBold = mStyle.weight >= 600 && !fe->IsBold();
nsRefPtr<gfxFont> font = fe->FindOrMakeFont(&mStyle, needsBold);
if (!font->Valid()) {
return nullptr;
}
return font.forget();
}
gfxFloat
gfxFontGroup::GetUnderlineOffset()
{
if (mUnderlineOffset == UNDERLINE_OFFSET_NOT_SET) {
// if the fontlist contains a bad underline font, make the underline
// offset the min of the first valid font and bad font underline offsets
uint32_t len = mFonts.Length();
for (uint32_t i = 0; i < len; i++) {
FamilyFace& ff = mFonts[i];
if (!ff.IsUserFont() && ff.Family() &&
ff.Family()->IsBadUnderlineFamily()) {
nsRefPtr<gfxFont> font = GetFontAt(i);
if (!font) {
continue;
}
gfxFloat bad = font->GetMetrics().underlineOffset;
gfxFloat first =
GetFirstValidFont()->GetMetrics().underlineOffset;
mUnderlineOffset = std::min(first, bad);
return mUnderlineOffset;
}
}
// no bad underline fonts, use the first valid font's metric
mUnderlineOffset = GetFirstValidFont()->GetMetrics().underlineOffset;
}
return mUnderlineOffset;
}
already_AddRefed<gfxFont>
gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
int32_t aRunScript, gfxFont *aPrevMatchedFont,
@ -2410,18 +2501,26 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
bool isVarSelector = gfxFontUtils::IsVarSelector(aCh);
if (!isJoinControl && !wasJoinCauser && !isVarSelector) {
nsRefPtr<gfxFont> firstFont = mFonts[0].Font();
nsRefPtr<gfxFont> firstFont = GetFontAt(0);
if (firstFont) {
if (firstFont->HasCharacter(aCh)) {
*aMatchType = gfxTextRange::kFontGroup;
return firstFont.forget();
}
// It's possible that another font in the family (e.g. regular face,
// where the requested style was italic) will support the character
nsRefPtr<gfxFont> font = TryAllFamilyMembers(mFonts[0].Family(), aCh);
// If italic, test the regular face to see if it supports character.
// Only do this for platform fonts, not userfonts.
if (mStyle.style != NS_FONT_STYLE_NORMAL &&
!firstFont->GetFontEntry()->IsUserFont()) {
nsRefPtr<gfxFont> font =
FindNonItalicFaceForChar(mFonts[0].Family(), aCh);
if (font) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
}
}
}
// we don't need to check the first font again below
++nextIndex;
}
@ -2459,20 +2558,61 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
}
// 1. check remaining fonts in the font group
uint32_t fontListLength = FontListLength();
uint32_t fontListLength = mFonts.Length();
for (uint32_t i = nextIndex; i < fontListLength; i++) {
nsRefPtr<gfxFont> font = mFonts[i].Font();
if (font->HasCharacter(aCh)) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
FamilyFace& ff = mFonts[i];
if (ff.IsInvalid() || ff.IsLoading()) {
continue;
}
font = TryAllFamilyMembers(mFonts[i].Family(), aCh);
nsRefPtr<gfxFont> font;
// test the font entry, build font if needed
gfxFontEntry *fe = ff.FontEntry();
if (fe->mIsUserFontContainer) {
// for userfonts, need to test the cmap of the platform font entry
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe);
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED) {
ufe->Load();
if (ufe->WaitForUserFont()) {
mSkipDrawing = true;
}
}
gfxFontEntry* pfe = ufe->GetPlatformFontEntry();
if (pfe && pfe->HasCharacter(aCh)) {
font = GetFontAt(i);
if (font) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
}
}
} else if (fe->HasCharacter(aCh)) {
font = GetFontAt(i);
if (font) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
}
}
// If italic, test the regular face to see if it supports the character.
// Only do this for platform fonts, not userfonts.
if (mStyle.style != NS_FONT_STYLE_NORMAL && !ff.IsUserFont()) {
font = FindNonItalicFaceForChar(mFonts[i].Family(), aCh);
if (font) {
*aMatchType = gfxTextRange::kFontGroup;
return font.forget();
}
}
}
if (fontListLength == 0) {
nsRefPtr<gfxFont> defaultFont = GetDefaultFont();
if (defaultFont->HasCharacter(aCh)) {
*aMatchType = gfxTextRange::kFontGroup;
return defaultFont.forget();
}
}
// if character is in Private Use Area, don't do matching against pref or system fonts
if ((aCh >= 0xE000 && aCh <= 0xF8FF) || (aCh >= 0xF0000 && aCh <= 0x10FFFD))
@ -2502,7 +2642,7 @@ gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh,
// we'll synthesize appropriate-width spaces instead of missing-glyph boxes
if (GetGeneralCategory(aCh) ==
HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR &&
GetFontAt(0)->SynthesizeSpaceWidth(aCh) >= 0.0)
GetFirstValidFont()->SynthesizeSpaceWidth(aCh) >= 0.0)
{
return nullptr;
}
@ -2527,7 +2667,7 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
// initialize prevFont to the group's primary font, so that this will be
// used for string-initial control chars, etc rather than risk hitting font
// fallback for these (bug 716229)
gfxFont *prevFont = GetFontAt(0);
gfxFont *prevFont = GetFirstValidFont();
// if we use the initial value of prevFont, we treat this as a match from
// the font group; fixes bug 978313
@ -2630,7 +2770,7 @@ gfxFontGroup::SetUserFontSet(gfxUserFontSet *aUserFontSet)
}
mUserFontSet = aUserFontSet;
mCurrGeneration = GetGeneration() - 1;
UpdateFontList();
UpdateUserFonts();
}
uint64_t
@ -2641,19 +2781,60 @@ gfxFontGroup::GetGeneration()
return mUserFontSet->GetGeneration();
}
// note: gfxPangoFontGroup overrides UpdateFontList, such that
uint64_t
gfxFontGroup::GetRebuildGeneration()
{
if (!mUserFontSet)
return 0;
return mUserFontSet->GetRebuildGeneration();
}
// note: gfxPangoFontGroup overrides UpdateUserFonts, such that
// BuildFontList is never used
void
gfxFontGroup::UpdateFontList()
gfxFontGroup::UpdateUserFonts()
{
if (mCurrGeneration != GetGeneration()) {
// xxx - can probably improve this to detect when all fonts were found, so no need to update list
if (mCurrGeneration < GetRebuildGeneration()) {
// fonts in userfont set changed, need to redo the fontlist
mFonts.Clear();
mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET;
mSkipDrawing = false;
BuildFontList();
mCurrGeneration = GetGeneration();
mCachedEllipsisTextRun = nullptr;
} else if (mCurrGeneration != GetGeneration()) {
// load state change occurred, verify load state and validity of fonts
mSkipDrawing = false;
mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET;
mCachedEllipsisTextRun = nullptr;
uint32_t len = mFonts.Length();
for (uint32_t i = 0; i < len; i++) {
FamilyFace& ff = mFonts[i];
if (ff.Font() || !ff.IsUserFont()) {
continue;
}
// confirm status
gfxUserFontEntry *ufe =
static_cast<gfxUserFontEntry*>(mFonts[i].FontEntry());
gfxUserFontEntry::UserFontLoadState state = ufe->LoadState();
switch (state) {
case gfxUserFontEntry::STATUS_LOADING:
ff.SetLoading(true);
break;
case gfxUserFontEntry::STATUS_FAILED:
ff.SetInvalid();
// fall-thru to the default case
default:
ff.SetLoading(false);
}
if (ufe->WaitForUserFont()) {
mSkipDrawing = true;
}
}
mCurrGeneration = GetGeneration();
}
}

Просмотреть файл

@ -723,27 +723,6 @@ private:
class gfxFontGroup : public gfxTextRunFactory {
public:
class FamilyFace {
public:
FamilyFace() { }
FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont)
: mFamily(aFamily), mFont(aFont)
{
NS_ASSERTION(aFont, "font pointer must not be null");
NS_ASSERTION(!aFamily ||
aFamily->ContainsFace(aFont->GetFontEntry()),
"font is not a member of the given family");
}
gfxFontFamily* Family() const { return mFamily.get(); }
gfxFont* Font() const { return mFont.get(); }
private:
nsRefPtr<gfxFontFamily> mFamily;
nsRefPtr<gfxFont> mFont;
};
static void Shutdown(); // platform must call this to release the languageAtomService
gfxFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
@ -752,29 +731,15 @@ public:
virtual ~gfxFontGroup();
virtual gfxFont *GetFontAt(int32_t i) {
// If it turns out to be hard for all clients that cache font
// groups to call UpdateFontList at appropriate times, we could
// instead consider just calling UpdateFontList from someplace
// more central (such as here).
NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(),
"Whoever was caching this font group should have "
"called UpdateFontList on it");
NS_ASSERTION(mFonts.Length() > uint32_t(i) && mFonts[i].Font(),
"Requesting a font index that doesn't exist");
return mFonts[i].Font();
}
// Returns first valid font in the fontlist or default font.
// Initiates userfont loads if userfont not loaded
virtual gfxFont* GetFirstValidFont();
// Returns the first font in the font-group that has an OpenType MATH table,
// or null if no such font is available. The GetMathConstant methods may be
// called on the returned font.
gfxFont *GetFirstMathFont();
uint32_t FontListLength() const {
return mFonts.Length();
}
const gfxFontStyle *GetStyle() const { return &mStyle; }
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
@ -845,15 +810,12 @@ public:
// This returns the preferred underline for this font group.
// Some CJK fonts have wrong underline offset in its metrics.
// If this group has such "bad" font, each platform's gfxFontGroup initialized mUnderlineOffset.
// The value should be lower value of first font's metrics and the bad font's metrics.
// Otherwise, this returns from first font's metrics.
// If this group has such "bad" font, each platform's gfxFontGroup
// initialized mUnderlineOffset. The value should be lower value of
// first font's metrics and the bad font's metrics. Otherwise, this
// returns from first font's metrics.
enum { UNDERLINE_OFFSET_NOT_SET = INT16_MAX };
virtual gfxFloat GetUnderlineOffset() {
if (mUnderlineOffset == UNDERLINE_OFFSET_NOT_SET)
mUnderlineOffset = GetFontAt(0)->GetMetrics().underlineOffset;
return mUnderlineOffset;
}
virtual gfxFloat GetUnderlineOffset();
virtual already_AddRefed<gfxFont>
FindFontForChar(uint32_t ch, uint32_t prevCh, int32_t aRunScript,
@ -879,16 +841,19 @@ public:
// with no @font-face rule, this always returns 0.
uint64_t GetGeneration();
// generation of the latest fontset rebuild, 0 when no fontset present
uint64_t GetRebuildGeneration();
// used when logging text performance
gfxTextPerfMetrics *GetTextPerfMetrics() { return mTextPerf; }
void SetTextPerfMetrics(gfxTextPerfMetrics *aTextPerf) { mTextPerf = aTextPerf; }
// This will call UpdateFontList() if the user font set is changed.
// This will call UpdateUserFonts() if the user font set is changed.
void SetUserFontSet(gfxUserFontSet *aUserFontSet);
// If there is a user font set, check to see whether the font list or any
// caches need updating.
virtual void UpdateFontList();
virtual void UpdateUserFonts();
bool ShouldSkipDrawing() const {
return mSkipDrawing;
@ -901,7 +866,7 @@ public:
// The gfxFontGroup keeps ownership of this textrun.
// It is only guaranteed to exist until the next call to GetEllipsisTextRun
// (which might use a different appUnitsPerDev value) for the font group,
// or until UpdateFontList is called, or the fontgroup is destroyed.
// or until UpdateUserFonts is called, or the fontgroup is destroyed.
// Get it/use it/forget it :) - don't keep a reference that might go stale.
gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
LazyReferenceContextGetter& aRefContextGetter);
@ -913,9 +878,144 @@ public:
nsTArray<nsString>& aGenericFamilies);
protected:
class FamilyFace {
public:
FamilyFace() : mFamily(nullptr), mFontEntry(nullptr),
mNeedsBold(false), mFontCreated(false),
mLoading(false), mInvalid(false)
{ }
FamilyFace(gfxFontFamily* aFamily, gfxFont* aFont)
: mFamily(aFamily), mNeedsBold(false), mFontCreated(true),
mLoading(false), mInvalid(false)
{
NS_ASSERTION(aFont, "font pointer must not be null");
NS_ASSERTION(!aFamily ||
aFamily->ContainsFace(aFont->GetFontEntry()),
"font is not a member of the given family");
mFont = aFont;
NS_ADDREF(aFont);
}
FamilyFace(gfxFontFamily* aFamily, gfxFontEntry* aFontEntry,
bool aNeedsBold)
: mFamily(aFamily), mNeedsBold(aNeedsBold), mFontCreated(false),
mLoading(false), mInvalid(false)
{
NS_ASSERTION(aFontEntry, "font entry pointer must not be null");
NS_ASSERTION(!aFamily ||
aFamily->ContainsFace(aFontEntry),
"font is not a member of the given family");
mFontEntry = aFontEntry;
NS_ADDREF(aFontEntry);
}
FamilyFace(const FamilyFace& aOtherFamilyFace)
: mFamily(aOtherFamilyFace.mFamily),
mNeedsBold(aOtherFamilyFace.mNeedsBold),
mFontCreated(aOtherFamilyFace.mFontCreated),
mLoading(aOtherFamilyFace.mLoading),
mInvalid(aOtherFamilyFace.mInvalid)
{
if (mFontCreated) {
mFont = aOtherFamilyFace.mFont;
NS_ADDREF(mFont);
} else {
mFontEntry = aOtherFamilyFace.mFontEntry;
NS_IF_ADDREF(mFontEntry);
}
}
~FamilyFace()
{
if (mFontCreated) {
NS_RELEASE(mFont);
} else {
NS_IF_RELEASE(mFontEntry);
}
}
FamilyFace& operator=(const FamilyFace& aOther)
{
if (mFontCreated) {
NS_RELEASE(mFont);
} else {
NS_IF_RELEASE(mFontEntry);
}
mFamily = aOther.mFamily;
mNeedsBold = aOther.mNeedsBold;
mFontCreated = aOther.mFontCreated;
mLoading = aOther.mLoading;
mInvalid = aOther.mInvalid;
if (mFontCreated) {
mFont = aOther.mFont;
NS_ADDREF(mFont);
} else {
mFontEntry = aOther.mFontEntry;
NS_IF_ADDREF(mFontEntry);
}
return *this;
}
gfxFontFamily* Family() const { return mFamily.get(); }
gfxFont* Font() const {
return mFontCreated ? mFont : nullptr;
}
gfxFontEntry* FontEntry() const {
return mFontCreated ? mFont->GetFontEntry() : mFontEntry;
}
bool NeedsBold() const { return mNeedsBold; }
bool IsUserFont() const {
return FontEntry()->mIsUserFontContainer;
}
bool IsLoading() const { return mLoading; }
bool IsInvalid() const { return mInvalid; }
void SetLoading(bool aIsLoading) { mLoading = aIsLoading; }
void SetInvalid() { mInvalid = true; }
void SetFont(gfxFont* aFont)
{
NS_ASSERTION(aFont, "font pointer must not be null");
NS_ADDREF(aFont);
if (mFontCreated) {
NS_RELEASE(mFont);
} else {
NS_IF_RELEASE(mFontEntry);
}
mFont = aFont;
mFontCreated = true;
}
private:
nsRefPtr<gfxFontFamily> mFamily;
// either a font or a font entry exists
union {
gfxFont* mFont;
gfxFontEntry* mFontEntry;
};
bool mNeedsBold : 1;
bool mFontCreated : 1;
bool mLoading : 1;
bool mInvalid : 1;
};
// List of font families, either named or generic.
// Generic names map to system pref fonts based on language.
mozilla::FontFamilyList mFamilyList;
gfxFontStyle mStyle;
// Fontlist containing a font entry for each family found. gfxFont objects
// are created as needed and userfont loads are initiated when needed.
// Code should be careful about addressing this array directly.
nsTArray<FamilyFace> mFonts;
nsRefPtr<gfxFont> mDefaultFont;
gfxFontStyle mStyle;
gfxFloat mUnderlineOffset;
gfxFloat mHyphenWidth;
@ -951,6 +1051,14 @@ protected:
// Initialize the list of fonts
void BuildFontList();
// Get the font at index i within the fontlist.
// Will initiate userfont load if not already loaded.
// May return null if userfont not loaded or if font invalid
virtual gfxFont* GetFontAt(int32_t i);
// will always return a font or force a shutdown
gfxFont* GetDefaultFont();
// Init this font group's font metrics. If there no bad fonts, you don't need to call this.
// But if there are one or more bad fonts which have bad underline offset,
// you should call this with the *first* bad font.
@ -975,10 +1083,11 @@ protected:
int32_t aRunScript);
// Helper for font-matching:
// see if aCh is supported in any of the faces from aFamily;
// if so return the best style match, else return null.
already_AddRefed<gfxFont> TryAllFamilyMembers(gfxFontFamily* aFamily,
uint32_t aCh);
// When matching the italic case, allow use of the regular face
// if it supports a character but the italic one doesn't.
// Return null if regular face doesn't support aCh
already_AddRefed<gfxFont>
FindNonItalicFaceForChar(gfxFontFamily* aFamily, uint32_t aCh);
// helper methods for looking up fonts

Просмотреть файл

@ -120,7 +120,8 @@ gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet,
uint32_t aLanguageOverride,
gfxSparseBitSet* aUnicodeRanges)
: gfxFontEntry(NS_LITERAL_STRING("userfont")),
mLoadingState(NOT_LOADING),
mUserFontLoadState(STATUS_NOT_LOADED),
mFontDataLoadingState(NOT_LOADING),
mUnsupportedFormat(false),
mLoader(nullptr),
mFontSet(aFontSet)
@ -310,16 +311,21 @@ CopyWOFFMetadata(const uint8_t* aFontData,
*aMetaOrigLen = woff->metaOrigLen;
}
gfxUserFontEntry::LoadStatus
gfxUserFontEntry::LoadNext()
void
gfxUserFontEntry::LoadNextSrc()
{
uint32_t numSrc = mSrcList.Length();
NS_ASSERTION(mSrcIndex < numSrc,
"already at the end of the src list for user font");
NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED ||
mUserFontLoadState == STATUS_LOADING) &&
mFontDataLoadingState < LOADING_FAILED,
"attempting to load a font that has either completed or failed");
if (mLoadingState == NOT_LOADING) {
mLoadingState = LOADING_STARTED;
if (mUserFontLoadState == STATUS_NOT_LOADED) {
SetLoadState(STATUS_LOADING);
mFontDataLoadingState = LOADING_STARTED;
mUnsupportedFormat = false;
} else {
// we were already loading; move to the next source,
@ -356,7 +362,8 @@ gfxUserFontEntry::LoadNext()
// local fonts are just available all the time.
StoreUserFontData(fe, false, nsString(), nullptr, 0);
mPlatformFontEntry = fe;
return STATUS_LOADED;
SetLoadState(STATUS_LOADED);
return;
} else {
LOG(("fontset (%p) [src %d] failed local: (%s) for (%s)\n",
mFontSet, mSrcIndex,
@ -385,7 +392,8 @@ gfxUserFontEntry::LoadNext()
mFontSet->GetPrivateBrowsing());
if (fe) {
mPlatformFontEntry = fe;
return STATUS_LOADED;
SetLoadState(STATUS_LOADED);
return;
}
}
@ -408,8 +416,9 @@ gfxUserFontEntry::LoadNext()
bufferLength);
if (NS_SUCCEEDED(rv) &&
LoadFont(buffer, bufferLength)) {
return STATUS_LOADED;
LoadPlatformFont(buffer, bufferLength)) {
SetLoadState(STATUS_LOADED);
return;
} else {
mFontSet->LogMessage(this,
"font load failed",
@ -432,7 +441,7 @@ gfxUserFontEntry::LoadNext()
NS_ConvertUTF16toUTF8(mFamilyName).get()));
}
#endif
return STATUS_LOADING;
return;
} else {
mFontSet->LogMessage(this,
"download failed",
@ -462,14 +471,24 @@ gfxUserFontEntry::LoadNext()
// all src's failed; mark this entry as unusable (so fallback will occur)
LOG(("userfonts (%p) failed all src for (%s)\n",
mFontSet, NS_ConvertUTF16toUTF8(mFamilyName).get()));
mLoadingState = LOADING_FAILED;
mFontDataLoadingState = LOADING_FAILED;
SetLoadState(STATUS_FAILED);
}
return STATUS_END_OF_LIST;
void
gfxUserFontEntry::SetLoadState(UserFontLoadState aLoadState)
{
mUserFontLoadState = aLoadState;
}
bool
gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength)
gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
{
NS_ASSERTION((mUserFontLoadState == STATUS_NOT_LOADED ||
mUserFontLoadState == STATUS_LOADING) &&
mFontDataLoadingState < LOADING_FAILED,
"attempting to load a font that has either completed or failed");
gfxFontEntry* fe = nullptr;
gfxUserFontType fontType =
@ -541,6 +560,7 @@ gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength)
}
#endif
mPlatformFontEntry = fe;
SetLoadState(STATUS_LOADED);
gfxUserFontSet::UserFontCache::CacheFont(fe);
} else {
#ifdef PR_LOGGING
@ -562,11 +582,20 @@ gfxUserFontEntry::LoadFont(const uint8_t* aFontData, uint32_t &aLength)
return fe != nullptr;
}
void
gfxUserFontEntry::Load()
{
if (mUserFontLoadState == STATUS_NOT_LOADED) {
LoadNextSrc();
}
}
// This is called when a font download finishes.
// Ownership of aFontData passes in here, and the font set must
// ensure that it is eventually deleted via NS_Free().
bool
gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
gfxUserFontEntry::FontDataDownloadComplete(const uint8_t* aFontData,
uint32_t aLength,
nsresult aDownloadStatus)
{
// forget about the loader, as we no longer potentially need to cancel it
@ -575,7 +604,7 @@ gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
// download successful, make platform font using font data
if (NS_SUCCEEDED(aDownloadStatus)) {
bool loaded = LoadFont(aFontData, aLength);
bool loaded = LoadPlatformFont(aFontData, aLength);
aFontData = nullptr;
if (loaded) {
@ -595,7 +624,7 @@ gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
}
// error occurred, load next src
LoadNext();
LoadNextSrc();
// We ignore the status returned by LoadNext();
// even if loading failed, we need to bump the font-set generation
@ -608,7 +637,7 @@ gfxUserFontEntry::OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
gfxUserFontSet::gfxUserFontSet()
: mFontFamilies(4), mLocalRulesUsed(false)
{
IncrementGeneration();
IncrementGeneration(true);
gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList();
if (fp) {
fp->AddUserFontSet(this);
@ -744,64 +773,57 @@ gfxUserFontSet::AddFontFace(const nsAString& aFamilyName,
gfxUserFontEntry*
gfxUserFontSet::FindUserFontEntry(gfxFontFamily* aFamily,
const gfxFontStyle& aFontStyle,
bool& aNeedsBold,
bool& aWaitForUserFont)
bool& aNeedsBold)
{
aWaitForUserFont = false;
gfxUserFontFamily* family = static_cast<gfxUserFontFamily*>(aFamily);
gfxFontEntry* fe = family->FindFontForStyle(aFontStyle, aNeedsBold);
NS_ASSERTION(!fe || fe->mIsUserFontContainer,
"should only have userfont entries in userfont families");
// if not a userfont entry, font has already been loaded
if (!fe || !fe->mIsUserFontContainer) {
return nullptr;
}
gfxUserFontEntry* userFontEntry = static_cast<gfxUserFontEntry*> (fe);
return userFontEntry;
}
gfxUserFontEntry*
gfxUserFontSet::FindUserFontEntryAndLoad(gfxFontFamily* aFamily,
const gfxFontStyle& aFontStyle,
bool& aNeedsBold,
bool& aWaitForUserFont)
{
aWaitForUserFont = false;
gfxUserFontEntry* userFontEntry =
FindUserFontEntry(aFamily, aFontStyle, aNeedsBold);
if (!userFontEntry) {
return nullptr;
}
// start the load if it hasn't been loaded
userFontEntry->Load();
if (userFontEntry->GetPlatformFontEntry()) {
return userFontEntry;
}
// if currently loading, return null for now
if (userFontEntry->mLoadingState > gfxUserFontEntry::NOT_LOADING) {
aWaitForUserFont =
(userFontEntry->mLoadingState < gfxUserFontEntry::LOADING_SLOWLY);
return nullptr;
}
// hasn't been loaded yet, start the load process
gfxUserFontEntry::LoadStatus status;
// NOTE that if all sources in the entry fail, this will delete userFontEntry,
// so we cannot use it again if status==STATUS_END_OF_LIST
status = userFontEntry->LoadNext();
// if the load succeeded immediately, return
if (status == gfxUserFontEntry::STATUS_LOADED) {
return userFontEntry;
}
// check whether we should wait for load to complete before painting
// a fallback font -- but not if all sources failed (bug 633500)
aWaitForUserFont = (status != gfxUserFontEntry::STATUS_END_OF_LIST) &&
(userFontEntry->mLoadingState < gfxUserFontEntry::LOADING_SLOWLY);
// if either loading or an error occurred, return null
aWaitForUserFont = userFontEntry->WaitForUserFont();
return nullptr;
}
void
gfxUserFontSet::IncrementGeneration()
gfxUserFontSet::IncrementGeneration(bool aIsRebuild)
{
// add one, increment again if zero
++sFontSetGeneration;
if (sFontSetGeneration == 0)
++sFontSetGeneration;
mGeneration = sFontSetGeneration;
if (aIsRebuild) {
mRebuildGeneration = mGeneration;
}
}
void

Просмотреть файл

@ -189,9 +189,17 @@ public:
// the given name
gfxUserFontFamily* LookupFamily(const nsAString& aName) const;
// Lookup a userfont entry for a given style, loaded or not.
// aFamily must be a family returned by our LookupFamily method.
// If only invalid fonts in family, returns null.
gfxUserFontEntry* FindUserFontEntry(gfxFontFamily* aFamily,
const gfxFontStyle& aFontStyle,
bool& aNeedsBold);
// Lookup a font entry for a given style, returns null if not loaded.
// aFamily must be a family returned by our LookupFamily method.
gfxUserFontEntry* FindUserFontEntry(gfxFontFamily* aFamily,
// (only used by gfxPangoFontGroup for now)
gfxUserFontEntry* FindUserFontEntryAndLoad(gfxFontFamily* aFamily,
const gfxFontStyle& aFontStyle,
bool& aNeedsBold,
bool& aWaitForUserFont);
@ -204,7 +212,7 @@ public:
bool* aBypassCache) = 0;
// initialize the process that loads external font data, which upon
// completion will call OnLoadComplete method
// completion will call FontDataDownloadComplete method
virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
const gfxFontFaceSrc* aFontFaceSrc) = 0;
@ -213,7 +221,12 @@ public:
uint64_t GetGeneration() { return mGeneration; }
// increment the generation on font load
void IncrementGeneration();
void IncrementGeneration(bool aIsRebuild = false);
// Generation is bumped on font loads but that doesn't affect name-style
// mappings. Rebuilds do however affect name-style mappings so need to
// lookup fontlists again when that happens.
uint64_t GetRebuildGeneration() { return mRebuildGeneration; }
// rebuild if local rules have been used
void RebuildLocalRules();
@ -448,7 +461,8 @@ protected:
// font families defined by @font-face rules
nsRefPtrHashtable<nsStringHashKey, gfxUserFontFamily> mFontFamilies;
uint64_t mGeneration;
uint64_t mGeneration; // bumped on any font load change
uint64_t mRebuildGeneration; // only bumped on rebuilds
// true when local names have been looked up, false otherwise
bool mLocalRulesUsed;
@ -465,12 +479,11 @@ class gfxUserFontEntry : public gfxFontEntry {
friend class gfxOTSContext;
public:
enum LoadStatus {
STATUS_LOADING = 0,
enum UserFontLoadState {
STATUS_NOT_LOADED = 0,
STATUS_LOADING,
STATUS_LOADED,
STATUS_FORMAT_NOT_SUPPORTED,
STATUS_ERROR,
STATUS_END_OF_LIST
STATUS_FAILED
};
gfxUserFontEntry(gfxUserFontSet* aFontSet,
@ -493,18 +506,23 @@ public:
uint32_t aLanguageOverride,
gfxSparseBitSet* aUnicodeRanges);
virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold);
virtual gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle,
bool aNeedsBold);
gfxFontEntry* GetPlatformFontEntry() { return mPlatformFontEntry; }
// when download has been completed, pass back data here
// aDownloadStatus == NS_OK ==> download succeeded, error otherwise
// returns true if platform font creation sucessful (or local()
// reference was next in line)
// Ownership of aFontData is passed in here; the font set must
// ensure that it is eventually deleted with NS_Free().
bool OnLoadComplete(const uint8_t* aFontData, uint32_t aLength,
nsresult aDownloadStatus);
// is the font loading or loaded, or did it fail?
UserFontLoadState LoadState() const { return mUserFontLoadState; }
// whether to wait before using fallback font or not
bool WaitForUserFont() const {
return mUserFontLoadState == STATUS_LOADING &&
mFontDataLoadingState < LOADING_SLOWLY;
}
// load the font - starts the loading of sources which continues until
// a valid font resource is found or all sources fail
void Load();
protected:
const uint8_t* SanitizeOpenTypeData(const uint8_t* aData,
@ -512,14 +530,26 @@ protected:
uint32_t& aSaneLength,
bool aIsCompressed);
// Attempt to load the next resource in the src list.
LoadStatus LoadNext();
// attempt to load the next resource in the src list.
void LoadNextSrc();
// change the load state
void SetLoadState(UserFontLoadState aLoadState);
// when download has been completed, pass back data here
// aDownloadStatus == NS_OK ==> download succeeded, error otherwise
// returns true if platform font creation sucessful (or local()
// reference was next in line)
// Ownership of aFontData is passed in here; the font set must
// ensure that it is eventually deleted with NS_Free().
bool FontDataDownloadComplete(const uint8_t* aFontData, uint32_t aLength,
nsresult aDownloadStatus);
// helper method for creating a platform font
// returns true if platform font creation successful
// Ownership of aFontData is passed in here; the font must
// ensure that it is eventually deleted with NS_Free().
bool LoadFont(const uint8_t* aFontData, uint32_t &aLength);
bool LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength);
// store metadata and src details for current src into aFontEntry
void StoreUserFontData(gfxFontEntry* aFontEntry,
@ -528,8 +558,13 @@ protected:
FallibleTArray<uint8_t>* aMetadata,
uint32_t aMetaOrigLen);
// general load state
UserFontLoadState mUserFontLoadState;
// detailed load state while font data is loading
// used to determine whether to use fallback font or not
// note that code depends on the ordering of these values!
enum LoadingState {
enum FontDataLoadingState {
NOT_LOADING = 0, // not started to load any font resources yet
LOADING_STARTED, // loading has started; hide fallback font
LOADING_ALMOST_DONE, // timeout happened but we're nearly done,
@ -538,7 +573,8 @@ protected:
// so use the fallback font
LOADING_FAILED // failed to load any source: use fallback
};
LoadingState mLoadingState;
FontDataLoadingState mFontDataLoadingState;
bool mUnsupportedFormat;
nsRefPtr<gfxFontEntry> mPlatformFontEntry;

Просмотреть файл

@ -283,17 +283,6 @@ gfxWindowsSurface::EndPage()
#endif
}
int32_t
gfxWindowsSurface::GetDefaultContextFlags() const
{
if (mForPrinting)
return gfxContext::FLAG_SIMPLIFY_OPERATORS |
gfxContext::FLAG_DISABLE_SNAPPING |
gfxContext::FLAG_DISABLE_COPY_BACKGROUND;
return 0;
}
const gfxIntSize
gfxWindowsSurface::GetSize() const
{

Просмотреть файл

@ -63,8 +63,6 @@ public:
nsresult BeginPage();
nsresult EndPage();
virtual int32_t GetDefaultContextFlags() const;
const gfxIntSize GetSize() const;
// The memory used by this surface lives in this process's address space,

Просмотреть файл

@ -612,8 +612,10 @@ RasterImage::GetFrame(uint32_t aFrameNum)
if (!ref) {
// The OS threw this frame away. We need to discard and redecode.
MOZ_ASSERT(!mAnim, "Animated frames should be locked");
if (CanForciblyDiscardAndRedecode()) {
ForceDiscard();
WantDecodedFrames();
}
return DrawableFrameRef();
}

Просмотреть файл

@ -1708,7 +1708,7 @@ ObjectAddress(JSContext *cx, unsigned argc, jsval *vp)
}
#ifdef JS_MORE_DETERMINISTIC
args.rval().setInt(0);
args.rval().setInt32(0);
#else
char buffer[64];
JS_snprintf(buffer, sizeof(buffer), "%p", &args[0].toObject());

Просмотреть файл

@ -1639,9 +1639,9 @@ GetCompartmentName(JSCompartment *c, nsCString &name, int *anonymizeID,
}
}
// We might have a file:// URL that includes paths from the local
// filesystem, which should be omitted if we're anonymizing.
if (*anonymizeID) {
// We might have a file:// URL that includes a path from the local
// filesystem, which should be omitted if we're anonymizing.
static const char *filePrefix = "file://";
int filePos = name.Find(filePrefix);
if (filePos >= 0) {
@ -1662,6 +1662,24 @@ GetCompartmentName(JSCompartment *c, nsCString &name, int *anonymizeID,
name += "<anonymized?!>";
}
}
// We might have a location like this:
// inProcessTabChildGlobal?ownedBy=http://www.example.com/
// The owner should be omitted if it's not a chrome: URI and we're
// anonymizing.
static const char *ownedByPrefix =
"inProcessTabChildGlobal?ownedBy=";
int ownedByPos = name.Find(ownedByPrefix);
if (ownedByPos >= 0) {
const char *chrome = "chrome:";
int ownerPos = ownedByPos + strlen(ownedByPrefix);
const nsDependentCSubstring& ownerFirstPart =
Substring(name, ownerPos, strlen(chrome));
if (!ownerFirstPart.EqualsASCII(chrome)) {
name.Truncate(ownerPos);
name += "<anonymized>";
}
}
}
// A hack: replace forward slashes with '\\' so they aren't

Просмотреть файл

@ -1701,10 +1701,15 @@ XrayToString(JSContext *cx, unsigned argc, Value *vp)
}
RootedObject obj(cx, XrayTraits::getTargetObject(wrapper));
if (UseDOMXray(obj))
XrayType type = GetXrayType(obj);
if (type == XrayForDOMObject)
return NativeToString(cx, wrapper, obj, args.rval());
if (type != XrayForWrappedNative) {
JS_ReportError(cx, "XrayToString called on an incompatible object");
return false;
}
static const char start[] = "[object XrayWrapper ";
static const char end[] = "]";
nsAutoString result;
@ -2304,12 +2309,13 @@ template class SCSecurityXrayXPCWN;
static nsQueryInterface
do_QueryInterfaceNative(JSContext* cx, HandleObject wrapper)
{
nsISupports* nativeSupports;
nsISupports* nativeSupports = nullptr;
if (IsWrapper(wrapper) && WrapperFactory::IsXrayWrapper(wrapper)) {
RootedObject target(cx, XrayTraits::getTargetObject(wrapper));
if (GetXrayType(target) == XrayForDOMObject) {
XrayType type = GetXrayType(target);
if (type == XrayForDOMObject) {
nativeSupports = UnwrapDOMObjectToISupports(target);
} else {
} else if (type == XrayForWrappedNative) {
XPCWrappedNative *wn = XPCWrappedNative::Get(target);
nativeSupports = wn->Native();
}

Просмотреть файл

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Macros used to log restyle events.
*/
#ifndef mozilla_RestyleLogging_h
#define mozilla_RestyleLogging_h
#include "mozilla/AutoRestore.h"
#ifdef DEBUG
#define RESTYLE_LOGGING
#endif
#ifdef RESTYLE_LOGGING
#define LOG_RESTYLE_IF(object_, cond_, message_, ...) \
PR_BEGIN_MACRO \
if (object_->ShouldLogRestyle() && (cond_)) { \
nsCString line; \
for (int32_t restyle_depth_##__LINE__ = 0; \
restyle_depth_##__LINE__ < object_->LoggingDepth(); \
restyle_depth_##__LINE__++) { \
line.AppendLiteral(" "); \
} \
line.AppendPrintf(message_, ##__VA_ARGS__); \
printf_stderr("%s\n", line.get()); \
} \
PR_END_MACRO
#define LOG_RESTYLE(message_, ...) \
LOG_RESTYLE_IF(this, true, message_, ##__VA_ARGS__)
// Beware that LOG_RESTYLE_INDENT is two statements not wrapped in a block.
#define LOG_RESTYLE_INDENT() \
AutoRestore<int32_t> ar_depth_##__LINE__(LoggingDepth()); \
++LoggingDepth();
#else
#define LOG_RESTYLE_IF(cond_, message_, ...) /* nothing */
#define LOG_RESTYLE(message_, ...) /* nothing */
#define LOG_RESTYLE_INDENT() /* nothing */
#endif
#endif /* mozilla_RestyleLogging_h */

Просмотреть файл

@ -36,6 +36,7 @@
#include "nsIFrameInlines.h"
#include "ActiveLayerTracker.h"
#include "nsDisplayList.h"
#include "RestyleTrackerInlines.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -45,6 +46,19 @@ namespace mozilla {
using namespace layers;
#define LOG_RESTYLE_CONTINUE(reason_, ...) \
LOG_RESTYLE("continuing restyle since " reason_, ##__VA_ARGS__)
#ifdef RESTYLE_LOGGING
static nsCString
FrameTagToString(const nsIFrame* aFrame)
{
nsCString result;
aFrame->ListTag(result);
return result;
}
#endif
RestyleManager::RestyleManager(nsPresContext* aPresContext)
: mPresContext(aPresContext)
, mRebuildAllStyleData(false)
@ -60,6 +74,9 @@ RestyleManager::RestyleManager(nsPresContext* aPresContext)
ELEMENT_IS_POTENTIAL_RESTYLE_ROOT)
, mPendingAnimationRestyles(ELEMENT_HAS_PENDING_ANIMATION_RESTYLE |
ELEMENT_IS_POTENTIAL_ANIMATION_RESTYLE_ROOT)
#ifdef RESTYLE_LOGGING
, mLoggingDepth(0)
#endif
{
mPendingRestyles.Init(this);
mPendingAnimationRestyles.Init(this);
@ -2257,6 +2274,9 @@ ElementRestyler::ElementRestyler(nsPresContext* aPresContext,
, mOurA11yNotification(eDontNotify)
, mVisibleKidsOfHiddenElement(aVisibleKidsOfHiddenElement)
#endif
#ifdef RESTYLE_LOGGING
, mLoggingDepth(aRestyleTracker.LoggingDepth() + 1)
#endif
{
}
@ -2284,6 +2304,9 @@ ElementRestyler::ElementRestyler(const ElementRestyler& aParentRestyler,
, mOurA11yNotification(eDontNotify)
, mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
#endif
#ifdef RESTYLE_LOGGING
, mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
#endif
{
if (aConstructorFlags & FOR_OUT_OF_FLOW_CHILD) {
// Note that the out-of-flow may not be a geometric descendant of
@ -2325,6 +2348,9 @@ ElementRestyler::ElementRestyler(ParentContextFromChildFrame,
, mOurA11yNotification(eDontNotify)
, mVisibleKidsOfHiddenElement(aParentRestyler.mVisibleKidsOfHiddenElement)
#endif
#ifdef RESTYLE_LOGGING
, mLoggingDepth(aParentRestyler.mLoggingDepth + 1)
#endif
{
}
@ -2351,6 +2377,11 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
(ourChange & nsChangeHint_NeedReflow),
"Reflow hint bits set without actually asking for a reflow");
LOG_RESTYLE("CaptureChange, ourChange = %s, aChangeToAssume = %s",
RestyleManager::ChangeHintToString(ourChange).get(),
RestyleManager::ChangeHintToString(aChangeToAssume).get());
LOG_RESTYLE_INDENT();
// nsChangeHint_UpdateEffects is inherited, but it can be set due to changes
// in inherited properties (fill and stroke). Avoid propagating it into
// text nodes.
@ -2362,11 +2393,17 @@ ElementRestyler::CaptureChange(nsStyleContext* aOldContext,
NS_UpdateHint(ourChange, aChangeToAssume);
if (NS_UpdateHint(mHintsHandled, ourChange)) {
if (!(ourChange & nsChangeHint_ReconstructFrame) || mContent) {
LOG_RESTYLE("appending change %s",
RestyleManager::ChangeHintToString(ourChange).get());
mChangeList->AppendChange(mFrame, mContent, ourChange);
} else {
LOG_RESTYLE("change has already been handled");
}
}
NS_UpdateHint(mHintsNotHandledForDescendants,
NS_HintsNotHandledForDescendantsIn(ourChange));
LOG_RESTYLE("mHintsNotHandledForDescendants = %s",
RestyleManager::ChangeHintToString(mHintsNotHandledForDescendants).get());
}
/**
@ -2449,14 +2486,12 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
// overall decision.
RestyleResult result = RestyleResult(0);
uint32_t swappedStructs = 0;
nsIFrame* providerFrame = nullptr;
nsRestyleHint thisRestyleHint = aRestyleHint;
bool haveMoreContinuations = false;
for (nsIFrame* f = mFrame; f; ) {
RestyleResult thisResult =
RestyleSelf(f, thisRestyleHint, &swappedStructs, &providerFrame);
RestyleResult thisResult = RestyleSelf(f, thisRestyleHint, &swappedStructs);
if (thisResult != eRestyleResult_Stop) {
// Calls to RestyleSelf for later same-style continuations must not
@ -2495,15 +2530,15 @@ ElementRestyler::Restyle(nsRestyleHint aRestyleHint)
MOZ_ASSERT(mFrame->StyleContext() == oldContext,
"frame should have been left with its old style context");
MOZ_ASSERT(providerFrame, "RestyleSelf should have supplied a providerFrame "
"if it returned eRestyleResult_Stop");
nsStyleContext* newParent = providerFrame->StyleContext();
nsStyleContext* newParent =
mFrame->GetParentStyleContextFrame()->StyleContext();
if (oldContext->GetParent() != newParent) {
// If we received eRestyleResult_Stop, then the old style context was
// left on mFrame. Since we ended up restyling our parent, change
// this old style context to point to its new parent.
LOG_RESTYLE("moving style context %p from old parent %p to new parent %p",
oldContext.get(), oldContext->GetParent(), newParent);
oldContext->MoveTo(newParent);
}
@ -2568,6 +2603,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf)
// have, so we don't considering stopping if this frame has any additional
// style contexts.
if (aSelf->GetAdditionalStyleContext(0)) {
LOG_RESTYLE_CONTINUE("there are additional style contexts");
return eRestyleResult_Continue;
}
@ -2577,7 +2613,14 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf)
// that they get the correct style context parent. Similarly for
// nsLineFrames.
nsIAtom* type = aSelf->GetType();
if (type == nsGkAtoms::letterFrame || type == nsGkAtoms::lineFrame) {
if (type == nsGkAtoms::letterFrame) {
LOG_RESTYLE_CONTINUE("frame is a letter frame");
return eRestyleResult_Continue;
}
if (type == nsGkAtoms::lineFrame) {
LOG_RESTYLE_CONTINUE("frame is a line frame");
return eRestyleResult_Continue;
}
@ -2590,16 +2633,19 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf)
// and we need to recompute the child's 'inherit' to that new value.
nsStyleContext* oldContext = aSelf->StyleContext();
if (oldContext->HasChildThatUsesGrandancestorStyle()) {
LOG_RESTYLE_CONTINUE("the old context uses grandancestor style");
return eRestyleResult_Continue;
}
// We ignore all situations that involve :visited style.
if (oldContext->GetStyleIfVisited()) {
LOG_RESTYLE_CONTINUE("the old style context has StyleIfVisited");
return eRestyleResult_Continue;
}
nsStyleContext* parentContext = oldContext->GetParent();
if (parentContext && parentContext->GetStyleIfVisited()) {
LOG_RESTYLE_CONTINUE("the old style context's parent has StyleIfVisited");
return eRestyleResult_Continue;
}
@ -2610,6 +2656,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf)
// pseudos.
nsIAtom* pseudoTag = oldContext->GetPseudo();
if (pseudoTag && pseudoTag != nsCSSAnonBoxes::mozNonElement) {
LOG_RESTYLE_CONTINUE("the old style context is for a pseudo");
return eRestyleResult_Continue;
}
@ -2621,6 +2668,7 @@ ElementRestyler::ComputeRestyleResultFromFrame(nsIFrame* aSelf)
// ancestor).
nsIAtom* parentPseudoTag = parent->StyleContext()->GetPseudo();
if (parentPseudoTag && parentPseudoTag != nsCSSAnonBoxes::mozNonElement) {
LOG_RESTYLE_CONTINUE("the old style context's parent is for a pseudo");
return eRestyleResult_Continue;
}
}
@ -2636,6 +2684,7 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
// that we can avoid the style context tree surgery having to deal to deal
// with visited styles.
if (aNewContext->GetStyleIfVisited()) {
LOG_RESTYLE_CONTINUE("the new style context has StyleIfVisited");
return eRestyleResult_Continue;
}
@ -2648,6 +2697,8 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
oldContext->GetPseudo() != aNewContext->GetPseudo() ||
oldContext->GetPseudoType() != aNewContext->GetPseudoType() ||
oldContext->RuleNode() != aNewContext->RuleNode()) {
LOG_RESTYLE_CONTINUE("the old and new style contexts have different link/"
"visited/pseudo/rulenodes");
return eRestyleResult_Continue;
}
@ -2656,9 +2707,16 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
// bits, then we must keep restyling so that those new bit values are
// propagated.
if (oldContext->HasTextDecorationLines() !=
aNewContext->HasTextDecorationLines() ||
oldContext->HasPseudoElementData() !=
aNewContext->HasTextDecorationLines()) {
LOG_RESTYLE_CONTINUE("NS_STYLE_HAS_TEXT_DECORATION_LINES differs between old"
" and new style contexts");
return eRestyleResult_Continue;
}
if (oldContext->HasPseudoElementData() !=
aNewContext->HasPseudoElementData()) {
LOG_RESTYLE_CONTINUE("NS_STYLE_HAS_PSEUDO_ELEMENT_DATA differs between old"
" and new style contexts");
return eRestyleResult_Continue;
}
@ -2668,8 +2726,7 @@ ElementRestyler::ComputeRestyleResultFromNewContext(nsIFrame* aSelf,
ElementRestyler::RestyleResult
ElementRestyler::RestyleSelf(nsIFrame* aSelf,
nsRestyleHint aRestyleHint,
uint32_t* aSwappedStructs,
nsIFrame** aProviderFrame)
uint32_t* aSwappedStructs)
{
MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
"eRestyle_LaterSiblings must not be part of aRestyleHint");
@ -2682,6 +2739,11 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
// We do need a reference to oldContext for the lifetime of this function, and it's possible
// that the frame has the last reference to it, so AddRef it here.
LOG_RESTYLE("RestyleSelf %s, aRestyleHint = %s",
FrameTagToString(aSelf).get(),
RestyleManager::RestyleHintToString(aRestyleHint).get());
LOG_RESTYLE_INDENT();
RestyleResult result;
if (aRestyleHint & eRestyle_ForceDescendants) {
@ -2707,7 +2769,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
nsStyleContext* parentContext;
// Get the frame providing the parent style context. If it is a
// child, then resolve the provider first.
nsIFrame* const providerFrame = aSelf->GetParentStyleContextFrame();
nsIFrame* providerFrame = aSelf->GetParentStyleContextFrame();
bool isChild = providerFrame && providerFrame->GetParent() == aSelf;
if (!isChild) {
if (providerFrame)
@ -2722,6 +2784,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
"ancestor filter.");
// resolve the provider here (before aSelf below).
LOG_RESTYLE("resolving child provider frame");
// assumeDifferenceHint forces the parent's change to be also
// applied to this frame, no matter what
@ -2741,6 +2804,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
// Set |mResolvedChild| so we don't bother resolving the
// provider again.
mResolvedChild = providerFrame;
LOG_RESTYLE_CONTINUE("we had a provider frame");
// Continue restyling past the odd style context inheritance.
result = eRestyleResult_Continue;
}
@ -2752,13 +2816,6 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
nsChangeHint_Hints_NotHandledForDescendants;
}
if (*aProviderFrame && *aProviderFrame != providerFrame) {
// XXX Uncomment when bug 979133 (restyle logging) lands.
// LOG_RESTYLE_CONTINUE("we had different provider frame from the previous "
// "same-style continuation");
result = eRestyleResult_Continue;
}
// We don't support using eRestyle_StyleAttribute when pseudo-elements
// are involved. This is mostly irrelevant since style attribute
// changes on pseudo-elements are very rare, though it does mean we
@ -2768,6 +2825,8 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
aRestyleHint = (aRestyleHint & ~eRestyle_StyleAttribute) | eRestyle_Self;
}
LOG_RESTYLE("parentContext = %p", parentContext);
// do primary context
nsRefPtr<nsStyleContext> newContext;
nsIFrame *prevContinuation =
@ -2781,6 +2840,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
if (copyFromContinuation) {
// Just use the style context from the frame's previous
// continuation.
LOG_RESTYLE("using previous continuation's context");
newContext = prevContinuationContext;
}
else if (pseudoTag == nsCSSAnonBoxes::mozNonElement) {
@ -2796,6 +2856,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
Element* pseudoElement =
(pseudoElementContent && pseudoElementContent->IsElement())
? pseudoElementContent->AsElement() : nullptr;
LOG_RESTYLE("reparenting style context");
newContext =
styleSet->ReparentStyleContext(oldContext, parentContext, element,
pseudoElement);
@ -2805,6 +2866,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
// ReparentStyleContext that rebuilds the path in the rule tree
// rather than reusing the rule node, as we need to do during a
// rule tree reconstruct.
LOG_RESTYLE("resolving style with replacement");
newContext =
styleSet->ResolveStyleWithReplacement(element, parentContext, oldContext,
aRestyleHint);
@ -2882,12 +2944,20 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
// we can use FindChildWithRules to keep a lot of the old
// style contexts around. However, we need to start from the
// same root.
LOG_RESTYLE("restyling root and keeping old context");
LOG_RESTYLE_IF(this, result != eRestyleResult_Continue,
"continuing restyle since this is the root");
newContext = oldContext;
// Never consider stopping restyling at the root.
result = eRestyleResult_Continue;
}
}
LOG_RESTYLE("oldContext = %p, newContext = %p%s",
oldContext.get(), newContext.get(),
oldContext == newContext ? (const char*) " (same)" :
(const char*) "");
if (newContext != oldContext) {
if (result == eRestyleResult_Stop) {
if (oldContext->IsShared()) {
@ -2895,6 +2965,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
// eRestyleResult_Stop and patch its parent to point to the
// new parent style context, as that change might not be valid
// for the other frames sharing the style context.
LOG_RESTYLE_CONTINUE("the old style context is shared");
result = eRestyleResult_Continue;
} else {
// Look at some details of the new style context to see if it would
@ -2918,6 +2989,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
if (equalStructs != NS_STYLE_INHERIT_MASK) {
// At least one struct had different data in it, so we must
// continue restyling children.
LOG_RESTYLE_CONTINUE("there is different style data: %s",
RestyleManager::StructNamesToString(
~equalStructs & NS_STYLE_INHERIT_MASK).get());
result = eRestyleResult_Continue;
}
}
@ -2930,6 +3004,9 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
if (equalStructs != NS_STYLE_INHERIT_MASK) {
// At least one struct had different data in it, so we must
// continue restyling children.
LOG_RESTYLE_CONTINUE("there is different style data: %s",
RestyleManager::StructNamesToString(
~equalStructs & NS_STYLE_INHERIT_MASK).get());
result = eRestyleResult_Continue;
}
}
@ -2958,6 +3035,7 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
sid = nsStyleStructID(sid + 1)) {
if (oldContext->HasCachedInheritedStyleData(sid) &&
!oldContext->HasSameCachedStyleData(newContext, sid)) {
LOG_RESTYLE_CONTINUE("there are different struct pointers");
result = eRestyleResult_Continue;
break;
}
@ -2974,12 +3052,29 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
// previous continuation, so newContext == oldContext.
if (result != eRestyleResult_Stop) {
if (!oldContext->IsShared() && !newContext->IsShared()) {
if (copyFromContinuation) {
LOG_RESTYLE("not swapping style structs, since we copied from a "
"continuation");
} else if (oldContext->IsShared() && newContext->IsShared()) {
LOG_RESTYLE("not swapping style structs, since both old and contexts "
"are shared");
} else if (oldContext->IsShared()) {
LOG_RESTYLE("not swapping style structs, since the old context is "
"shared");
} else if (newContext->IsShared()) {
LOG_RESTYLE("not swapping style structs, since the new context is "
"shared");
} else {
LOG_RESTYLE("swapping style structs between %p and %p",
oldContext.get(), newContext.get());
oldContext->SwapStyleData(newContext, equalStructs);
*aSwappedStructs |= equalStructs;
}
LOG_RESTYLE("setting new style context");
aSelf->SetStyleContext(newContext);
}
} else {
LOG_RESTYLE("not setting new style context, since we'll reframe");
}
}
oldContext = nullptr;
@ -2991,6 +3086,8 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
for (nsStyleContext* oldExtraContext;
(oldExtraContext = aSelf->GetAdditionalStyleContext(contextIndex));
++contextIndex) {
LOG_RESTYLE("extra context %d", contextIndex);
LOG_RESTYLE_INDENT();
nsRefPtr<nsStyleContext> newExtraContext;
nsIAtom* const extraPseudoTag = oldExtraContext->GetPseudo();
const nsCSSPseudoElements::Type extraPseudoType =
@ -3036,19 +3133,22 @@ ElementRestyler::RestyleSelf(nsIFrame* aSelf,
MOZ_ASSERT(newExtraContext);
LOG_RESTYLE("newExtraContext = %p", newExtraContext.get());
if (oldExtraContext != newExtraContext) {
uint32_t equalStructs;
CaptureChange(oldExtraContext, newExtraContext, assumeDifferenceHint,
&equalStructs);
if (!(mHintsHandled & nsChangeHint_ReconstructFrame)) {
LOG_RESTYLE("setting new extra style context");
aSelf->SetAdditionalStyleContext(contextIndex, newExtraContext);
} else {
LOG_RESTYLE("not setting new extra style context, since we'll reframe");
}
}
}
if (result == eRestyleResult_Stop) {
*aProviderFrame = providerFrame;
}
LOG_RESTYLE("returning %s", RestyleResultToString(result).get());
return result;
}
@ -3153,6 +3253,9 @@ ElementRestyler::RestyleUndisplayedChildren(nsRestyleHint aChildRestyleHint)
"Shouldn't have random pseudo style contexts in the "
"undisplayed map");
LOG_RESTYLE("RestyleUndisplayedChildren: undisplayed->mContent = %p",
undisplayed->mContent.get());
// Get the parent of the undisplayed content and check if it is a XBL
// children element. Push the children element as an ancestor here because it does
// not have a frame and would not otherwise be pushed as an ancestor.
@ -3234,6 +3337,8 @@ ElementRestyler::MaybeReframeForBeforePseudo()
nsCSSPseudoElements::ePseudo_before,
mPresContext)) {
// Have to create the new :before frame
LOG_RESTYLE("MaybeReframeForBeforePseudo, appending "
"nsChangeHint_ReconstructFrame");
NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
mChangeList->AppendChange(mFrame, mContent,
nsChangeHint_ReconstructFrame);
@ -3270,6 +3375,8 @@ ElementRestyler::MaybeReframeForAfterPseudo(nsIFrame* aFrame)
mPresContext) &&
!nsLayoutUtils::GetAfterFrame(aFrame)) {
// have to create the new :after frame
LOG_RESTYLE("MaybeReframeForAfterPseudo, appending "
"nsChangeHint_ReconstructFrame");
NS_UpdateHint(mHintsHandled, nsChangeHint_ReconstructFrame);
mChangeList->AppendChange(aFrame, mContent,
nsChangeHint_ReconstructFrame);
@ -3322,6 +3429,8 @@ void
ElementRestyler::RestyleContentChildren(nsIFrame* aParent,
nsRestyleHint aChildRestyleHint)
{
LOG_RESTYLE("RestyleContentChildren");
nsIFrame::ChildListIterator lists(aParent);
TreeMatchContext::AutoAncestorPusher ancestorPusher(mTreeMatchContext);
if (!lists.IsDone()) {
@ -3527,4 +3636,138 @@ RestyleManager::ComputeStyleChangeFor(nsIFrame* aFrame,
}
}
#ifdef DEBUG
/* static */ nsCString
RestyleManager::RestyleHintToString(nsRestyleHint aHint)
{
nsCString result;
bool any = false;
const char* names[] = { "Self", "Subtree", "LaterSiblings", "CSSTransitions",
"CSSAnimations", "SVGAttrAnimations", "StyleAttribute",
"ChangeAnimationPhase", "Force", "ForceDescendants" };
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);
for (uint32_t i = 0; i < ArrayLength(names); i++) {
if (hint & (1 << i)) {
if (any) {
result.AppendLiteral(" | ");
}
result.AppendPrintf("eRestyle_%s", names[i]);
any = true;
}
}
if (rest) {
if (any) {
result.AppendLiteral(" | ");
}
result.AppendPrintf("0x%0x", rest);
} else {
if (!any) {
result.AppendLiteral("0");
}
}
return result;
}
/* static */ nsCString
RestyleManager::ChangeHintToString(nsChangeHint aHint)
{
nsCString result;
bool any = false;
const char* names[] = {
"RepaintFrame", "NeedReflow", "ClearAncestorIntrinsics",
"ClearDescendantIntrinsics", "NeedDirtyReflow", "SyncFrameView",
"UpdateCursor", "UpdateEffects", "UpdateOpacityLayer",
"UpdateTransformLayer", "ReconstructFrame", "UpdateOverflow",
"UpdateSubtreeOverflow", "UpdatePostTransformOverflow",
"ChildrenOnlyTransform", "RecomputePosition", "AddOrRemoveTransform",
"BorderStyleNoneChange", "UpdateTextPath", "NeutralChange"
};
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);
if (hint == nsChangeHint_Hints_NotHandledForDescendants) {
result.AppendLiteral("nsChangeHint_Hints_NotHandledForDescendants");
hint = 0;
any = true;
} else {
if ((hint & NS_STYLE_HINT_FRAMECHANGE) == NS_STYLE_HINT_FRAMECHANGE) {
result.AppendLiteral("NS_STYLE_HINT_FRAMECHANGE");
hint = hint & ~NS_STYLE_HINT_FRAMECHANGE;
any = true;
} else if ((hint & NS_STYLE_HINT_REFLOW) == NS_STYLE_HINT_REFLOW) {
result.AppendLiteral("NS_STYLE_HINT_REFLOW");
hint = hint & ~NS_STYLE_HINT_REFLOW;
any = true;
} else if ((hint & nsChangeHint_AllReflowHints) == nsChangeHint_AllReflowHints) {
result.AppendLiteral("nsChangeHint_AllReflowHints");
hint = hint & ~nsChangeHint_AllReflowHints;
any = true;
} else if ((hint & NS_STYLE_HINT_VISUAL) == NS_STYLE_HINT_VISUAL) {
result.AppendLiteral("NS_STYLE_HINT_VISUAL");
hint = hint & ~NS_STYLE_HINT_VISUAL;
any = true;
}
}
for (uint32_t i = 0; i < ArrayLength(names); i++) {
if (hint & (1 << i)) {
if (any) {
result.AppendLiteral(" | ");
}
result.AppendPrintf("nsChangeHint_%s", names[i]);
any = true;
}
}
if (rest) {
if (any) {
result.AppendLiteral(" | ");
}
result.AppendPrintf("0x%0x", rest);
} else {
if (!any) {
result.AppendLiteral("NS_STYLE_HINT_NONE");
}
}
return result;
}
/* static */ nsCString
RestyleManager::StructNamesToString(uint32_t aSIDs)
{
nsCString result;
bool any = false;
for (nsStyleStructID sid = nsStyleStructID(0);
sid < nsStyleStructID_Length;
sid = nsStyleStructID(sid + 1)) {
if (aSIDs & nsCachedStyleData::GetBitForSID(sid)) {
if (any) {
result.AppendLiteral(",");
}
result.AppendPrintf("%s", nsStyleContext::StructName(sid));
any = true;
}
}
return result;
}
/* static */ nsCString
ElementRestyler::RestyleResultToString(RestyleResult aRestyleResult)
{
nsCString result;
switch (aRestyleResult) {
case eRestyleResult_Stop:
result.AssignLiteral("eRestyleResult_Stop");
break;
case eRestyleResult_Continue:
result.AssignLiteral("eRestyleResult_Continue");
break;
case eRestyleResult_ContinueAndForceDescendants:
result.AssignLiteral("eRestyleResult_ContinueAndForceDescendants");
break;
default:
result.AppendPrintf("RestyleResult(%d)", aRestyleResult);
}
return result;
}
#endif
} // namespace mozilla

Просмотреть файл

@ -11,6 +11,7 @@
#ifndef mozilla_RestyleManager_h
#define mozilla_RestyleManager_h
#include "mozilla/RestyleLogging.h"
#include "nsISupportsImpl.h"
#include "nsChangeHint.h"
#include "RestyleTracker.h"
@ -316,6 +317,11 @@ public:
mOverflowChangedTracker.Flush();
}
#ifdef DEBUG
static nsCString RestyleHintToString(nsRestyleHint aHint);
static nsCString ChangeHintToString(nsChangeHint aHint);
#endif
private:
/**
* Notify the frame constructor that an element needs to have its
@ -351,6 +357,39 @@ public:
*/
void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint);
#ifdef RESTYLE_LOGGING
/**
* Returns whether a restyle event currently being processed by this
* RestyleManager should be logged.
*/
bool ShouldLogRestyle() {
return ShouldLogRestyle(mPresContext);
}
/**
* Returns whether a restyle event currently being processed for the
* document with the specified nsPresContext should be logged.
*/
static bool ShouldLogRestyle(nsPresContext* aPresContext) {
return aPresContext->RestyleLoggingEnabled() &&
(!aPresContext->IsProcessingAnimationStyleChange() ||
AnimationRestyleLoggingEnabled());
}
static bool RestyleLoggingInitiallyEnabled() {
static bool enabled = getenv("MOZ_DEBUG_RESTYLE") != 0;
return enabled;
}
static bool AnimationRestyleLoggingEnabled() {
static bool animations = getenv("MOZ_DEBUG_RESTYLE_ANIMATIONS") != 0;
return animations;
}
static nsCString StructNamesToString(uint32_t aSIDs);
int32_t& LoggingDepth() { return mLoggingDepth; }
#endif
private:
/* aMinHint is the minimal change that should be made to the element */
// XXXbz do we really need the aPrimaryFrame argument here?
@ -393,6 +432,10 @@ private:
RestyleTracker mPendingRestyles;
RestyleTracker mPendingAnimationRestyles;
#ifdef RESTYLE_LOGGING
int32_t mLoggingDepth;
#endif
};
/**
@ -451,6 +494,12 @@ public:
*/
nsChangeHint HintsHandledForFrame() { return mHintsHandled; }
#ifdef RESTYLE_LOGGING
bool ShouldLogRestyle() {
return RestyleManager::ShouldLogRestyle(mPresContext);
}
#endif
private:
// Enum for the result of RestyleSelf, which indicates whether the
// restyle procedure should continue to the children, and how.
@ -474,8 +523,7 @@ private:
*/
RestyleResult RestyleSelf(nsIFrame* aSelf,
nsRestyleHint aRestyleHint,
uint32_t* aSwappedStructs,
nsIFrame** aProviderFrame);
uint32_t* aSwappedStructs);
/**
* Restyle the children of this frame (and, in turn, their children).
@ -518,6 +566,14 @@ private:
eNotifyHidden
};
#ifdef RESTYLE_LOGGING
int32_t& LoggingDepth() { return mLoggingDepth; }
#endif
#ifdef DEBUG
static nsCString RestyleResultToString(RestyleResult aRestyleResult);
#endif
private:
nsPresContext* const mPresContext;
nsIFrame* const mFrame;
@ -547,6 +603,10 @@ private:
nsTArray<nsIContent*>& mVisibleKidsOfHiddenElement;
bool mWasFrameVisible;
#endif
#ifdef RESTYLE_LOGGING
int32_t mLoggingDepth;
#endif
};
} // namespace mozilla

Просмотреть файл

@ -12,9 +12,38 @@
#include "nsStyleChangeList.h"
#include "RestyleManager.h"
#include "GeckoProfiler.h"
#include "nsIDocument.h"
#include "RestyleTrackerInlines.h"
namespace mozilla {
#ifdef RESTYLE_LOGGING
static nsCString
GetDocumentURI(nsIDocument* aDocument)
{
nsCString result;
nsString url;
aDocument->GetDocumentURI(url);
result.Append(NS_ConvertUTF16toUTF8(url).get());
return result;
}
static nsCString
FrameTagToString(dom::Element* aElement)
{
nsCString result;
nsIFrame* frame = aElement->GetPrimaryFrame();
if (frame) {
nsFrame::ListTag(result, frame);
} else {
nsAutoString buf;
aElement->Tag()->ToString(buf);
result.AppendPrintf("(%s@%p)", NS_ConvertUTF16toUTF8(buf).get(), aElement);
}
return result;
}
#endif
inline nsIDocument*
RestyleTracker::Document() const {
return mRestyleManager->PresContext()->Document();
@ -56,6 +85,9 @@ struct RestyleEnumerateData : RestyleTracker::Hints {
struct RestyleCollector {
RestyleTracker* tracker;
RestyleEnumerateData** restyleArrayPtr;
#ifdef RESTYLE_LOGGING
uint32_t count;
#endif
};
static PLDHashOperator
@ -73,6 +105,9 @@ CollectRestyles(nsISupports* aElement,
// document.
if (element->GetCrossShadowCurrentDoc() != collector->tracker->Document() ||
!element->HasFlag(collector->tracker->RestyleBit())) {
LOG_RESTYLE_IF(collector->tracker, true,
"skipping pending restyle %s, already restyled or no longer "
"in the document", FrameTagToString(element).get());
return PL_DHASH_NEXT;
}
@ -101,6 +136,10 @@ CollectRestyles(nsISupports* aElement,
currentRestyle->mRestyleHint = aData->mRestyleHint;
currentRestyle->mChangeHint = aData->mChangeHint;
#ifdef RESTYLE_LOGGING
collector->count++;
#endif
// Increment to the next slot in the array
*restyleArrayPtr = currentRestyle + 1;
@ -118,6 +157,10 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
NS_PRECONDITION(aElement->GetCrossShadowCurrentDoc() == Document(),
"Element has unexpected document");
LOG_RESTYLE("aRestyleHint = %s, aChangeHint = %s",
RestyleManager::RestyleHintToString(aRestyleHint).get(),
RestyleManager::ChangeHintToString(aChangeHint).get());
nsIFrame* primaryFrame = aElement->GetPrimaryFrame();
if (aRestyleHint & ~eRestyle_LaterSiblings) {
mRestyleManager->RestyleElement(aElement, primaryFrame, aChangeHint,
@ -140,6 +183,14 @@ RestyleTracker::DoProcessRestyles()
mRestyleManager->BeginProcessingRestyles();
LOG_RESTYLE("Processing %d pending %srestyles with %d restyle roots for %s",
mPendingRestyles.Count(),
mRestyleManager->PresContext()->IsProcessingAnimationStyleChange()
? (const char*) "animation " : (const char*) "",
static_cast<int>(mRestyleRoots.Length()),
GetDocumentURI(Document()).get());
LOG_RESTYLE_INDENT();
// loop so that we process any restyle events generated by processing
while (mPendingRestyles.Count()) {
if (mHaveLaterSiblingRestyles) {
@ -152,8 +203,12 @@ RestyleTracker::DoProcessRestyles()
for (nsIContent* sibling = element->GetNextSibling();
sibling;
sibling = sibling->GetNextSibling()) {
if (sibling->IsElement() &&
AddPendingRestyle(sibling->AsElement(), eRestyle_Subtree,
if (sibling->IsElement()) {
LOG_RESTYLE("adding pending restyle for %s due to "
"eRestyle_LaterSiblings hint on %s",
FrameTagToString(sibling->AsElement()).get(),
FrameTagToString(element->AsElement()).get());
if (AddPendingRestyle(sibling->AsElement(), eRestyle_Subtree,
NS_STYLE_HINT_NONE)) {
// Nothing else to do here; we'll handle the following
// siblings when we get to |sibling| in laterSiblingArr.
@ -161,6 +216,7 @@ RestyleTracker::DoProcessRestyles()
}
}
}
}
// Now remove all those eRestyle_LaterSiblings bits
for (uint32_t i = 0; i < laterSiblingArr.Length(); ++i) {
@ -176,6 +232,9 @@ RestyleTracker::DoProcessRestyles()
nsRestyleHint(data->mRestyleHint & ~eRestyle_LaterSiblings);
}
LOG_RESTYLE("%d pending restyles after expanding out "
"eRestyle_LaterSiblings", mPendingRestyles.Count());
mHaveLaterSiblingRestyles = false;
}
@ -188,17 +247,23 @@ RestyleTracker::DoProcessRestyles()
element.swap(mRestyleRoots[rootCount - 1]);
mRestyleRoots.RemoveElementAt(rootCount - 1);
LOG_RESTYLE("processing style root %s at index %d",
FrameTagToString(element).get(), rootCount - 1);
LOG_RESTYLE_INDENT();
// Do the document check before calling GetRestyleData, since we
// don't want to do the sibling-processing GetRestyleData does if
// the node is no longer relevant.
if (element->GetCrossShadowCurrentDoc() != Document()) {
// Content node has been removed from our document; nothing else
// to do here
LOG_RESTYLE("skipping, no longer in the document");
continue;
}
nsAutoPtr<RestyleData> data;
if (!GetRestyleData(element, data)) {
LOG_RESTYLE("skipping, already restyled");
continue;
}
@ -227,9 +292,16 @@ RestyleTracker::DoProcessRestyles()
// Clear the hashtable now that we don't need it anymore
mPendingRestyles.Clear();
#ifdef RESTYLE_LOGGING
uint32_t index = 0;
#endif
for (RestyleEnumerateData* currentRestyle = restylesToProcess;
currentRestyle != lastRestyle;
++currentRestyle) {
LOG_RESTYLE("processing pending restyle %s at index %d/%d",
FrameTagToString(currentRestyle->mElement).get(),
index++, collector.count);
LOG_RESTYLE_INDENT();
ProcessOneRestyle(currentRestyle->mElement,
currentRestyle->mRestyleHint,
currentRestyle->mChangeHint);

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsClassHashtable.h"
#include "nsContainerFrame.h"
#include "mozilla/SplayTree.h"
#include "mozilla/RestyleLogging.h"
namespace mozilla {
@ -233,9 +234,9 @@ public:
friend class ElementRestyler; // for AddPendingRestyleToTable
explicit RestyleTracker(Element::FlagsType aRestyleBits) :
mRestyleBits(aRestyleBits),
mHaveLaterSiblingRestyles(false)
explicit RestyleTracker(Element::FlagsType aRestyleBits)
: mRestyleBits(aRestyleBits)
, mHaveLaterSiblingRestyles(false)
{
NS_PRECONDITION((mRestyleBits & ~ELEMENT_ALL_RESTYLE_FLAGS) == 0,
"Why do we have these bits set?");
@ -342,6 +343,12 @@ public:
*/
inline nsIDocument* Document() const;
#ifdef RESTYLE_LOGGING
// Defined in RestyleTrackerInlines.h.
inline bool ShouldLogRestyle();
inline int32_t& LoggingDepth();
#endif
private:
bool AddPendingRestyleToTable(Element* aElement, nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);

Просмотреть файл

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_RestyleTrackerInlines_h
#define mozilla_RestyleTrackerInlines_h
#ifdef RESTYLE_LOGGING
bool
mozilla::RestyleTracker::ShouldLogRestyle()
{
return mRestyleManager->ShouldLogRestyle();
}
int32_t&
mozilla::RestyleTracker::LoggingDepth()
{
return mRestyleManager->LoggingDepth();
}
#endif
#endif // !defined(mozilla_RestyleTrackerInlines_h)

Просмотреть файл

@ -59,6 +59,7 @@ EXPORTS += [
EXPORTS.mozilla += [
'GeometryUtils.h',
'PaintTracker.h',
'RestyleLogging.h',
]
UNIFIED_SOURCES += [

Просмотреть файл

@ -153,7 +153,8 @@ enum nsChangeHint {
nsChangeHint_NeutralChange = 0x100000
// IMPORTANT NOTE: When adding new hints, consider whether you need to
// add them to NS_HintsNotHandledForDescendantsIn() below.
// add them to NS_HintsNotHandledForDescendantsIn() below. Please also
// add them to RestyleManager::ChangeHintToString.
};
// Redefine these operators to return nothing. This will catch any use
@ -277,6 +278,9 @@ inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint)
* Similarly, eRestyle_ForceDescendants will cause the frame and all of its
* descendants to be traversed and for the new style contexts that are created
* to be set on the frames.
*
* NOTE: When adding new restyle hints, please also add them to
* RestyleManager::RestyleHintToString.
*/
enum nsRestyleHint {
// Rerun selector matching on the element. If a new style context

Просмотреть файл

@ -270,6 +270,11 @@ public:
*/
void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; }
bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; }
/**
* @return Returns true if we should include the caret in any display lists
* that we make.
*/
bool IsBuildingCaret() { return mBuildCaret; }
/**
* Allows callers to selectively override the regular paint suppression checks,
* so that methods like GetFrameForPoint work when painting is suppressed.

Просмотреть файл

@ -41,7 +41,7 @@
#include "nsFontFaceLoader.h"
#include "mozilla/EventListenerManager.h"
#include "prenv.h"
#include "nsObjectFrame.h"
#include "nsPluginFrame.h"
#include "nsTransitionManager.h"
#include "nsAnimationManager.h"
#include "CounterStyleManager.h"
@ -1074,6 +1074,10 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext)
mEventManager->SetPresContext(this);
#ifdef RESTYLE_LOGGING
mRestyleLoggingEnabled = RestyleManager::RestyleLoggingInitiallyEnabled();
#endif
#ifdef DEBUG
mInitialized = true;
#endif
@ -2856,7 +2860,7 @@ static PLDHashOperator
SetPluginHidden(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
{
nsIFrame* root = static_cast<nsIFrame*>(userArg);
nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
nsPluginFrame* f = static_cast<nsPluginFrame*>(aEntry->GetKey()->GetPrimaryFrame());
if (!f) {
NS_WARNING("Null frame in SetPluginHidden");
return PL_DHASH_NEXT;
@ -3016,7 +3020,7 @@ SortConfigurations(nsTArray<nsIWidget::Configuration>* aConfigurations)
static PLDHashOperator
PluginDidSetGeometryEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
{
nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
nsPluginFrame* f = static_cast<nsPluginFrame*>(aEntry->GetKey()->GetPrimaryFrame());
if (!f) {
NS_WARNING("Null frame in PluginDidSetGeometryEnumerator");
return PL_DHASH_NEXT;
@ -3033,7 +3037,7 @@ PluginGetGeometryUpdate(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
{
PluginGetGeometryUpdateClosure* closure =
static_cast<PluginGetGeometryUpdateClosure*>(userArg);
nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
nsPluginFrame* f = static_cast<nsPluginFrame*>(aEntry->GetKey()->GetPrimaryFrame());
if (!f) {
NS_WARNING("Null frame in GetPluginGeometryUpdate");
return PL_DHASH_NEXT;

Просмотреть файл

@ -37,6 +37,7 @@
#include "nsThreadUtils.h"
#include "ScrollbarStyles.h"
#include "nsIMessageManager.h"
#include "mozilla/RestyleLogging.h"
class nsBidiPresUtils;
class nsAString;
@ -59,7 +60,7 @@ class gfxUserFontSet;
class gfxTextPerfMetrics;
class nsUserFontSet;
struct nsFontFaceRuleContainer;
class nsObjectFrame;
class nsPluginFrame;
class nsTransitionManager;
class nsAnimationManager;
class nsRefreshDriver;
@ -1151,6 +1152,14 @@ public:
*/
bool MayHavePaintEventListenerInSubDocument();
#ifdef RESTYLE_LOGGING
// Controls for whether debug information about restyling in this
// document should be output.
bool RestyleLoggingEnabled() const { return mRestyleLoggingEnabled; }
void StartRestyleLogging() { mRestyleLoggingEnabled = true; }
void StopRestyleLogging() { mRestyleLoggingEnabled = false; }
#endif
protected:
void InvalidateThebesLayers();
void AppUnitsPerDevPixelChanged();
@ -1352,6 +1361,11 @@ protected:
unsigned mHasWarnedAboutPositionedTableParts : 1;
#ifdef RESTYLE_LOGGING
// Should we output debug information about restyling for this document?
bool mRestyleLoggingEnabled;
#endif
#ifdef DEBUG
bool mInitialized;
#endif
@ -1431,7 +1445,7 @@ public:
* Compute geometry updates for each plugin given that aList is the display
* list for aFrame. The updates are not yet applied;
* ApplyPluginGeometryUpdates is responsible for that. In the meantime they
* are stored on each nsObjectFrame.
* are stored on each nsPluginFrame.
* This needs to be called even when aFrame is a popup, since although
* windowed plugins aren't allowed in popups, windowless plugins are
* and ComputePluginGeometryUpdates needs to be called for them.

Просмотреть файл

@ -490,3 +490,4 @@ support-files =
bug687297_b.html
bug687297_c.html
[test_bug990340.html]
[test_bug1070851.html]

Просмотреть файл

@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1070851
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1070851</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
/* Eliminate the blue glow when focusing an element. */
input, textarea, div {
background: none;
border: none;
outline: none;
}
</style>
<script type="application/javascript">
/** Test for Bug 1070851 **/
SimpleTest.waitForExplicitFinish();
function testSnapshot(aElementId)
{
var noTouchCaret = snapshotWindow(window, true);
// Focus the element to make the touch caret show, but do not capture it.
var element = document.getElementById(aElementId);
element.focus();
var notCaptureTouchCaret = snapshotWindow(window, false);
[result, first, second] = compareSnapshots(noTouchCaret, notCaptureTouchCaret,
true);
ok(result, "Both snapshots of " + aElementId + " should have no touch caret." +
"\nFirst snapshot: " + first + "\nSecond snapshot: " + second);
element.blur();
}
SimpleTest.waitForFocus(function() {
testSnapshot('input');
testSnapshot('textarea');
testSnapshot('content');
SimpleTest.finish();
})
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1070851">Mozilla Bug 1070851</a>
<input id="input">
<textarea id="textarea"></textarea>
<div id="content" contenteditable="true">test</div>
</body>
</html>

Просмотреть файл

@ -27,7 +27,7 @@ EXPORTS += [
'nsIScrollableFrame.h',
'nsIScrollPositionListener.h',
'nsIStatefulFrame.h',
'nsObjectFrame.h',
'nsPluginFrame.h',
'nsQueryFrame.h',
'nsSplittableFrame.h',
'nsSubDocumentFrame.h',
@ -100,10 +100,10 @@ UNIFIED_SOURCES += [
]
# nsLineLayout.cpp needs to be built separately because it uses plarena.h.
# nsObjectFrame.cpp needs to be built separately because of name clashes in the OS X headers.
# nsPluginFrame.cpp needs to be built separately because of name clashes in the OS X headers.
SOURCES += [
'nsLineLayout.cpp',
'nsObjectFrame.cpp',
'nsPluginFrame.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':

Просмотреть файл

@ -416,6 +416,11 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsIFrame* kid;
for (kid = GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
// Skip touch caret frame if we do not build caret.
if (!aBuilder->IsBuildingCaret() && kid->GetContent() == mTouchCaretElement) {
continue;
}
// Put our child into its own pseudo-stack.
BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
}

Просмотреть файл

@ -103,7 +103,7 @@ FRAME_ID(nsMenuFrame)
FRAME_ID(nsMenuPopupFrame)
FRAME_ID(nsMeterFrame)
FRAME_ID(nsNumberControlFrame)
FRAME_ID(nsObjectFrame)
FRAME_ID(nsPluginFrame)
FRAME_ID(nsPageBreakFrame)
FRAME_ID(nsPageContentFrame)
FRAME_ID(nsPageFrame)

Просмотреть файл

@ -488,9 +488,9 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState,
*aMetrics, &kidReflowState, 0, 0,
NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_SIZE_VIEW);
// XXX Some frames (e.g., nsObjectFrame, nsFrameFrame, nsTextFrame) don't bother
// XXX Some frames (e.g., nsPluginFrame, nsFrameFrame, nsTextFrame) don't bother
// setting their mOverflowArea. This is wrong because every frame should
// always set mOverflowArea. In fact nsObjectFrame and nsFrameFrame don't
// always set mOverflowArea. In fact nsPluginFrame and nsFrameFrame don't
// support the 'outline' property because of this. Rather than fix the world
// right now, just fix up the overflow area if necessary. Note that we don't
// check HasOverflowRect() because it could be set even though the

Просмотреть файл

@ -6,7 +6,7 @@
/* rendering objects for replaced elements implemented by a plugin */
#include "nsObjectFrame.h"
#include "nsPluginFrame.h"
#include "gfx2DGlue.h"
#include "gfxMatrix.h"
@ -97,7 +97,7 @@ GetObjectFrameLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("nsObjectFrame");
sLog = PR_NewLogModule("nsPluginFrame");
return sLog;
}
#endif /* PR_LOGGING */
@ -145,7 +145,7 @@ using namespace mozilla::layers;
class PluginBackgroundSink : public ReadbackSink {
public:
PluginBackgroundSink(nsObjectFrame* aFrame, uint64_t aStartSequenceNumber)
PluginBackgroundSink(nsPluginFrame* aFrame, uint64_t aStartSequenceNumber)
: mLastSequenceNumber(aStartSequenceNumber), mFrame(aFrame) {}
~PluginBackgroundSink()
{
@ -187,37 +187,37 @@ protected:
}
uint64_t mLastSequenceNumber;
nsObjectFrame* mFrame;
nsPluginFrame* mFrame;
};
nsObjectFrame::nsObjectFrame(nsStyleContext* aContext)
: nsObjectFrameSuper(aContext)
nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
: nsPluginFrameSuper(aContext)
, mReflowCallbackPosted(false)
{
PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG,
("Created new nsObjectFrame %p\n", this));
("Created new nsPluginFrame %p\n", this));
}
nsObjectFrame::~nsObjectFrame()
nsPluginFrame::~nsPluginFrame()
{
PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG,
("nsObjectFrame %p deleted\n", this));
("nsPluginFrame %p deleted\n", this));
}
NS_QUERYFRAME_HEAD(nsObjectFrame)
NS_QUERYFRAME_ENTRY(nsObjectFrame)
NS_QUERYFRAME_HEAD(nsPluginFrame)
NS_QUERYFRAME_ENTRY(nsPluginFrame)
NS_QUERYFRAME_ENTRY(nsIObjectFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsObjectFrameSuper)
NS_QUERYFRAME_TAIL_INHERITING(nsPluginFrameSuper)
#ifdef ACCESSIBILITY
a11y::AccType
nsObjectFrame::AccessibleType()
nsPluginFrame::AccessibleType()
{
return a11y::ePluginType;
}
#ifdef XP_WIN
NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort)
NS_IMETHODIMP nsPluginFrame::GetPluginPort(HWND *aPort)
{
*aPort = (HWND) mInstanceOwner->GetPluginPortFromWidget();
return NS_OK;
@ -226,18 +226,18 @@ NS_IMETHODIMP nsObjectFrame::GetPluginPort(HWND *aPort)
#endif
void
nsObjectFrame::Init(nsIContent* aContent,
nsPluginFrame::Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow)
{
PR_LOG(GetObjectFrameLog(), PR_LOG_DEBUG,
("Initializing nsObjectFrame %p for content %p\n", this, aContent));
("Initializing nsPluginFrame %p for content %p\n", this, aContent));
nsObjectFrameSuper::Init(aContent, aParent, aPrevInFlow);
nsPluginFrameSuper::Init(aContent, aParent, aPrevInFlow);
}
void
nsObjectFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
if (mReflowCallbackPosted) {
PresContext()->PresShell()->CancelReflowCallback(this);
@ -259,11 +259,11 @@ nsObjectFrame::DestroyFrom(nsIFrame* aDestructRoot)
mBackgroundSink->Destroy();
}
nsObjectFrameSuper::DestroyFrom(aDestructRoot);
nsPluginFrameSuper::DestroyFrom(aDestructRoot);
}
/* virtual */ void
nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
nsPluginFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
{
if (HasView()) {
nsView* view = GetView();
@ -275,25 +275,25 @@ nsObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
}
}
nsObjectFrameSuper::DidSetStyleContext(aOldStyleContext);
nsPluginFrameSuper::DidSetStyleContext(aOldStyleContext);
}
nsIAtom*
nsObjectFrame::GetType() const
nsPluginFrame::GetType() const
{
return nsGkAtoms::objectFrame;
}
#ifdef DEBUG_FRAME_DUMP
nsresult
nsObjectFrame::GetFrameName(nsAString& aResult) const
nsPluginFrame::GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("ObjectFrame"), aResult);
return MakeFrameName(NS_LITERAL_STRING("PluginFrame"), aResult);
}
#endif
nsresult
nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
nsPluginFrame::PrepForDrawing(nsIWidget *aWidget)
{
mWidget = aWidget;
@ -411,7 +411,7 @@ nsObjectFrame::PrepForDrawing(nsIWidget *aWidget)
#define EMBED_DEF_HEIGHT 200
/* virtual */ nscoord
nsObjectFrame::GetMinISize(nsRenderingContext *aRenderingContext)
nsPluginFrame::GetMinISize(nsRenderingContext *aRenderingContext)
{
nscoord result = 0;
@ -427,13 +427,13 @@ nsObjectFrame::GetMinISize(nsRenderingContext *aRenderingContext)
}
/* virtual */ nscoord
nsObjectFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
nsPluginFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
{
return nsObjectFrame::GetMinISize(aRenderingContext);
return nsPluginFrame::GetMinISize(aRenderingContext);
}
void
nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext,
nsPluginFrame::GetDesiredSize(nsPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aMetrics)
{
@ -498,12 +498,12 @@ nsObjectFrame::GetDesiredSize(nsPresContext* aPresContext,
}
void
nsObjectFrame::Reflow(nsPresContext* aPresContext,
nsPluginFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
DO_GLOBAL_REFLOW_COUNT("nsObjectFrame");
DO_GLOBAL_REFLOW_COUNT("nsPluginFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus);
// Get our desired size
@ -548,7 +548,7 @@ nsObjectFrame::Reflow(nsPresContext* aPresContext,
///////////// nsIReflowCallback ///////////////
bool
nsObjectFrame::ReflowFinished()
nsPluginFrame::ReflowFinished()
{
mReflowCallbackPosted = false;
CallSetWindow();
@ -556,13 +556,13 @@ nsObjectFrame::ReflowFinished()
}
void
nsObjectFrame::ReflowCallbackCanceled()
nsPluginFrame::ReflowCallbackCanceled()
{
mReflowCallbackPosted = false;
}
void
nsObjectFrame::FixupWindow(const nsSize& aSize)
nsPluginFrame::FixupWindow(const nsSize& aSize)
{
nsPresContext* presContext = PresContext();
@ -613,7 +613,7 @@ nsObjectFrame::FixupWindow(const nsSize& aSize)
}
nsresult
nsObjectFrame::CallSetWindow(bool aCheckIsHidden)
nsPluginFrame::CallSetWindow(bool aCheckIsHidden)
{
NPWindow *win = nullptr;
@ -683,7 +683,7 @@ nsObjectFrame::CallSetWindow(bool aCheckIsHidden)
}
void
nsObjectFrame::RegisterPluginForGeometryUpdates()
nsPluginFrame::RegisterPluginForGeometryUpdates()
{
nsRootPresContext* rpc = PresContext()->GetRootPresContext();
NS_ASSERTION(rpc, "We should have a root pres context!");
@ -702,7 +702,7 @@ nsObjectFrame::RegisterPluginForGeometryUpdates()
}
void
nsObjectFrame::UnregisterPluginForGeometryUpdates()
nsPluginFrame::UnregisterPluginForGeometryUpdates()
{
if (!mRootPresContextRegisteredWith) {
// Not registered...
@ -713,7 +713,7 @@ nsObjectFrame::UnregisterPluginForGeometryUpdates()
}
void
nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
nsPluginFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
{
// The ownership model here is historically fuzzy. This should only be called
// by nsPluginInstanceOwner when it is given a new frame, and
@ -743,15 +743,15 @@ nsObjectFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
}
bool
nsObjectFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
nsPluginFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
{
if (aTabIndex)
*aTabIndex = -1;
return nsObjectFrameSuper::IsFocusable(aTabIndex, aWithMouse);
return nsPluginFrameSuper::IsFocusable(aTabIndex, aWithMouse);
}
bool
nsObjectFrame::IsHidden(bool aCheckVisibilityStyle) const
nsPluginFrame::IsHidden(bool aCheckVisibilityStyle) const
{
if (aCheckVisibilityStyle) {
if (!StyleVisibility()->IsVisibleOrCollapsed())
@ -780,7 +780,7 @@ nsObjectFrame::IsHidden(bool aCheckVisibilityStyle) const
return false;
}
nsIntPoint nsObjectFrame::GetWindowOriginInPixels(bool aWindowless)
nsIntPoint nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
{
nsView * parentWithView;
nsPoint origin(0,0);
@ -801,7 +801,7 @@ nsIntPoint nsObjectFrame::GetWindowOriginInPixels(bool aWindowless)
}
void
nsObjectFrame::DidReflow(nsPresContext* aPresContext,
nsPluginFrame::DidReflow(nsPresContext* aPresContext,
const nsHTMLReflowState* aReflowState,
nsDidReflowStatus aStatus)
{
@ -814,7 +814,7 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext,
objContent->HasNewFrame(this);
}
nsObjectFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
nsPluginFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
// The view is created hidden; once we have reflowed it and it has been
// positioned then we show it.
@ -830,7 +830,7 @@ nsObjectFrame::DidReflow(nsPresContext* aPresContext,
}
/* static */ void
nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx,
nsPluginFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx,
const nsRect& aDirtyRect, nsPoint aPt)
{
gfxContext* ctx = aCtx->ThebesContext();
@ -845,7 +845,7 @@ nsObjectFrame::PaintPrintPlugin(nsIFrame* aFrame, nsRenderingContext* aCtx,
// FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
static_cast<nsObjectFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
static_cast<nsPluginFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
}
/**
@ -876,7 +876,7 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
{
return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
}
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
@ -925,7 +925,7 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
{
return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
}
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
@ -961,7 +961,7 @@ void
nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
bool snap;
f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap));
}
@ -971,7 +971,7 @@ nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion)
{
if (aBuilder->IsForPluginGeometry()) {
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
if (!aBuilder->IsInTransform() || f->IsPaintedByGecko()) {
// Since transforms induce reference frames, we don't need to worry
// about this method fluffing out due to non-rectilinear transforms.
@ -1016,7 +1016,7 @@ nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
{
*aSnap = false;
nsRegion result;
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
if (!aBuilder->IsForPluginGeometry()) {
nsIWidget* widget = f->GetWidget();
if (widget) {
@ -1045,7 +1045,7 @@ nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
}
nsresult
nsObjectFrame::PluginEventNotifier::Run() {
nsPluginFrame::PluginEventNotifier::Run() {
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
obsSvc->NotifyObservers(nullptr, "plugin-changed-event", mEventType.get());
@ -1053,13 +1053,13 @@ nsObjectFrame::PluginEventNotifier::Run() {
}
void
nsObjectFrame::NotifyPluginReflowObservers()
nsPluginFrame::NotifyPluginReflowObservers()
{
nsContentUtils::AddScriptRunner(new PluginEventNotifier(NS_LITERAL_STRING("reflow")));
}
void
nsObjectFrame::DidSetWidgetGeometry()
nsPluginFrame::DidSetWidgetGeometry()
{
#if defined(XP_MACOSX)
if (mInstanceOwner) {
@ -1080,7 +1080,7 @@ nsObjectFrame::DidSetWidgetGeometry()
}
bool
nsObjectFrame::IsOpaque() const
nsPluginFrame::IsOpaque() const
{
#if defined(XP_MACOSX)
// ???
@ -1094,7 +1094,7 @@ nsObjectFrame::IsOpaque() const
}
bool
nsObjectFrame::IsTransparentMode() const
nsPluginFrame::IsTransparentMode() const
{
#if defined(XP_MACOSX)
// ???
@ -1125,7 +1125,7 @@ nsObjectFrame::IsTransparentMode() const
}
void
nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
@ -1141,7 +1141,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (type == nsPresContext::eContext_PrintPreview)
return;
DO_GLOBAL_REFLOW_COUNT_DSP("nsObjectFrame");
DO_GLOBAL_REFLOW_COUNT_DSP("nsPluginFrame");
#ifndef XP_MACOSX
if (mWidget && aBuilder->IsInTransform()) {
@ -1207,7 +1207,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
void
nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
nsPluginFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
nsCOMPtr<nsIObjectLoadingContent> obj(do_QueryInterface(mContent));
@ -1420,7 +1420,7 @@ nsObjectFrame::PrintPlugin(nsRenderingContext& aRenderingContext,
}
nsRect
nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem)
nsPluginFrame::GetPaintedRect(nsDisplayPlugin* aItem)
{
if (!mInstanceOwner)
return nsRect();
@ -1436,7 +1436,7 @@ nsObjectFrame::GetPaintedRect(nsDisplayPlugin* aItem)
}
LayerState
nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
nsPluginFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager)
{
if (!mInstanceOwner)
@ -1456,7 +1456,7 @@ nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
}
already_AddRefed<Layer>
nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
nsDisplayItem* aItem,
const ContainerLayerParameters& aContainerParameters)
@ -1594,7 +1594,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
}
void
nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, const nsRect& aPluginRect)
{
@ -1826,7 +1826,7 @@ nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
}
nsresult
nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
WidgetGUIEvent* anEvent,
nsEventStatus* anEventStatus)
{
@ -1869,7 +1869,7 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
}
#ifdef XP_WIN
rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
return rv;
#endif
@ -1893,10 +1893,10 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
}
#endif
rv = nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
// We need to be careful from this point because the call to
// nsObjectFrameSuper::HandleEvent() might have killed us.
// nsPluginFrameSuper::HandleEvent() might have killed us.
#ifdef XP_MACOSX
if (anEvent->message == NS_MOUSE_BUTTON_UP) {
@ -1908,7 +1908,7 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
}
nsresult
nsObjectFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance)
nsPluginFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance)
{
*aPluginInstance = nullptr;
@ -1920,7 +1920,7 @@ nsObjectFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance)
}
nsresult
nsObjectFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
nsPluginFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
{
if (!mInstanceOwner) {
return NS_ERROR_FAILURE;
@ -1937,11 +1937,11 @@ nsObjectFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
return NS_ERROR_FAILURE;
}
return nsObjectFrameSuper::GetCursor(aPoint, aCursor);
return nsPluginFrameSuper::GetCursor(aPoint, aCursor);
}
void
nsObjectFrame::SetIsDocumentActive(bool aIsActive)
nsPluginFrame::SetIsDocumentActive(bool aIsActive)
{
#ifndef XP_MACOSX
if (mInstanceOwner) {
@ -1952,7 +1952,7 @@ nsObjectFrame::SetIsDocumentActive(bool aIsActive)
// static
nsIObjectFrame *
nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
nsPluginFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
{
nsIFrame* child = aRoot->GetFirstPrincipalChild();
@ -1975,7 +1975,7 @@ nsObjectFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
}
/*static*/ void
nsObjectFrame::BeginSwapDocShells(nsISupports* aSupports, void*)
nsPluginFrame::BeginSwapDocShells(nsISupports* aSupports, void*)
{
NS_PRECONDITION(aSupports, "");
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
@ -1984,19 +1984,19 @@ nsObjectFrame::BeginSwapDocShells(nsISupports* aSupports, void*)
}
// This function is called from a document content enumerator so we need
// to filter out the nsObjectFrames and ignore the rest.
// to filter out the nsPluginFrames and ignore the rest.
nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame());
if (!obj)
return;
nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj);
nsPluginFrame* objectFrame = static_cast<nsPluginFrame*>(obj);
NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(),
"Plugin windows must not be toplevel");
objectFrame->UnregisterPluginForGeometryUpdates();
}
/*static*/ void
nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*)
nsPluginFrame::EndSwapDocShells(nsISupports* aSupports, void*)
{
NS_PRECONDITION(aSupports, "");
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
@ -2005,12 +2005,12 @@ nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*)
}
// This function is called from a document content enumerator so we need
// to filter out the nsObjectFrames and ignore the rest.
// to filter out the nsPluginFrames and ignore the rest.
nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame());
if (!obj)
return;
nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj);
nsPluginFrame* objectFrame = static_cast<nsPluginFrame*>(obj);
nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
NS_ASSERTION(rootPC, "unable to register the plugin frame");
nsIWidget* widget = objectFrame->mWidget;
@ -2038,11 +2038,11 @@ nsObjectFrame::EndSwapDocShells(nsISupports* aSupports, void*)
nsIFrame*
NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsObjectFrame(aContext);
return new (aPresShell) nsPluginFrame(aContext);
}
bool
nsObjectFrame::IsPaintedByGecko() const
nsPluginFrame::IsPaintedByGecko() const
{
#ifdef XP_MACOSX
return true;
@ -2051,4 +2051,4 @@ nsObjectFrame::IsPaintedByGecko() const
#endif
}
NS_IMPL_FRAMEARENA_HELPERS(nsObjectFrame)
NS_IMPL_FRAMEARENA_HELPERS(nsPluginFrame)

Просмотреть файл

@ -5,8 +5,8 @@
/* rendering objects for replaced elements implemented by a plugin */
#ifndef nsObjectFrame_h___
#define nsObjectFrame_h___
#ifndef nsPluginFrame_h___
#define nsPluginFrame_h___
#include "mozilla/Attributes.h"
#include "nsIObjectFrame.h"
@ -40,9 +40,9 @@ class LayerManager;
}
}
typedef nsFrame nsObjectFrameSuper;
typedef nsFrame nsPluginFrameSuper;
class nsObjectFrame : public nsObjectFrameSuper,
class nsPluginFrame : public nsPluginFrameSuper,
public nsIObjectFrame,
public nsIReflowCallback {
public:
@ -57,7 +57,7 @@ public:
friend nsIFrame* NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
NS_DECL_QUERYFRAME
NS_DECL_QUERYFRAME_TARGET(nsObjectFrame)
NS_DECL_QUERYFRAME_TARGET(nsPluginFrame)
virtual void Init(nsIContent* aContent,
nsContainerFrame* aParent,
@ -83,7 +83,7 @@ public:
virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
{
return nsObjectFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
return nsPluginFrameSuper::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced));
}
virtual bool NeedsView() MOZ_OVERRIDE { return true; }
@ -183,14 +183,14 @@ public:
nsRect GetPaintedRect(nsDisplayPlugin* aItem);
/**
* If aSupports has a nsObjectFrame, then prepare it for a DocShell swap.
* If aSupports has a nsPluginFrame, then prepare it for a DocShell swap.
* @see nsSubDocumentFrame::BeginSwapDocShells.
* There will be a call to EndSwapDocShells after we were moved to the
* new view tree.
*/
static void BeginSwapDocShells(nsISupports* aSupports, void*);
/**
* If aSupports has a nsObjectFrame, then set it up after a DocShell swap.
* If aSupports has a nsPluginFrame, then set it up after a DocShell swap.
* @see nsSubDocumentFrame::EndSwapDocShells.
*/
static void EndSwapDocShells(nsISupports* aSupports, void*);
@ -211,8 +211,8 @@ public:
void SetInstanceOwner(nsPluginInstanceOwner* aOwner);
protected:
explicit nsObjectFrame(nsStyleContext* aContext);
virtual ~nsObjectFrame();
explicit nsPluginFrame(nsStyleContext* aContext);
virtual ~nsPluginFrame();
// NOTE: This frame class does not inherit from |nsLeafFrame|, so
// this is not a virtual method implementation.
@ -273,7 +273,7 @@ private:
nsCOMPtr<nsIWidget> mWidget;
nsIntRect mWindowlessRect;
/**
* This is owned by the ReadbackLayer for this nsObjectFrame. It is
* This is owned by the ReadbackLayer for this nsPluginFrame. It is
* automatically cleared if the PluginBackgroundSink is destroyed.
*/
PluginBackgroundSink* mBackgroundSink;
@ -327,7 +327,7 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
{
return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder,
return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder,
aManager,
this,
aContainerParameters);
@ -337,9 +337,9 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
{
return static_cast<nsObjectFrame*>(mFrame)->GetLayerState(aBuilder,
return static_cast<nsPluginFrame*>(mFrame)->GetLayerState(aBuilder,
aManager);
}
};
#endif /* nsObjectFrame_h___ */
#endif /* nsPluginFrame_h___ */

Просмотреть файл

@ -34,7 +34,7 @@
#include "nsIObjectLoadingContent.h"
#include "nsLayoutUtils.h"
#include "FrameLayerBuilder.h"
#include "nsObjectFrame.h"
#include "nsPluginFrame.h"
#include "nsContentUtils.h"
#include "nsIPermissionManager.h"
#include "nsServiceManagerUtils.h"
@ -1021,7 +1021,7 @@ BeginSwapDocShellsForDocument(nsIDocument* aDocument, void*)
}
}
aDocument->EnumerateActivityObservers(
nsObjectFrame::BeginSwapDocShells, nullptr);
nsPluginFrame::BeginSwapDocShells, nullptr);
aDocument->EnumerateSubDocuments(BeginSwapDocShellsForDocument, nullptr);
return true;
}
@ -1118,7 +1118,7 @@ EndSwapDocShellsForDocument(nsIDocument* aDocument, void*)
}
aDocument->EnumerateActivityObservers(
nsObjectFrame::EndSwapDocShells, nullptr);
nsPluginFrame::EndSwapDocShells, nullptr);
aDocument->EnumerateSubDocuments(EndSwapDocShellsForDocument, nullptr);
return true;
}

Просмотреть файл

@ -1795,7 +1795,7 @@ GetFirstFontMetrics(gfxFontGroup* aFontGroup)
{
if (!aFontGroup)
return gfxFont::Metrics();
gfxFont* font = aFontGroup->GetFontAt(0);
gfxFont* font = aFontGroup->GetFirstValidFont();
if (!font)
return gfxFont::Metrics();
return font->GetMetrics();
@ -5660,7 +5660,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
sdptr = sdptr->mNext;
}
gfxFont* firstFont = aProvider.GetFontGroup()->GetFontAt(0);
gfxFont* firstFont = aProvider.GetFontGroup()->GetFirstValidFont();
if (!firstFont)
return; // OOM
gfxFont::Metrics decorationMetrics(firstFont->GetMetrics());
@ -6341,7 +6341,7 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
GetFontSizeInflation());
gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
gfxFont* firstFont = fontGroup->GetFontAt(0);
gfxFont* firstFont = fontGroup->GetFirstValidFont();
if (!firstFont)
return false; // OOM
const gfxFont::Metrics& metrics = firstFont->GetMetrics();

Просмотреть файл

@ -57,7 +57,7 @@ NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
nsresult
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager();
nsNodeInfoManager *nodeInfoManager = GetContent()->GetComposedDoc()->NodeInfoManager();
nsRefPtr<NodeInfo> nodeInfo;
Element *element;

Просмотреть файл

@ -555,7 +555,8 @@ nsOpenTypeTable::MakeTextRun(gfxContext* aThebesContext,
aThebesContext, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel
};
gfxTextRun* textRun = gfxTextRun::Create(&params, 1, aFontGroup, 0);
textRun->AddGlyphRun(aFontGroup->GetFontAt(0), gfxTextRange::kFontGroup, 0,
textRun->AddGlyphRun(aFontGroup->GetFirstValidFont(),
gfxTextRange::kFontGroup, 0,
false, gfxTextRunFactory::TEXT_ORIENT_HORIZONTAL);
// We don't care about CSS writing mode here;
// math runs are assumed to be horizontal.
@ -563,7 +564,7 @@ nsOpenTypeTable::MakeTextRun(gfxContext* aThebesContext,
detailedGlyph.mGlyphID = aGlyph.glyphID;
detailedGlyph.mAdvance =
NSToCoordRound(aAppUnitsPerDevPixel *
aFontGroup->GetFontAt(0)->
aFontGroup->GetFirstValidFont()->
GetGlyphHAdvance(aThebesContext, aGlyph.glyphID));
detailedGlyph.mXOffset = detailedGlyph.mYOffset = 0;
gfxShapedText::CompressedGlyph g;
@ -993,7 +994,7 @@ nsMathMLChar::SetFontFamily(nsPresContext* aPresContext,
*getter_AddRefs(fm));
// Set the font if it is an unicode table
// or if the same family name has been found
gfxFont *firstFont = fm->GetThebesFontGroup()->GetFontAt(0);
gfxFont *firstFont = fm->GetThebesFontGroup()->GetFirstValidFont();
FontFamilyList firstFontList;
if (firstFont) {
firstFontList.Append(
@ -1439,7 +1440,7 @@ nsMathMLChar::StretchEnumContext::EnumCallback(const FontFamilyName& aFamily,
glyphTable = &gGlyphTableList->mUnicodeTable;
} else {
// If the font contains an Open Type MATH table, use it.
openTypeTable = nsOpenTypeTable::Create(fontGroup->GetFontAt(0));
openTypeTable = nsOpenTypeTable::Create(fontGroup->GetFirstValidFont());
if (openTypeTable) {
glyphTable = openTypeTable;
} else {

Просмотреть файл

@ -240,7 +240,7 @@ NS_IMPL_ISUPPORTS(nsMathMLmactionFrame::MouseListener,
// helper to show a msg on the status bar
// curled from nsObjectFrame.cpp ...
// curled from nsPluginFrame.cpp ...
void
ShowStatus(nsPresContext* aPresContext, nsString& aStatusMsg)
{

Просмотреть файл

@ -3,7 +3,7 @@
<style>
@font-face {
font-family: Ahem;
url: src(../fonts/Ahem.ttf);
src: url(../fonts/Ahem.ttf);
}
#a { font-family: Ahem }
</style>

Просмотреть файл

@ -3,7 +3,7 @@
<style>
@font-face {
font-family: Ahem;
url: src(../fonts/Ahem.ttf);
src: url(../fonts/Ahem.ttf);
}
#a { font-family: Ahem }
#c { font-family: Ahem2 }
@ -13,7 +13,7 @@
<style scoped>
@font-face {
font-family: Ahem2;
url: src(../fonts/Ahem.ttf);
src: url(../fonts/Ahem.ttf);
}
p { font-family: Ahem2; color: blue }
</style>

Просмотреть файл

@ -78,7 +78,8 @@ nsAnimationManager::GetEventsForCurrentTime(AnimationPlayerCollection*
TimeDuration elapsedTime =
std::max(iterationStart, anim->InitialAdvance());
AnimationEventInfo ei(aCollection->mElement, player->Name(), message,
elapsedTime, aCollection->PseudoElement());
StickyTimeDuration(elapsedTime),
aCollection->PseudoElement());
aEventsToDispatch.AppendElement(ei);
}
break;
@ -91,8 +92,9 @@ nsAnimationManager::GetEventsForCurrentTime(AnimationPlayerCollection*
// (This is overwritten below but we set it here to maintain
// internal consistency.)
anim->SetLastNotification(0);
TimeDuration elapsedTime =
std::min(anim->InitialAdvance(), computedTiming.mActiveDuration);
StickyTimeDuration elapsedTime =
std::min(StickyTimeDuration(anim->InitialAdvance()),
computedTiming.mActiveDuration);
AnimationEventInfo ei(aCollection->mElement,
player->Name(), NS_ANIMATION_START,
elapsedTime, aCollection->PseudoElement());

Просмотреть файл

@ -27,7 +27,8 @@ struct AnimationEventInfo {
AnimationEventInfo(mozilla::dom::Element *aElement,
const nsSubstring& aAnimationName,
uint32_t aMessage, mozilla::TimeDuration aElapsedTime,
uint32_t aMessage,
const mozilla::StickyTimeDuration& aElapsedTime,
const nsAString& aPseudoElement)
: mElement(aElement), mEvent(true, aMessage)
{

Просмотреть файл

@ -1397,14 +1397,30 @@ DOMCI_DATA(CSSNameSpaceRule, css::NameSpaceRule)
// nsCSSFontFaceStyleDecl and related routines
//
// Mapping from nsCSSFontDesc codes to nsCSSFontFaceStyleDecl fields.
nsCSSValue nsCSSFontFaceStyleDecl::* const
nsCSSFontFaceStyleDecl::Fields[] = {
#define CSS_FONT_DESC(name_, method_) &nsCSSFontFaceStyleDecl::m##method_,
// Mapping from nsCSSFontDesc codes to CSSFontFaceDescriptors fields.
nsCSSValue CSSFontFaceDescriptors::* const
CSSFontFaceDescriptors::Fields[] = {
#define CSS_FONT_DESC(name_, method_) &CSSFontFaceDescriptors::m##method_,
#include "nsCSSFontDescList.h"
#undef CSS_FONT_DESC
};
const nsCSSValue&
CSSFontFaceDescriptors::Get(nsCSSFontDesc aFontDescID) const
{
MOZ_ASSERT(aFontDescID > eCSSFontDesc_UNKNOWN &&
aFontDescID < eCSSFontDesc_COUNT);
return this->*CSSFontFaceDescriptors::Fields[aFontDescID];
}
nsCSSValue&
CSSFontFaceDescriptors::Get(nsCSSFontDesc aFontDescID)
{
MOZ_ASSERT(aFontDescID > eCSSFontDesc_UNKNOWN &&
aFontDescID < eCSSFontDesc_COUNT);
return this->*CSSFontFaceDescriptors::Fields[aFontDescID];
}
// QueryInterface implementation for nsCSSFontFaceStyleDecl
NS_INTERFACE_MAP_BEGIN(nsCSSFontFaceStyleDecl)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
@ -1435,7 +1451,7 @@ nsCSSFontFaceStyleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
if (aFontDescID == eCSSFontDesc_UNKNOWN)
return NS_OK;
const nsCSSValue& val = this->*nsCSSFontFaceStyleDecl::Fields[aFontDescID];
const nsCSSValue& val = mDescriptors.Get(aFontDescID);
if (val.GetUnit() == eCSSUnit_Null) {
// Avoid having to check no-value in the Family and Src cases below.
@ -1505,8 +1521,7 @@ nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
id < eCSSFontDesc_COUNT;
id = nsCSSFontDesc(id + 1)) {
if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
!= eCSSUnit_Null &&
if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null &&
NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
NS_ASSERTION(descStr.Length() > 0,
"GetCssText: non-null unit, empty property value");
@ -1568,7 +1583,7 @@ nsCSSFontFaceStyleDecl::RemoveProperty(const nsAString & propertyName,
} else {
nsresult rv = GetPropertyValue(descID, aResult);
NS_ENSURE_SUCCESS(rv, rv);
(this->*nsCSSFontFaceStyleDecl::Fields[descID]).Reset();
mDescriptors.Get(descID).Reset();
}
return NS_OK;
}
@ -1601,7 +1616,7 @@ nsCSSFontFaceStyleDecl::GetLength(uint32_t *aLength)
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
id < eCSSFontDesc_COUNT;
id = nsCSSFontDesc(id + 1))
if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null)
if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null)
len++;
*aLength = len;
@ -1627,8 +1642,7 @@ nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString &
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
id < eCSSFontDesc_COUNT;
id = nsCSSFontDesc(id + 1)) {
if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
!= eCSSUnit_Null) {
if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null) {
nset++;
if (nset == int32_t(index)) {
aFound = true;
@ -1744,8 +1758,7 @@ nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const
for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
id < eCSSFontDesc_COUNT;
id = nsCSSFontDesc(id + 1))
if ((mDecl.*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
!= eCSSUnit_Null) {
if (mDecl.mDescriptors.Get(id).GetUnit() != eCSSUnit_Null) {
if (NS_FAILED(mDecl.GetPropertyValue(id, descStr)))
descStr.AssignLiteral("#<serialization error>");
else if (descStr.Length() == 0)
@ -1824,7 +1837,7 @@ nsCSSFontFaceRule::SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue)
// FIXME: handle dynamic changes
mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID] = aValue;
mDecl.mDescriptors.Get(aDescID) = aValue;
}
void
@ -1834,7 +1847,7 @@ nsCSSFontFaceRule::GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue)
aDescID < eCSSFontDesc_COUNT,
"aDescID out of range in nsCSSFontFaceRule::GetDesc");
aValue = mDecl.*nsCSSFontFaceStyleDecl::Fields[aDescID];
aValue = mDecl.mDescriptors.Get(aDescID);
}
/* virtual */ size_t

Просмотреть файл

@ -180,6 +180,20 @@ protected:
};
} // namespace css
struct CSSFontFaceDescriptors
{
#define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_;
#include "nsCSSFontDescList.h"
#undef CSS_FONT_DESC
const nsCSSValue& Get(nsCSSFontDesc aFontDescID) const;
nsCSSValue& Get(nsCSSFontDesc aFontDescID);
private:
static nsCSSValue CSSFontFaceDescriptors::* const Fields[];
};
} // namespace mozilla
// A nsCSSFontFaceStyleDecl is always embedded in a nsCSSFontFaceRule.
@ -212,14 +226,12 @@ protected:
~nsCSSFontFaceStyleDecl() {}
friend class nsCSSFontFaceRule;
#define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_;
#include "nsCSSFontDescList.h"
#undef CSS_FONT_DESC
static nsCSSValue nsCSSFontFaceStyleDecl::* const Fields[];
inline nsCSSFontFaceRule* ContainingRule();
inline const nsCSSFontFaceRule* ContainingRule() const;
mozilla::CSSFontFaceDescriptors mDescriptors;
private:
// NOT TO BE IMPLEMENTED
// This object cannot be allocated on its own, only as part of

Просмотреть файл

@ -94,7 +94,7 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader)
nsITimer::TYPE_ONE_SHOT);
}
} else {
mUserFontEntry->mLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
}
mStreamLoader = aStreamLoader;
}
@ -114,7 +114,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
// If the entry is loading, check whether it's >75% done; if so,
// we allow another timeout period before showing a fallback font.
if (ufe->mLoadingState == gfxUserFontEntry::LOADING_STARTED) {
if (ufe->mFontDataLoadingState == gfxUserFontEntry::LOADING_STARTED) {
int64_t contentLength;
uint32_t numBytesRead;
if (NS_SUCCEEDED(loader->mChannel->GetContentLength(&contentLength)) &&
@ -126,7 +126,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
// More than 3/4 the data has been downloaded, so allow 50% extra
// time and hope the remainder will arrive before the additional
// time expires.
ufe->mLoadingState = gfxUserFontEntry::LOADING_ALMOST_DONE;
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_ALMOST_DONE;
uint32_t delay;
loader->mLoadTimer->GetDelay(&delay);
loader->mLoadTimer->InitWithFuncCallback(LoadTimerCallback,
@ -142,7 +142,7 @@ nsFontFaceLoader::LoadTimerCallback(nsITimer* aTimer, void* aClosure)
// before, we mark this entry as "loading slowly", so the fallback
// font will be used in the meantime, and tell the context to refresh.
if (updateUserFontSet) {
ufe->mLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
ufe->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;
gfxUserFontSet* fontSet = loader->mFontSet;
nsPresContext* ctx = loader->mFontSet->GetPresContext();
NS_ASSERTION(ctx, "userfontset doesn't have a presContext?");
@ -209,12 +209,12 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
// The userFontEntry is responsible for freeing the downloaded data
// (aString) when finished with it; the pointer is no longer valid
// after OnLoadComplete returns.
// after FontDataDownloadComplete returns.
// This is called even in the case of a failed download (HTTP 404, etc),
// as there may still be data to be freed (e.g. an error page),
// and we need the fontSet to initiate loading the next source.
bool fontUpdate = mUserFontEntry->OnLoadComplete(aString,
aStringLen, aStatus);
// and we need to load the next source.
bool fontUpdate =
mUserFontEntry->FontDataDownloadComplete(aString, aStringLen, aStatus);
// when new font loaded, need to reflow
if (fontUpdate) {
@ -237,7 +237,7 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
void
nsFontFaceLoader::Cancel()
{
mUserFontEntry->mLoadingState = gfxUserFontEntry::NOT_LOADING;
mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::NOT_LOADING;
mUserFontEntry->mLoader = nullptr;
mFontSet = nullptr;
if (mLoadTimer) {
@ -486,7 +486,7 @@ nsUserFontSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
}
if (modified) {
IncrementGeneration();
IncrementGeneration(true);
}
// local rules have been rebuilt, so clear the flag

Просмотреть файл

@ -500,7 +500,7 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
nsRefPtr<nsFontMetrics> fm =
GetMetricsFor(aPresContext, aStyleContext, styleFont,
aFontSize, aUseUserFontSet);
gfxFloat zeroWidth = (fm->GetThebesFontGroup()->GetFontAt(0)
gfxFloat zeroWidth = (fm->GetThebesFontGroup()->GetFirstValidFont()
->GetMetrics().zeroOrAveCharWidth);
return ScaleCoordRound(aValue, ceil(aPresContext->AppUnitsPerDevPixel() *

Просмотреть файл

@ -144,10 +144,10 @@ nsStyleContext::AssertStructsNotUsedElsewhere(
if (data && \
!(aDestroyingContext->mBits & NS_STYLE_INHERIT_BIT(name_)) && \
(mCachedInheritedData.mStyleStructs[eStyleStruct_##name_] == data)) { \
printf("style struct %p found on style context %p\n", data, this); \
printf_stderr("style struct %p found on style context %p\n", data, this);\
nsString url; \
PresContext()->Document()->GetURL(url); \
printf(" in %s\n", NS_LossyConvertUTF16toASCII(url).get()); \
printf_stderr(" in %s\n", NS_ConvertUTF16toUTF8(url).get()); \
MOZ_ASSERT(false, "destroying " #name_ " style struct still present " \
"in style context tree"); \
}
@ -168,10 +168,11 @@ nsStyleContext::AssertStructsNotUsedElsewhere(
if (data && \
!(aDestroyingContext->mBits & NS_STYLE_INHERIT_BIT(name_)) && \
(mCachedResetData->mStyleStructs[eStyleStruct_##name_] == data)) { \
printf("style struct %p found on style context %p\n", data, this); \
printf_stderr("style struct %p found on style context %p\n", data, \
this); \
nsString url; \
PresContext()->Document()->GetURL(url); \
printf(" in %s\n", NS_LossyConvertUTF16toASCII(url).get()); \
printf_stderr(" in %s\n", NS_ConvertUTF16toUTF8(url).get()); \
MOZ_ASSERT(false, "destroying " #name_ " style struct still present "\
"in style context tree"); \
}
@ -1033,6 +1034,20 @@ nsStyleContext::AssertStyleStructMaxDifferenceValid()
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
}
/* static */ const char*
nsStyleContext::StructName(nsStyleStructID aSID)
{
switch (aSID) {
#define STYLE_STRUCT(name_, checkdata_cb) \
case eStyleStruct_##name_: \
return #name_;
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
default:
return "Unknown";
}
}
#endif
bool

Просмотреть файл

@ -396,6 +396,7 @@ public:
#ifdef DEBUG
void List(FILE* out, int32_t aIndent);
static void AssertStyleStructMaxDifferenceValid();
static const char* StructName(nsStyleStructID aSID);
#endif
private:

Просмотреть файл

@ -2614,6 +2614,10 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
}
}
if (mMixBlendMode != aOther.mMixBlendMode) {
NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
}
/* If we've added or removed the transform property, we need to reconstruct the frame to add
* or remove the view object, and also to handle abs-pos and fixed-pos containers.
*/
@ -2711,7 +2715,6 @@ nsChangeHint nsStyleDisplay::CalcDifference(const nsStyleDisplay& aOther) const
(!mClip.IsEqualEdges(aOther.mClip) ||
mOriginalDisplay != aOther.mOriginalDisplay ||
mOriginalFloats != aOther.mOriginalFloats ||
mMixBlendMode != aOther.mMixBlendMode ||
mTransitions != aOther.mTransitions ||
mTransitionTimingFunctionCount !=
aOther.mTransitionTimingFunctionCount ||

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __ClearKeyDecryptor_h__
#define __ClearKeyDecryptor_h_
#define __ClearKeyDecryptor_h__
#include <map>
#include <string>

Просмотреть файл

@ -6,7 +6,7 @@
SharedLibrary('clearkey')
SOURCES += [
UNIFIED_SOURCES += [
'ClearKeyDecryptionManager.cpp',
'ClearKeySession.cpp',
'ClearKeyUtils.cpp',

Просмотреть файл

@ -7,4 +7,3 @@
]>
<iframe id="iframe" name="iframename" src="test2.xul"/>
</dialog>

Просмотреть файл

@ -113,7 +113,7 @@
// Shouldn't get any anonymized paths.
if (aPath.contains('<anonymized')) {
present.anonymizedWhenUnnecessary = true;
present.anonymizedWhenUnnecessary = aPath;
}
}
@ -122,12 +122,12 @@
{
// Shouldn't get http: or https: in any paths.
if (aPath.contains('http:')) {
present.httpWhenAnonymized = true;
present.httpWhenAnonymized = aPath;
}
// file: URLs should have their path anonymized.
if (aPath.search('file:..[^<]') !== -1) {
present.unanonymizedFilePathWhenAnonymized = true;
present.unanonymizedFilePathWhenAnonymized = aPath;
}
}
@ -230,10 +230,15 @@
ok(present.smallString1, "small string 1 is present");
ok(present.smallString2, "small string 2 is present");
ok(!present.anonymizedWhenUnnecessary, "anonymized paths are not present when unnecessary");
ok(!present.httpWhenAnonymized, "http URLs are anonymized when necessary");
ok(!present.anonymizedWhenUnnecessary,
"anonymized paths are not present when unnecessary. Failed case: " +
present.anonymizedWhenUnnecessary);
ok(!present.httpWhenAnonymized,
"http URLs are anonymized when necessary. Failed case: " +
present.httpWhenAnonymized);
ok(!present.unanonymizedFilePathWhenAnonymized,
"file URLs are anonymized when necessary");
"file URLs are anonymized when necessary. Failed case: " +
present.unanonymizedFilePathWhenAnonymized);
// Reporter registration tests

Просмотреть файл

@ -1517,6 +1517,7 @@ DumpHelp()
printf(" -h or -help Print this message.\n"
" -v or -version Print %s version.\n"
" -P <profile> Start with <profile>.\n"
" -profile <path> Start with profile at <path>.\n"
" -migration Start with migration wizard.\n"
" -ProfileManager Start with ProfileManager.\n"
" -no-remote Do not accept or send remote commands; implies -new-instance.\n"

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше