Merge last green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2011-11-18 08:43:10 +00:00
commit aa5192da19
111 changed files with 2036 additions and 696 deletions

View File

@ -592,8 +592,8 @@ NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
if (aThisEvent->mPackedEvent) {
aThisEvent->mPackedEvent->mEventType =
aThisEvent->mPackedEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_ADD) :
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_REMOVE);
nsIAccessibleEvent::EVENT_SELECTION_ADD :
nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
aThisEvent->mPackedEvent->mEventRule =
AccEvent::eCoalesceSelectionChange;
@ -603,8 +603,8 @@ NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
aThisEvent->mEventType =
aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_ADD) :
static_cast<PRUint32>(nsIAccessibleEvent::EVENT_SELECTION_REMOVE);
nsIAccessibleEvent::EVENT_SELECTION_ADD :
nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
return;
}

View File

@ -440,7 +440,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates
kNoReqStates,
eARIAOrientation
},
{
"slider",
@ -450,6 +451,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
eARIAOrientation,
eARIAReadonly
},
{
@ -649,8 +651,8 @@ nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
// eARIAOrientation
nsStateMapEntry(&nsGkAtoms::aria_orientation, eUseFirstState,
"vertical", states::VERTICAL,
"horizontal", states::HORIZONTAL),
"horizontal", states::HORIZONTAL,
"vertical", states::VERTICAL),
// eARIAPressed
nsStateMapEntry(&nsGkAtoms::aria_pressed, kMixedType,

View File

@ -191,7 +191,7 @@ __try {
if (aTargetIndex < 0 || aTargetIndex >= mTargets.Length() || !aTarget)
return E_INVALIDARG;
mTargets[aTargetIndex]->QueryInterface((const nsID&) IID_IUnknown, (void**) aTarget);
mTargets[aTargetIndex]->QueryNativeInterface(IID_IUnknown, (void**) aTarget);
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

View File

@ -124,10 +124,16 @@
testStates("aria_main_anchor", STATE_SELECTABLE);
testStates("aria_navigation_anchor", STATE_SELECTABLE);
// scrollbar
testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL);
// aria-orientation (applied to scrollbar, separator, slider)
testStates("aria_scrollbar", 0, EXT_STATE_HORIZONTAL);
testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL);
testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL);
testStates("aria_separator", 0, EXT_STATE_HORIZONTAL);
testStates("aria_hseparator", 0, EXT_STATE_HORIZONTAL);
testStates("aria_vseparator", 0, EXT_STATE_VERTICAL);
testStates("aria_slider", 0, EXT_STATE_HORIZONTAL);
testStates("aria_hslider", 0, EXT_STATE_HORIZONTAL);
testStates("aria_vslider", 0, EXT_STATE_VERTICAL);
SimpleTest.finish();
}
@ -160,6 +166,11 @@
title="aria-autocomplete not supported on standard form text input controls">
Mozilla Bug 681674
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674"
title="aria-orientation should be applied to separator and slider roles">
Mozilla Bug 681674
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
@ -227,9 +238,15 @@
<a id="aria_main_anchor" role="main" name="main_anchor">main</a>
<a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
<!-- scrollbar -->
<div id="aria_scrollbar" role="scrollbar">scrollbar</a>
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</a>
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</a>
<!-- aria-orientation -->
<div id="aria_scrollbar" role="scrollbar">scrollbar</div>
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</div>
<div id="aria_separator" role="separator">separator</div>
<div id="aria_hseparator" role="separator" aria-orientation="horizontal">horizontal separator</div>
<div id="aria_vseparator" role="separator" aria-orientation="vertical">vertical separator</div>
<div id="aria_slider" role="slider">slider</div>
<div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div>
<div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div>
</body>
</html>

View File

@ -36,9 +36,9 @@
#
# ***** END LICENSE BLOCK *****
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
// Bug 671101 - directly using webNavigation in this context
// causes docshells to leak

View File

@ -260,10 +260,10 @@ var gTests = [
function nextTest() {
if (gTests.length) {
var test = gTests.shift();
info("Start of test: " + test.desc);
test.run();
waitForFocus(nextTest);
waitForFocus(function() {
info("Start of test: " + test.desc);
test.run();
});
}
else {
// Collapse the personal toolbar if needed.
@ -283,6 +283,6 @@ function test() {
if (wasCollapsed)
setToolbarVisibility(toolbar, true);
waitForFocus(nextTest);
nextTest();
}

View File

@ -36,7 +36,7 @@
"use strict";
const Cu = Components.utils;
let Cu = Components.utils;
Cu.import("resource:///modules/tabview/utils.jsm");

View File

@ -8428,7 +8428,7 @@ nsIDocument::SizeOf() const
}
static void
DispatchFullScreenChange(nsINode* aTarget)
DispatchFullScreenChange(nsIDocument* aTarget)
{
nsRefPtr<nsPLDOMEvent> e =
new nsPLDOMEvent(aTarget,
@ -8652,7 +8652,7 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
// element, and the full-screen-ancestor styles on ancestors of the element
// in this document.
if (SetFullScreenState(aElement, true)) {
DispatchFullScreenChange(aElement);
DispatchFullScreenChange(aElement->OwnerDoc());
}
// Propagate up the document hierarchy, setting the full-screen element as
@ -8665,7 +8665,7 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
while ((parent = child->GetParentDocument())) {
Element* element = parent->FindContentForSubDocument(child)->AsElement();
if (::SetFullScreenState(parent, element, true)) {
DispatchFullScreenChange(element);
DispatchFullScreenChange(element->OwnerDoc());
}
child = parent;
}

View File

@ -131,6 +131,8 @@ public:
ViewConfig aConfig = ViewConfig())
: mViewportSize(0, 0)
, mContentSize(0, 0)
, mParentScaleX(1.0)
, mParentScaleY(1.0)
, mFrameLoader(aFrameLoader)
, mScrollId(aScrollId)
, mConfig(aConfig)
@ -150,6 +152,8 @@ public:
nsSize mViewportSize;
nsSize mContentSize;
float mParentScaleX;
float mParentScaleY;
nsFrameLoader* mFrameLoader; // WEAK

View File

@ -116,6 +116,7 @@
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/Preferences.h"
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
@ -989,9 +990,10 @@ nsresult
NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
{
#ifdef XP_WIN
if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
if ((gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
gfxWindowsPlatform::RENDER_DIRECT2D ||
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) &&
!Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
return NS_ERROR_NOT_AVAILABLE;
}
#elif !defined(XP_MACOSX) && !defined(ANDROID)

View File

@ -29,6 +29,18 @@ function IsAzureEnabled() {
return enabled;
}
function IsAzureSkia() {
var enabled = false;
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var backend = Components.classes["@mozilla.org/gfx/info;1"].getService(Components.interfaces.nsIGfxInfo).getInfo().AzureBackend;
enabled = (backend == "skia");
} catch (e) { }
return enabled;
}
</script>
<!-- Includes all the tests in the content/canvas/tests except for test_bug397524.html -->
@ -11985,7 +11997,7 @@ isPixel(ctx, 65,21, 0,255,0,255, 0);
isPixel(ctx, 72,28, 0,255,0,255, 0);
isPixel(ctx, 73,27, 0,255,0,255, 0);
isPixel(ctx, 78,36, 0,255,0,255, 0);
isPixel(ctx, 79,35, 0,255,0,255, 0);
isPixel(ctx, 79,35, 0,255,0,255, IsAzureSkia() ? 1 : 0);
isPixel(ctx, 80,44, 0,255,0,255, 0);
isPixel(ctx, 80,45, 0,255,0,255, 0);
isPixel(ctx, 80,46, 0,255,0,255, 0);
@ -12032,11 +12044,11 @@ isPixel(ctx, 50,25, 0,255,0,255, 0);
isPixel(ctx, 55,19, 0,255,0,255, 0);
isPixel(ctx, 55,20, 0,255,0,255, 0);
isPixel(ctx, 55,21, 0,255,0,255, 0);
isPixel(ctx, 64,22, 0,255,0,255, 0);
isPixel(ctx, 64,22, 0,255,0,255, IsAzureSkia() ? 1 : 0);
isPixel(ctx, 65,21, 0,255,0,255, 0);
isPixel(ctx, 72,28, 0,255,0,255, 0);
isPixel(ctx, 73,27, 0,255,0,255, 0);
isPixel(ctx, 78,36, 0,255,0,255, 0);
isPixel(ctx, 73,27, 0,255,0,255, IsAzureSkia() ? 1 : 0);
isPixel(ctx, 78,36, 0,255,0,255, IsAzureSkia() ? 1 : 0);
isPixel(ctx, 79,35, 0,255,0,255, 0);
isPixel(ctx, 80,44, 0,255,0,255, 0);
isPixel(ctx, 80,45, 0,255,0,255, 0);
@ -14339,8 +14351,11 @@ ctx.lineTo(50, 25);
ctx.closePath();
ctx.stroke();
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
if (IsAzureEnabled() && IsAzureSkia()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
}
</script>
@ -14412,7 +14427,11 @@ ctx.moveTo(50, 25);
ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
ctx.stroke();
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
if (IsAzureEnabled() && IsAzureSkia()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
}
@ -14445,8 +14464,11 @@ ctx.moveTo(50, 25);
ctx.lineTo(50, 25);
ctx.stroke();
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
if (IsAzureEnabled() && IsAzureSkia()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
}
</script>
@ -14479,8 +14501,11 @@ ctx.stroke();
ctx.strokeRect(50, 25, 0, 0);
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
if (IsAzureEnabled() && IsAzureSkia()) {
isPixel(ctx, 50,25, 0,255,0,255, 0);
} else {
todo_isPixel(ctx, 50,25, 0,255,0,255, 0);
}
}
</script>
@ -19185,7 +19210,7 @@ isPixel(ctx, 21,11, 0,255,0,255, 0);
isPixel(ctx, 79,11, 0,255,0,255, 0);
isPixel(ctx, 21,39, 0,255,0,255, 0);
isPixel(ctx, 79,39, 0,255,0,255, 0);
isPixel(ctx, 39,19, 0,255,0,255, 0);
isPixel(ctx, 39,19, 0,255,0,255, IsAzureSkia() ? 1 : 0);
isPixel(ctx, 61,19, 0,255,0,255, 0);
isPixel(ctx, 39,31, 0,255,0,255, 0);
isPixel(ctx, 61,31, 0,255,0,255, 0);
@ -19393,7 +19418,7 @@ isPixel(ctx, 21,11, 0,255,0,255, 0);
isPixel(ctx, 79,11, 0,255,0,255, 0);
isPixel(ctx, 21,39, 0,255,0,255, 0);
isPixel(ctx, 79,39, 0,255,0,255, 0);
isPixel(ctx, 39,19, 0,255,0,255, 0);
isPixel(ctx, 39,19, 0,255,0,255, IsAzureSkia() ? 1 : 0);
isPixel(ctx, 61,19, 0,255,0,255, 0);
isPixel(ctx, 39,31, 0,255,0,255, 0);
isPixel(ctx, 61,31, 0,255,0,255, 0);

View File

@ -65,7 +65,7 @@ function fullScreenChange(event) {
switch (fullScreenChangeCount) {
case 0: {
ok(document.mozFullScreen, "Should be in full-screen mode (first time)");
is(event.target, fullScreenElement(), "Event target should be full-screen element");
is(event.target, document, "Event target should be full-screen document #1");
is(document.mozFullScreenElement, fullScreenElement(),
"Full-screen element should be div element.");
ok(document.mozFullScreenElement.mozMatchesSelector(":-moz-full-screen"),
@ -83,7 +83,7 @@ function fullScreenChange(event) {
}
case 1: {
ok(!document.mozFullScreen, "Should have left full-screen mode (first time)");
is(event.target, document, "Event target should be document when we exit via removing from doc");
is(event.target, document, "Event target should be full-screen document #2");
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
iframe = document.createElement("iframe");
iframe.mozAllowFullScreen = true;
@ -93,8 +93,7 @@ function fullScreenChange(event) {
}
case 2: {
ok(document.mozFullScreen, "Should be back in full-screen mode (second time)");
is(event.target, iframe,
"Event target should be full-screen element container");
is(event.target, document, "Event target should be full-screen document #3");
is(document.mozFullScreenElement, iframe,
"Full-screen element should be iframe element.");
@ -126,8 +125,7 @@ function fullScreenChange(event) {
}
case 3: {
ok(!document.mozFullScreen, "Should be back in non-full-screen mode (second time)");
is(event.target, document,
"Event target should be full-screen element container");
is(event.target, document, "Event target should be full-screen document #4");
is(document.mozFullScreenElement, null, "Full-screen element should be null.");
document.body.removeChild(iframe);
iframe = null;
@ -155,7 +153,7 @@ function fullScreenChange(event) {
}
case 4: {
ok(document.mozFullScreen, "Should still be in full-screen mode (third time)");
is(event.target, inDocElement, "Event target should be inDocElement");
is(event.target, document, "Event target should be full-screen document #5");
ok(fullScreenErrorRun, "Should have run fullscreenerror handler from previous case.");
is(document.mozFullScreenElement, inDocElement,
"FSE should be inDocElement.");

View File

@ -137,36 +137,6 @@ GfxOpToSkiaOp(CompositionOp op)
return SkXfermode::kSrcOver_Mode;
}
SkPaint::Cap
CapStyleToSkiaCap(CapStyle aCap)
{
switch (aCap)
{
case CAP_BUTT:
return SkPaint::kButt_Cap;
case CAP_ROUND:
return SkPaint::kRound_Cap;
case CAP_SQUARE:
return SkPaint::kSquare_Cap;
}
return SkPaint::kDefault_Cap;
}
SkPaint::Join
JoinStyleToSkiaJoin(JoinStyle aJoin)
{
switch (aJoin)
{
case JOIN_BEVEL:
return SkPaint::kBevel_Join;
case JOIN_ROUND:
return SkPaint::kRound_Join;
case JOIN_MITER:
case JOIN_MITER_OR_BEVEL:
return SkPaint::kMiter_Join;
}
return SkPaint::kDefault_Join;
}
SkRect
RectToSkRect(const Rect& aRect)
@ -201,7 +171,14 @@ DrawTargetSkia::DrawTargetSkia()
DrawTargetSkia::~DrawTargetSkia()
{
MarkChanged();
if (mSnapshots.size()) {
for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
iter != mSnapshots.end(); iter++) {
(*iter)->DrawTargetDestroyed();
}
// All snapshots will now have copied data.
mSnapshots.clear();
}
}
TemporaryRef<SourceSurface>
@ -280,6 +257,7 @@ struct AutoPaintSetup {
mPaint.setAlpha(aOptions.mAlpha*255.0);
mAlpha = aOptions.mAlpha;
}
mPaint.setFilterBitmap(true);
}
void SetPattern(const Pattern& aPattern)
@ -336,27 +314,6 @@ struct AutoPaintSetup {
}
}
void SetStroke(const StrokeOptions &aOptions)
{
mPaint.setStrokeWidth(SkFloatToScalar(aOptions.mLineWidth));
mPaint.setStrokeMiter(SkFloatToScalar(aOptions.mMiterLimit));
mPaint.setStrokeCap(CapStyleToSkiaCap(aOptions.mLineCap));
mPaint.setStrokeJoin(JoinStyleToSkiaJoin(aOptions.mLineJoin));
if (aOptions.mDashLength) {
std::vector<SkScalar> pattern;
pattern.resize(aOptions.mDashLength);
for (uint32_t i = 0; i < aOptions.mDashLength; i++) {
pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i]);
}
SkDashPathEffect* dash = new SkDashPathEffect(&pattern.front(),
aOptions.mDashLength,
SkFloatToScalar(aOptions.mDashOffset));
SkSafeUnref(mPaint.setPathEffect(dash));
}
mPaint.setStyle(SkPaint::kStroke_Style);
}
// TODO: Maybe add an operator overload to access this easier?
SkPaint mPaint;
bool mNeedsRestore;
@ -386,7 +343,6 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
MarkChanged();
NS_ASSERTION(aSurfOptions.mFilter == FILTER_LINEAR, "Only linear filtering supported currently!");
SkRect destRect = RectToSkRect(aDest);
SkRect sourceRect = RectToSkRect(aSource);
@ -399,6 +355,9 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
SkShader *shader = SkShader::CreateBitmapShader(bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
shader->setLocalMatrix(matrix);
SkSafeUnref(paint.mPaint.setShader(shader));
if (aSurfOptions.mFilter != FILTER_LINEAR) {
paint.mPaint.setFilterBitmap(false);
}
mCanvas->drawRect(destRect, paint.mPaint);
}
@ -492,7 +451,9 @@ DrawTargetSkia::Stroke(const Path *aPath,
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
paint.SetStroke(aStrokeOptions);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return;
}
mCanvas->drawPath(skiaPath->GetPath(), paint.mPaint);
}
@ -505,7 +466,9 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
{
MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
paint.SetStroke(aStrokeOptions);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return;
}
mCanvas->drawRect(RectToSkRect(aRect), paint.mPaint);
}
@ -519,7 +482,9 @@ DrawTargetSkia::StrokeLine(const Point &aStart,
{
MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern);
paint.SetStroke(aStrokeOptions);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return;
}
mCanvas->drawLine(SkFloatToScalar(aStart.x), SkFloatToScalar(aStart.y),
SkFloatToScalar(aEnd.x), SkFloatToScalar(aEnd.y),

View File

@ -46,6 +46,9 @@
#ifdef XP_MACOSX
#include "ScaledFontMac.h"
#endif
#ifdef WIN32
#include "ScaledFontWin.h"
#endif
#include "ScaledFontSkia.h"
#endif
@ -124,6 +127,12 @@ Factory::CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSiz
{
return new ScaledFontMac(static_cast<CGFontRef>(aNativeFont.mFont), aSize);
}
#endif
#ifdef WIN32
case NATIVE_FONT_GDI_FONT_FACE:
{
return new ScaledFontWin(static_cast<gfxGDIFont*>(aNativeFont.mFont), aSize);
}
#endif
case NATIVE_FONT_SKIA_FONT_FACE:
{

View File

@ -40,6 +40,7 @@
#include "2D.h"
#include "skia/SkCanvas.h"
#include "skia/SkDashPathEffect.h"
namespace mozilla {
namespace gfx {
@ -72,6 +73,65 @@ GfxMatrixToSkiaMatrix(const Matrix& mat, SkMatrix& retval)
0, 0, SK_Scalar1);
}
static inline SkPaint::Cap
CapStyleToSkiaCap(CapStyle aCap)
{
switch (aCap)
{
case CAP_BUTT:
return SkPaint::kButt_Cap;
case CAP_ROUND:
return SkPaint::kRound_Cap;
case CAP_SQUARE:
return SkPaint::kSquare_Cap;
}
return SkPaint::kDefault_Cap;
}
static inline SkPaint::Join
JoinStyleToSkiaJoin(JoinStyle aJoin)
{
switch (aJoin)
{
case JOIN_BEVEL:
return SkPaint::kBevel_Join;
case JOIN_ROUND:
return SkPaint::kRound_Join;
case JOIN_MITER:
case JOIN_MITER_OR_BEVEL:
return SkPaint::kMiter_Join;
}
return SkPaint::kDefault_Join;
}
static inline bool
StrokeOptionsToPaint(SkPaint& aPaint, const StrokeOptions &aOptions)
{
// Skia rendewrs 0 width strokes with a width of 1 (and in black),
// so we should just skip the draw call entirely.
if (!aOptions.mLineWidth) {
return false;
}
aPaint.setStrokeWidth(SkFloatToScalar(aOptions.mLineWidth));
aPaint.setStrokeMiter(SkFloatToScalar(aOptions.mMiterLimit));
aPaint.setStrokeCap(CapStyleToSkiaCap(aOptions.mLineCap));
aPaint.setStrokeJoin(JoinStyleToSkiaJoin(aOptions.mLineJoin));
if (aOptions.mDashLength > 1) {
std::vector<SkScalar> pattern;
pattern.resize(aOptions.mDashLength);
for (uint32_t i = 0; i < aOptions.mDashLength; i++) {
pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i]);
}
SkDashPathEffect* dash = new SkDashPathEffect(&pattern.front(),
aOptions.mDashLength,
SkFloatToScalar(aOptions.mDashOffset));
SkSafeUnref(aPaint.setPathEffect(dash));
}
aPaint.setStyle(SkPaint::kStroke_Style);
return true;
}
}
}

View File

@ -107,9 +107,13 @@ CPPSRCS += \
SourceSurfaceD2DTarget.cpp \
PathD2D.cpp \
ScaledFontDWrite.cpp \
$(NULL)
DEFINES += -DWIN32
SourceSurfaceSkia.cpp \
DrawTargetSkia.cpp \
PathSkia.cpp \
ScaledFontSkia.cpp \
ScaledFontWin.cpp \
$(NULL)
DEFINES += -DWIN32 -DUSE_SKIA
endif
#ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)

View File

@ -196,8 +196,14 @@ Rect
PathSkia::GetStrokedBounds(const StrokeOptions &aStrokeOptions,
const Matrix &aTransform) const
{
NS_ASSERTION(false, "GetStrokedBounds not supported yet!");
return Rect(0, 0, 0, 0);
SkPaint paint;
StrokeOptionsToPaint(paint, aStrokeOptions);
SkPath result;
paint.getFillPath(mPath, &result);
Rect bounds = SkRectToRect(result.getBounds());
return aTransform.TransformBounds(bounds);
}
}

53
gfx/2d/ScaledFontWin.cpp Normal file
View File

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Castelluccio <mar.castelluccio@studenti.unina.it>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ScaledFontWin.h"
#include "skia/SkTypeface_win.h"
namespace mozilla {
namespace gfx {
ScaledFontWin::ScaledFontWin(gfxGDIFont* aFont, Float aSize)
: ScaledFontSkia(aSize)
{
LOGFONT lf;
GetObject(aFont->GetHFONT(), sizeof(LOGFONT), &lf);
mTypeface = SkCreateTypefaceFromLOGFONT(lf);
}
}
}

61
gfx/2d/ScaledFontWin.h Normal file
View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Corporation code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Castelluccio <mar.castelluccio@studenti.unina.it>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef MOZILLA_GFX_SCALEDFONTWIN_H_
#define MOZILLA_GFX_SCALEDFONTWIN_H_
#include "ScaledFontSkia.h"
#include "gfxGDIFont.h"
namespace mozilla {
namespace gfx {
class ScaledFontWin : public ScaledFontSkia
{
public:
ScaledFontWin(gfxGDIFont* aFont, Float aSize);
virtual FontType GetType() const { return FONT_GDI; }
private:
friend class DrawTargetSkia;
};
}
}
#endif /* MOZILLA_GFX_SCALEDFONTWIN_H_ */

View File

@ -129,6 +129,12 @@ SourceSurfaceSkia::DrawTargetWillChange()
}
}
void
SourceSurfaceSkia::DrawTargetDestroyed()
{
mDrawTarget = NULL;
}
void
SourceSurfaceSkia::MarkIndependent()
{
@ -138,6 +144,5 @@ SourceSurfaceSkia::MarkIndependent()
}
}
}
}

View File

@ -82,6 +82,7 @@ private:
friend class DrawTargetSkia;
void DrawTargetWillChange();
void DrawTargetDestroyed();
void MarkIndependent();
SkBitmap mBitmap;

View File

@ -43,7 +43,7 @@
namespace mozilla {
namespace gfx {
bool
static inline bool
IsOperatorBoundByMask(CompositionOp aOp) {
switch (aOp) {
case OP_IN:

View File

@ -91,6 +91,7 @@ enum BackendType
enum FontType
{
FONT_DWRITE,
FONT_GDI,
FONT_MAC,
FONT_SKIA
};
@ -103,6 +104,7 @@ enum NativeSurfaceType
enum NativeFontType
{
NATIVE_FONT_DWRITE_FONT_FACE,
NATIVE_FONT_GDI_FONT_FACE,
NATIVE_FONT_MAC_FONT_FACE,
NATIVE_FONT_SKIA_FONT_FACE
};

View File

@ -50,7 +50,7 @@ endif
DIRS += 2d ycbcr angle src qcms layers harfbuzz/src ots/src thebes ipc
ifeq (,$(filter-out cocoa android,$(MOZ_WIDGET_TOOLKIT)))
ifeq (,$(filter-out cocoa android windows,$(MOZ_WIDGET_TOOLKIT)))
DIRS += skia
endif

View File

@ -4797,3 +4797,29 @@ cairo_d2d_get_surface_vram_usage(cairo_device_t *device)
cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
return d2d_device->mVRAMUsage;
}
int
cairo_d2d_surface_get_width(cairo_surface_t *surface)
{
if (surface->backend != &cairo_d2d_surface_backend) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
return size.width;
}
int
cairo_d2d_surface_get_height(cairo_surface_t *surface)
{
if (surface->backend != &cairo_d2d_surface_backend) {
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
return 0;
}
cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
return size.height;
}

View File

@ -3910,3 +3910,23 @@ cairo_win32_surface_get_can_convert_to_dib (cairo_surface_t *asurface, cairo_boo
*can_convert = ((surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0);
return CAIRO_STATUS_SUCCESS;
}
int
cairo_win32_surface_get_width (cairo_surface_t *asurface)
{
cairo_win32_surface_t *surface = (cairo_win32_surface_t*) asurface;
if (surface->base.type != CAIRO_SURFACE_TYPE_WIN32)
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
return surface->extents.width;
}
int
cairo_win32_surface_get_height (cairo_surface_t *asurface)
{
cairo_win32_surface_t *surface = (cairo_win32_surface_t*) asurface;
if (surface->base.type != CAIRO_SURFACE_TYPE_WIN32)
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
return surface->extents.height;
}

View File

@ -82,6 +82,12 @@ cairo_win32_surface_get_can_convert_to_dib (cairo_surface_t *surface, cairo_bool
BYTE cairo_win32_get_system_text_quality (void);
cairo_public int
cairo_win32_surface_get_width (cairo_surface_t *surface);
cairo_public int
cairo_win32_surface_get_height (cairo_surface_t *surface);
#if CAIRO_HAS_WIN32_FONT
/*
@ -309,6 +315,16 @@ int cairo_d2d_get_image_surface_cache_usage();
* cache.
*/
int cairo_d2d_get_surface_vram_usage(cairo_device_t *device);
/**
* Get the width of the surface.
*/
int cairo_d2d_surface_get_width(cairo_surface_t *surface);
/**
* Get the height of the surface.
*/
int cairo_d2d_surface_get_height(cairo_surface_t *surface);
#endif
CAIRO_END_DECLS

View File

@ -62,7 +62,11 @@ CanvasLayerD3D9::Initialize(const Data& aData)
{
NS_ASSERTION(mSurface == nsnull, "BasicCanvasLayer::Initialize called twice!");
if (aData.mSurface) {
if (aData.mDrawTarget) {
mDrawTarget = aData.mDrawTarget;
mNeedsYFlip = false;
mDataIsPremultiplied = true;
} else if (aData.mSurface) {
mSurface = aData.mSurface;
NS_ASSERTION(aData.mGLContext == nsnull,
"CanvasLayer can't have both surface and GLContext");
@ -75,7 +79,7 @@ CanvasLayerD3D9::Initialize(const Data& aData)
mDataIsPremultiplied = aData.mGLBufferIsPremultiplied;
mNeedsYFlip = true;
} else {
NS_ERROR("CanvasLayer created without mSurface or mGLContext?");
NS_ERROR("CanvasLayer created without mSurface, mGLContext or mDrawTarget?");
}
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
@ -150,7 +154,7 @@ CanvasLayerD3D9::UpdateSurface()
}
delete [] destination;
}
} else if (mSurface) {
} else {
RECT r;
r.left = mBounds.x;
r.top = mBounds.y;
@ -166,11 +170,18 @@ CanvasLayerD3D9::UpdateSurface()
D3DLOCKED_RECT lockedRect = textureLock.GetLockRect();
nsRefPtr<gfxImageSurface> sourceSurface;
nsRefPtr<gfxASurface> tempSurface;
if (mDrawTarget) {
tempSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
}
else {
tempSurface = mSurface;
}
if (mSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
sourceSurface = mSurface->GetAsImageSurface();
} else if (mSurface->GetType() == gfxASurface::SurfaceTypeImage) {
sourceSurface = static_cast<gfxImageSurface*>(mSurface.get());
if (tempSurface->GetType() == gfxASurface::SurfaceTypeWin32) {
sourceSurface = tempSurface->GetAsImageSurface();
} else if (tempSurface->GetType() == gfxASurface::SurfaceTypeImage) {
sourceSurface = static_cast<gfxImageSurface*>(tempSurface.get());
if (sourceSurface->Format() != gfxASurface::ImageFormatARGB32 &&
sourceSurface->Format() != gfxASurface::ImageFormatRGB24)
{

View File

@ -85,6 +85,7 @@ protected:
nsRefPtr<gfxASurface> mSurface;
nsRefPtr<GLContext> mGLContext;
nsRefPtr<IDirect3DTexture9> mTexture;
RefPtr<gfx::DrawTarget> mDrawTarget;
PRUint32 mCanvasFramebuffer;

View File

@ -58,6 +58,7 @@ LOCAL_INCLUDES += \
-I$(srcdir)/src/core \
-I$(srcdir)/include/images \
-I$(srcdir)/include/utils/mac \
-I$(srcdir)/include/utils/win \
-I$(srcdir)/include/views \
-I$(srcdir)/include/effects \
$(NULL)
@ -172,7 +173,6 @@ EXPORTS_skia = \
include/effects/SkLayerDrawLooper.h \
include/effects/SkLayerRasterizer.h \
include/effects/SkDashPathEffect.h \
include/ports/SkTypeface_mac.h \
$(NULL)
DEFINES += -DUSE_SKIA
@ -230,7 +230,6 @@ CPPSRCS = \
SkGlyphCache.cpp \
SkGraphics.cpp \
SkLineClipper.cpp \
SkMMapStream.cpp \
SkMallocPixelRef.cpp \
SkMask.cpp \
SkMaskFilter.cpp \
@ -286,7 +285,6 @@ CPPSRCS = \
SkGlobals_global.cpp \
SkOSFile_stdio.cpp \
SkThread_none.cpp \
SkTime_Unix.cpp \
SkGradientShader.cpp \
SkBitmapCache.cpp \
SkBlurDrawLooper.cpp \
@ -308,6 +306,7 @@ CPPSRCS += \
SkBlitRow_opts_SSE2.cpp \
SkUtils_opts_SSE2.cpp \
opts_check_SSE2.cpp \
SkTime_Unix.cpp \
$(NULL)
endif
@ -319,10 +318,27 @@ CPPSRCS += \
SkFontHost_android.cpp \
SkFontHost_gamma.cpp \
SkUtils_opts_none.cpp \
SkMMapStream.cpp \
SkTime_Unix.cpp \
$(NULL)
DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
endif
ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
EXPORTS_skia += \
include/config/sk_stdint.h \
include/ports/SkTypeface_win.h \
$(NULL)
CPPSRCS += \
SkFontHost_win.cpp \
SkTime_win.cpp \
SkBitmapProcState_opts_SSE2.cpp \
SkBlitRow_opts_SSE2.cpp \
SkUtils_opts_SSE2.cpp \
opts_check_SSE2.cpp \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

View File

@ -145,6 +145,8 @@
//#define SK_SUPPORT_UNITTEST
#endif
#define SK_DISABLE_DITHER_32BIT_GRADIENT
/* If your system embeds skia and has complex event logging, define this
symbol to name a file that maps the following macros to your system's
equivalents:
@ -166,4 +168,8 @@
#define SK_A32_SHIFT 24
#endif
#ifdef SK_BUILD_FOR_WIN32
#define SK_IGNORE_STDINT_DOT_H
#endif
#endif

View File

@ -0,0 +1,463 @@
diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
--- a/gfx/skia/src/effects/SkGradientShader.cpp
+++ b/gfx/skia/src/effects/SkGradientShader.cpp
@@ -1170,117 +1170,18 @@ public:
fRadius(radius)
{
// make sure our table is insync with our current #define for kSQRT_TABLE_SIZE
SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE);
rad_to_unit_matrix(center, radius, &fPtsToUnit);
}
- virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count);
- virtual void shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) {
- SkASSERT(count > 0);
-
- SkPoint srcPt;
- SkMatrix::MapXYProc dstProc = fDstToIndexProc;
- TileProc proc = fTileProc;
- const uint16_t* SK_RESTRICT cache = this->getCache16();
- int toggle = ((x ^ y) & 1) << kCache16Bits;
-
- if (fDstToIndexClass != kPerspective_MatrixClass) {
- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
- SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
-
- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
- SkFixed storage[2];
- (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
- dx = storage[0];
- dy = storage[1];
- } else {
- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = SkScalarToFixed(fDstToIndex.getScaleX());
- dy = SkScalarToFixed(fDstToIndex.getSkewY());
- }
-
- if (proc == clamp_tileproc) {
- const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
-
- /* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
- rather than 0xFFFF which is slower. This is a compromise, since it reduces our
- precision, but that appears to be visually OK. If we decide this is OK for
- all of our cases, we could (it seems) put this scale-down into fDstToIndex,
- to avoid having to do these extra shifts each time.
- */
- fx >>= 1;
- dx >>= 1;
- fy >>= 1;
- dy >>= 1;
- if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
- fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
- fy *= fy;
- do {
- unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
- unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
- fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
- fx += dx;
- *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
- toggle ^= (1 << kCache16Bits);
- } while (--count != 0);
- } else {
- do {
- unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
- unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
- fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
- fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
- fx += dx;
- fy += dy;
- *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
- toggle ^= (1 << kCache16Bits);
- } while (--count != 0);
- }
- } else if (proc == mirror_tileproc) {
- do {
- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
- unsigned fi = mirror_tileproc(dist);
- SkASSERT(fi <= 0xFFFF);
- fx += dx;
- fy += dy;
- *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
- toggle ^= (1 << kCache16Bits);
- } while (--count != 0);
- } else {
- SkASSERT(proc == repeat_tileproc);
- do {
- SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
- unsigned fi = repeat_tileproc(dist);
- SkASSERT(fi <= 0xFFFF);
- fx += dx;
- fy += dy;
- *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
- toggle ^= (1 << kCache16Bits);
- } while (--count != 0);
- }
- } else { // perspective case
- SkScalar dstX = SkIntToScalar(x);
- SkScalar dstY = SkIntToScalar(y);
- do {
- dstProc(fDstToIndex, dstX, dstY, &srcPt);
- unsigned fi = proc(SkScalarToFixed(srcPt.length()));
- SkASSERT(fi <= 0xFFFF);
-
- int index = fi >> (16 - kCache16Bits);
- *dstC++ = cache[toggle + index];
- toggle ^= (1 << kCache16Bits);
-
- dstX += SK_Scalar1;
- } while (--count != 0);
- }
- }
+ virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
+ virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
virtual BitmapType asABitmap(SkBitmap* bitmap,
SkMatrix* matrix,
TileMode* xy,
SkScalar* twoPointRadialParams) const {
if (bitmap) {
this->commonAsABitmap(bitmap);
}
@@ -1494,16 +1395,117 @@ void Radial_Gradient::shadeSpan(int x, i
unsigned fi = proc(SkScalarToFixed(srcPt.length()));
SkASSERT(fi <= 0xFFFF);
*dstC++ = cache[fi >> (16 - kCache32Bits)];
dstX += SK_Scalar1;
} while (--count != 0);
}
}
+void Radial_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) {
+ SkASSERT(count > 0);
+
+ SkPoint srcPt;
+ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+ TileProc proc = fTileProc;
+ const uint16_t* SK_RESTRICT cache = this->getCache16();
+ int toggle = ((x ^ y) & 1) << kCache16Bits;
+
+ if (fDstToIndexClass != kPerspective_MatrixClass) {
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
+ SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
+
+ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+ SkFixed storage[2];
+ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
+ dx = storage[0];
+ dy = storage[1];
+ } else {
+ SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
+ dx = SkScalarToFixed(fDstToIndex.getScaleX());
+ dy = SkScalarToFixed(fDstToIndex.getSkewY());
+ }
+
+ if (proc == clamp_tileproc) {
+ const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
+
+ /* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
+ rather than 0xFFFF which is slower. This is a compromise, since it reduces our
+ precision, but that appears to be visually OK. If we decide this is OK for
+ all of our cases, we could (it seems) put this scale-down into fDstToIndex,
+ to avoid having to do these extra shifts each time.
+ */
+ fx >>= 1;
+ dx >>= 1;
+ fy >>= 1;
+ dy >>= 1;
+ if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
+ fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
+ fy *= fy;
+ do {
+ unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
+ unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
+ fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
+ fx += dx;
+ *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
+ toggle ^= (1 << kCache16Bits);
+ } while (--count != 0);
+ } else {
+ do {
+ unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
+ unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
+ fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
+ fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
+ fx += dx;
+ fy += dy;
+ *dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
+ toggle ^= (1 << kCache16Bits);
+ } while (--count != 0);
+ }
+ } else if (proc == mirror_tileproc) {
+ do {
+ SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
+ unsigned fi = mirror_tileproc(dist);
+ SkASSERT(fi <= 0xFFFF);
+ fx += dx;
+ fy += dy;
+ *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
+ toggle ^= (1 << kCache16Bits);
+ } while (--count != 0);
+ } else {
+ SkASSERT(proc == repeat_tileproc);
+ do {
+ SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
+ unsigned fi = repeat_tileproc(dist);
+ SkASSERT(fi <= 0xFFFF);
+ fx += dx;
+ fy += dy;
+ *dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
+ toggle ^= (1 << kCache16Bits);
+ } while (--count != 0);
+ }
+ } else { // perspective case
+ SkScalar dstX = SkIntToScalar(x);
+ SkScalar dstY = SkIntToScalar(y);
+ do {
+ dstProc(fDstToIndex, dstX, dstY, &srcPt);
+ unsigned fi = proc(SkScalarToFixed(srcPt.length()));
+ SkASSERT(fi <= 0xFFFF);
+
+ int index = fi >> (16 - kCache16Bits);
+ *dstC++ = cache[toggle + index];
+ toggle ^= (1 << kCache16Bits);
+
+ dstX += SK_Scalar1;
+ } while (--count != 0);
+ }
+}
+
/* Two-point radial gradients are specified by two circles, each with a center
point and radius. The gradient can be considered to be a series of
concentric circles, with the color interpolated from the start circle
(at t=0) to the end circle (at t=1).
For each point (x, y) in the span, we want to find the
interpolated circle that intersects that point. The center
of the desired circle (Cx, Cy) falls at some distance t
@@ -1648,109 +1650,17 @@ public:
info->fPoint[0] = fCenter1;
info->fPoint[1] = fCenter2;
info->fRadius[0] = fRadius1;
info->fRadius[1] = fRadius2;
}
return kRadial2_GradientType;
}
- virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
- SkASSERT(count > 0);
-
- // Zero difference between radii: fill with transparent black.
- // TODO: Is removing this actually correct? Two circles with the
- // same radius, but different centers doesn't sound like it
- // should be cleared
- if (fDiffRadius == 0 && fCenter1 == fCenter2) {
- sk_bzero(dstC, count * sizeof(*dstC));
- return;
- }
- SkMatrix::MapXYProc dstProc = fDstToIndexProc;
- TileProc proc = fTileProc;
- const SkPMColor* SK_RESTRICT cache = this->getCache32();
-
- SkScalar foura = fA * 4;
- bool posRoot = fDiffRadius < 0;
- if (fDstToIndexClass != kPerspective_MatrixClass) {
- SkPoint srcPt;
- dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
- SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
- SkScalar dx, fx = srcPt.fX;
- SkScalar dy, fy = srcPt.fY;
-
- if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
- SkFixed fixedX, fixedY;
- (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
- dx = SkFixedToScalar(fixedX);
- dy = SkFixedToScalar(fixedY);
- } else {
- SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
- dx = fDstToIndex.getScaleX();
- dy = fDstToIndex.getSkewY();
- }
- SkScalar b = (SkScalarMul(fDiff.fX, fx) +
- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
- SkScalar db = (SkScalarMul(fDiff.fX, dx) +
- SkScalarMul(fDiff.fY, dy)) * 2;
- if (proc == clamp_tileproc) {
- for (; count > 0; --count) {
- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
- if (t < 0) {
- *dstC++ = cache[-1];
- } else if (t > 0xFFFF) {
- *dstC++ = cache[kCache32Count * 2];
- } else {
- SkASSERT(t <= 0xFFFF);
- *dstC++ = cache[t >> (16 - kCache32Bits)];
- }
- fx += dx;
- fy += dy;
- b += db;
- }
- } else if (proc == mirror_tileproc) {
- for (; count > 0; --count) {
- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
- SkFixed index = mirror_tileproc(t);
- SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> (16 - kCache32Bits)];
- fx += dx;
- fy += dy;
- b += db;
- }
- } else {
- SkASSERT(proc == repeat_tileproc);
- for (; count > 0; --count) {
- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
- SkFixed index = repeat_tileproc(t);
- SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> (16 - kCache32Bits)];
- fx += dx;
- fy += dy;
- b += db;
- }
- }
- } else { // perspective case
- SkScalar dstX = SkIntToScalar(x);
- SkScalar dstY = SkIntToScalar(y);
- for (; count > 0; --count) {
- SkPoint srcPt;
- dstProc(fDstToIndex, dstX, dstY, &srcPt);
- SkScalar fx = srcPt.fX;
- SkScalar fy = srcPt.fY;
- SkScalar b = (SkScalarMul(fDiff.fX, fx) +
- SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
- SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
- SkFixed index = proc(t);
- SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> (16 - kCache32Bits)];
- dstX += SK_Scalar1;
- }
- }
- }
+ virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
virtual bool setContext(const SkBitmap& device,
const SkPaint& paint,
const SkMatrix& matrix) {
if (!this->INHERITED::setContext(device, paint, matrix)) {
return false;
}
@@ -1804,16 +1714,110 @@ private:
fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY);
fPtsToUnit.postScale(inv, inv);
}
};
+void Two_Point_Radial_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
+ SkASSERT(count > 0);
+
+ // Zero difference between radii: fill with transparent black.
+ // TODO: Is removing this actually correct? Two circles with the
+ // same radius, but different centers doesn't sound like it
+ // should be cleared
+ if (fDiffRadius == 0 && fCenter1 == fCenter2) {
+ sk_bzero(dstC, count * sizeof(*dstC));
+ return;
+ }
+ SkMatrix::MapXYProc dstProc = fDstToIndexProc;
+ TileProc proc = fTileProc;
+ const SkPMColor* SK_RESTRICT cache = this->getCache32();
+
+ SkScalar foura = fA * 4;
+ bool posRoot = fDiffRadius < 0;
+ if (fDstToIndexClass != kPerspective_MatrixClass) {
+ SkPoint srcPt;
+ dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+ SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+ SkScalar dx, fx = srcPt.fX;
+ SkScalar dy, fy = srcPt.fY;
+
+ if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
+ SkFixed fixedX, fixedY;
+ (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
+ dx = SkFixedToScalar(fixedX);
+ dy = SkFixedToScalar(fixedY);
+ } else {
+ SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
+ dx = fDstToIndex.getScaleX();
+ dy = fDstToIndex.getSkewY();
+ }
+ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
+ SkScalar db = (SkScalarMul(fDiff.fX, dx) +
+ SkScalarMul(fDiff.fY, dy)) * 2;
+ if (proc == clamp_tileproc) {
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+ if (t < 0) {
+ *dstC++ = cache[-1];
+ } else if (t > 0xFFFF) {
+ *dstC++ = cache[kCache32Count * 2];
+ } else {
+ SkASSERT(t <= 0xFFFF);
+ *dstC++ = cache[t >> (16 - kCache32Bits)];
+ }
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ } else if (proc == mirror_tileproc) {
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+ SkFixed index = mirror_tileproc(t);
+ SkASSERT(index <= 0xFFFF);
+ *dstC++ = cache[index >> (16 - kCache32Bits)];
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ } else {
+ SkASSERT(proc == repeat_tileproc);
+ for (; count > 0; --count) {
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+ SkFixed index = repeat_tileproc(t);
+ SkASSERT(index <= 0xFFFF);
+ *dstC++ = cache[index >> (16 - kCache32Bits)];
+ fx += dx;
+ fy += dy;
+ b += db;
+ }
+ }
+ } else { // perspective case
+ SkScalar dstX = SkIntToScalar(x);
+ SkScalar dstY = SkIntToScalar(y);
+ for (; count > 0; --count) {
+ SkPoint srcPt;
+ dstProc(fDstToIndex, dstX, dstY, &srcPt);
+ SkScalar fx = srcPt.fX;
+ SkScalar fy = srcPt.fY;
+ SkScalar b = (SkScalarMul(fDiff.fX, fx) +
+ SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
+ SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
+ SkFixed index = proc(t);
+ SkASSERT(index <= 0xFFFF);
+ *dstC++ = cache[index >> (16 - kCache32Bits)];
+ dstX += SK_Scalar1;
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
class Sweep_Gradient : public Gradient_Shader {
public:
Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[],
const SkScalar pos[], int count, SkUnitMapper* mapper)
: Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper),
fCenter(SkPoint::Make(cx, cy))

View File

@ -1175,107 +1175,8 @@ public:
rad_to_unit_matrix(center, radius, &fPtsToUnit);
}
virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count);
virtual void shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) {
SkASSERT(count > 0);
SkPoint srcPt;
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = fTileProc;
const uint16_t* SK_RESTRICT cache = this->getCache16();
int toggle = ((x ^ y) & 1) << kCache16Bits;
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed storage[2];
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
dx = storage[0];
dy = storage[1];
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
dx = SkScalarToFixed(fDstToIndex.getScaleX());
dy = SkScalarToFixed(fDstToIndex.getSkewY());
}
if (proc == clamp_tileproc) {
const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
/* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
rather than 0xFFFF which is slower. This is a compromise, since it reduces our
precision, but that appears to be visually OK. If we decide this is OK for
all of our cases, we could (it seems) put this scale-down into fDstToIndex,
to avoid having to do these extra shifts each time.
*/
fx >>= 1;
dx >>= 1;
fy >>= 1;
dy >>= 1;
if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
fy *= fy;
do {
unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
fx += dx;
*dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
} else {
do {
unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
fx += dx;
fy += dy;
*dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
}
} else if (proc == mirror_tileproc) {
do {
SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
unsigned fi = mirror_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
fx += dx;
fy += dy;
*dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
} else {
SkASSERT(proc == repeat_tileproc);
do {
SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
unsigned fi = repeat_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
fx += dx;
fy += dy;
*dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
}
} else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
do {
dstProc(fDstToIndex, dstX, dstY, &srcPt);
unsigned fi = proc(SkScalarToFixed(srcPt.length()));
SkASSERT(fi <= 0xFFFF);
int index = fi >> (16 - kCache16Bits);
*dstC++ = cache[toggle + index];
toggle ^= (1 << kCache16Bits);
dstX += SK_Scalar1;
} while (--count != 0);
}
}
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
virtual BitmapType asABitmap(SkBitmap* bitmap,
SkMatrix* matrix,
@ -1499,6 +1400,107 @@ void Radial_Gradient::shadeSpan(int x, int y,
}
}
void Radial_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int count) {
SkASSERT(count > 0);
SkPoint srcPt;
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = fTileProc;
const uint16_t* SK_RESTRICT cache = this->getCache16();
int toggle = ((x ^ y) & 1) << kCache16Bits;
if (fDstToIndexClass != kPerspective_MatrixClass) {
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
SkFixed dy, fy = SkScalarToFixed(srcPt.fY);
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed storage[2];
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]);
dx = storage[0];
dy = storage[1];
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
dx = SkScalarToFixed(fDstToIndex.getScaleX());
dy = SkScalarToFixed(fDstToIndex.getSkewY());
}
if (proc == clamp_tileproc) {
const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
/* knock these down so we can pin against +- 0x7FFF, which is an immediate load,
rather than 0xFFFF which is slower. This is a compromise, since it reduces our
precision, but that appears to be visually OK. If we decide this is OK for
all of our cases, we could (it seems) put this scale-down into fDstToIndex,
to avoid having to do these extra shifts each time.
*/
fx >>= 1;
dx >>= 1;
fy >>= 1;
dy >>= 1;
if (dy == 0) { // might perform this check for the other modes, but the win will be a smaller % of the total
fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
fy *= fy;
do {
unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
fx += dx;
*dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
} else {
do {
unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
fx += dx;
fy += dy;
*dstC++ = cache[toggle + (sqrt_table[fi] >> (8 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
}
} else if (proc == mirror_tileproc) {
do {
SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
unsigned fi = mirror_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
fx += dx;
fy += dy;
*dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
} else {
SkASSERT(proc == repeat_tileproc);
do {
SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
unsigned fi = repeat_tileproc(dist);
SkASSERT(fi <= 0xFFFF);
fx += dx;
fy += dy;
*dstC++ = cache[toggle + (fi >> (16 - kCache16Bits))];
toggle ^= (1 << kCache16Bits);
} while (--count != 0);
}
} else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
do {
dstProc(fDstToIndex, dstX, dstY, &srcPt);
unsigned fi = proc(SkScalarToFixed(srcPt.length()));
SkASSERT(fi <= 0xFFFF);
int index = fi >> (16 - kCache16Bits);
*dstC++ = cache[toggle + index];
toggle ^= (1 << kCache16Bits);
dstX += SK_Scalar1;
} while (--count != 0);
}
}
/* Two-point radial gradients are specified by two circles, each with a center
point and radius. The gradient can be considered to be a series of
concentric circles, with the color interpolated from the start circle
@ -1653,99 +1655,7 @@ public:
return kRadial2_GradientType;
}
virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
SkASSERT(count > 0);
// Zero difference between radii: fill with transparent black.
// TODO: Is removing this actually correct? Two circles with the
// same radius, but different centers doesn't sound like it
// should be cleared
if (fDiffRadius == 0 && fCenter1 == fCenter2) {
sk_bzero(dstC, count * sizeof(*dstC));
return;
}
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = fTileProc;
const SkPMColor* SK_RESTRICT cache = this->getCache32();
SkScalar foura = fA * 4;
bool posRoot = fDiffRadius < 0;
if (fDstToIndexClass != kPerspective_MatrixClass) {
SkPoint srcPt;
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
SkScalar dx, fx = srcPt.fX;
SkScalar dy, fy = srcPt.fY;
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed fixedX, fixedY;
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
dx = SkFixedToScalar(fixedX);
dy = SkFixedToScalar(fixedY);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
dx = fDstToIndex.getScaleX();
dy = fDstToIndex.getSkewY();
}
SkScalar b = (SkScalarMul(fDiff.fX, fx) +
SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
SkScalar db = (SkScalarMul(fDiff.fX, dx) +
SkScalarMul(fDiff.fY, dy)) * 2;
if (proc == clamp_tileproc) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
if (t < 0) {
*dstC++ = cache[-1];
} else if (t > 0xFFFF) {
*dstC++ = cache[kCache32Count * 2];
} else {
SkASSERT(t <= 0xFFFF);
*dstC++ = cache[t >> (16 - kCache32Bits)];
}
fx += dx;
fy += dy;
b += db;
}
} else if (proc == mirror_tileproc) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
SkFixed index = mirror_tileproc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> (16 - kCache32Bits)];
fx += dx;
fy += dy;
b += db;
}
} else {
SkASSERT(proc == repeat_tileproc);
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
SkFixed index = repeat_tileproc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> (16 - kCache32Bits)];
fx += dx;
fy += dy;
b += db;
}
}
} else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
for (; count > 0; --count) {
SkPoint srcPt;
dstProc(fDstToIndex, dstX, dstY, &srcPt);
SkScalar fx = srcPt.fX;
SkScalar fy = srcPt.fY;
SkScalar b = (SkScalarMul(fDiff.fX, fx) +
SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
SkFixed index = proc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> (16 - kCache32Bits)];
dstX += SK_Scalar1;
}
}
}
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
virtual bool setContext(const SkBitmap& device,
const SkPaint& paint,
@ -1809,6 +1719,100 @@ private:
}
};
void Two_Point_Radial_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
SkASSERT(count > 0);
// Zero difference between radii: fill with transparent black.
// TODO: Is removing this actually correct? Two circles with the
// same radius, but different centers doesn't sound like it
// should be cleared
if (fDiffRadius == 0 && fCenter1 == fCenter2) {
sk_bzero(dstC, count * sizeof(*dstC));
return;
}
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
TileProc proc = fTileProc;
const SkPMColor* SK_RESTRICT cache = this->getCache32();
SkScalar foura = fA * 4;
bool posRoot = fDiffRadius < 0;
if (fDstToIndexClass != kPerspective_MatrixClass) {
SkPoint srcPt;
dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
SkScalar dx, fx = srcPt.fX;
SkScalar dy, fy = srcPt.fY;
if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
SkFixed fixedX, fixedY;
(void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
dx = SkFixedToScalar(fixedX);
dy = SkFixedToScalar(fixedY);
} else {
SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
dx = fDstToIndex.getScaleX();
dy = fDstToIndex.getSkewY();
}
SkScalar b = (SkScalarMul(fDiff.fX, fx) +
SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
SkScalar db = (SkScalarMul(fDiff.fX, dx) +
SkScalarMul(fDiff.fY, dy)) * 2;
if (proc == clamp_tileproc) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
if (t < 0) {
*dstC++ = cache[-1];
} else if (t > 0xFFFF) {
*dstC++ = cache[kCache32Count * 2];
} else {
SkASSERT(t <= 0xFFFF);
*dstC++ = cache[t >> (16 - kCache32Bits)];
}
fx += dx;
fy += dy;
b += db;
}
} else if (proc == mirror_tileproc) {
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
SkFixed index = mirror_tileproc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> (16 - kCache32Bits)];
fx += dx;
fy += dy;
b += db;
}
} else {
SkASSERT(proc == repeat_tileproc);
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
SkFixed index = repeat_tileproc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> (16 - kCache32Bits)];
fx += dx;
fy += dy;
b += db;
}
}
} else { // perspective case
SkScalar dstX = SkIntToScalar(x);
SkScalar dstY = SkIntToScalar(y);
for (; count > 0; --count) {
SkPoint srcPt;
dstProc(fDstToIndex, dstX, dstY, &srcPt);
SkScalar fx = srcPt.fX;
SkScalar fy = srcPt.fY;
SkScalar b = (SkScalarMul(fDiff.fX, fx) +
SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, fOneOverTwoA, posRoot);
SkFixed index = proc(t);
SkASSERT(index <= 0xFFFF);
*dstC++ = cache[index >> (16 - kCache32Bits)];
dstX += SK_Scalar1;
}
}
}
///////////////////////////////////////////////////////////////////////////////
class Sweep_Gradient : public Gradient_Shader {

View File

@ -103,3 +103,5 @@ patch -p3 < getpostextpath.patch
patch -p3 < new-aa.patch
# Bug 688366 - Fix Skia marking radial gradients with the same radius as invalid.
patch -p3 < radial-gradients.patch
# Fix restrict keyword problem for VS2005
patch -p3 < skia-restrict-problem.patch

View File

@ -151,6 +151,11 @@ EXPORTS += \
WGLLibrary.h \
gfxDWriteFonts.h \
gfxD2DSurface.h \
gfxGDIFont.h \
gfxGDIFontList.h \
gfxPlatformFontList.h \
gfxAtoms.h \
gfxAtomList.h \
$(NULL)
endif

View File

@ -79,12 +79,6 @@ gfxAndroidPlatform::CreateOffscreenSurface(const gfxIntSize& size,
return newSurface.forget();
}
RefPtr<DrawTarget>
gfxAndroidPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
return Factory::CreateDrawTarget(BACKEND_SKIA, aSize, aFormat);
}
nsresult
gfxAndroidPlatform::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,

View File

@ -66,8 +66,7 @@ public:
CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType);
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend) { aBackend = mozilla::gfx::BACKEND_SKIA; return true; }
virtual gfxImageFormat GetOffscreenFormat() { return gfxASurface::ImageFormatRGB16_565; }

View File

@ -123,3 +123,9 @@ gfxD2DSurface::ReleaseDC(const nsIntRect *aUpdatedRect)
rect.height = aUpdatedRect->height;
cairo_d2d_release_dc(CairoSurface(), &rect);
}
const gfxIntSize gfxD2DSurface::GetSize() const
{
return gfxIntSize(cairo_d2d_surface_get_width(mSurface),
cairo_d2d_surface_get_height(mSurface));
}

View File

@ -70,6 +70,8 @@ public:
void Present();
void Scroll(const nsIntPoint &aDelta, const nsIntRect &aClip);
virtual const gfxIntSize GetSize() const;
ID3D10Texture2D *GetTexture();
HDC GetDC(bool aRetainContents);

View File

@ -361,8 +361,10 @@ gfxFontUtils::ReadCMAPTableFormat4(const PRUint8 *aBuf, PRUint32 aLength,
const PRUint16 idRangeOffset = ReadShortAt16(idRangeOffsets, i);
// sanity-check range
NS_ENSURE_TRUE((startCount > prevEndCount || i == 0 || startCount == 0xFFFF) &&
startCount <= endCount,
// This permits ranges to overlap by 1 character, which is strictly
// incorrect but occurs in Baskerville on OS X 10.7 (see bug 689087),
// and appears to be harmless in practice
NS_ENSURE_TRUE(startCount >= prevEndCount && startCount <= endCount,
NS_ERROR_GFX_CMAP_MALFORMED);
prevEndCount = endCount;

View File

@ -49,6 +49,7 @@
#include "cairo-quartz.h"
using namespace mozilla;
using namespace mozilla::gfx;
gfxMacFont::gfxMacFont(MacOSFontEntry *aFontEntry, const gfxFontStyle *aFontStyle,
bool aNeedsBold)
@ -495,3 +496,18 @@ gfxMacFont::InitMetricsFromATSMetrics(ATSFontRef aFontRef)
mIsValid = true;
}
RefPtr<ScaledFont>
gfxMacFont::GetScaledFont()
{
if (!mAzureFont) {
NativeFont nativeFont;
nativeFont.mType = NATIVE_FONT_MAC_FONT_FACE;
nativeFont.mFont = GetCGFontRef();
mAzureFont =
mozilla::gfx::Factory::CreateScaledFontForNativeFont(nativeFont, GetAdjustedSize());
}
return mAzureFont;
}

View File

@ -43,6 +43,7 @@
#include "gfxFont.h"
#include "gfxMacPlatformFontList.h"
#include "mozilla/gfx/2D.h"
#include "cairo.h"
@ -78,6 +79,8 @@ public:
// use CGFontRef API to get direct access to system font data
virtual hb_blob_t *GetFontTable(PRUint32 aTag);
mozilla::RefPtr<mozilla::gfx::ScaledFont> GetScaledFont();
protected:
virtual void CreatePlatformShaper();
@ -110,6 +113,8 @@ protected:
Metrics mMetrics;
PRUint32 mSpaceGlyph;
mozilla::RefPtr<mozilla::gfx::ScaledFont> mAzureFont;
};
#endif /* GFX_MACFONT_H */

View File

@ -220,6 +220,7 @@ static const char *gPrefLangNames[] = {
};
gfxPlatform::gfxPlatform()
: mAzureBackendCollector(this, &gfxPlatform::GetAzureBackendInfo)
{
mUseHarfBuzzScripts = UNINITIALIZED_VALUE;
mAllowDownloadableFonts = UNINITIALIZED_VALUE;
@ -515,6 +516,13 @@ gfxPlatform::GetScaledFontForFont(gfxFont *aFont)
return NULL;
}
cairo_user_data_key_t kDrawSourceSurface;
static void
DataSourceSurfaceDestroy(void *dataSourceSurface)
{
static_cast<DataSourceSurface*>(dataSourceSurface)->Release();
}
already_AddRefed<gfxASurface>
gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
{
@ -531,13 +539,19 @@ gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
nsRefPtr<gfxImageSurface> image =
new gfxImageSurface(data->GetData(), gfxIntSize(size.width, size.height),
data->Stride(), format);
image->SetData(&kDrawSourceSurface, data.forget().drop(), DataSourceSurfaceDestroy);
return image.forget();
}
RefPtr<DrawTarget>
gfxPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
return NULL;
BackendType backend;
if (!SupportsAzure(backend)) {
return NULL;
}
return Factory::CreateDrawTarget(backend, aSize, aFormat);
}
nsresult

View File

@ -53,6 +53,7 @@
#include "gfx2DGlue.h"
#include "mozilla/RefPtr.h"
#include "GfxInfoCollector.h"
#ifdef XP_OS2
#undef OS2EMX_PLAIN_CHAR
@ -142,6 +143,24 @@ const PRUint32 kMaxLenPrefLangList = 32;
typedef gfxASurface::gfxImageFormat gfxImageFormat;
inline const char*
GetBackendName(mozilla::gfx::BackendType aBackend)
{
switch (aBackend) {
case mozilla::gfx::BACKEND_DIRECT2D:
return "direct2d";
case mozilla::gfx::BACKEND_COREGRAPHICS:
return "quartz";
case mozilla::gfx::BACKEND_CAIRO:
return "cairo";
case mozilla::gfx::BACKEND_SKIA:
return "skia";
default:
NS_ERROR("Invalid backend type!");
return "";
}
}
class THEBES_API gfxPlatform {
public:
/**
@ -188,6 +207,15 @@ public:
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend) { return false; }
void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
mozilla::gfx::BackendType backend;
if (SupportsAzure(backend)) {
aObj.DefineProperty("AzureBackend", GetBackendName(backend));
}
}
/*
* Font bits
*/
@ -406,6 +434,7 @@ private:
nsTArray<PRUint32> mCJKPrefLangs;
nsCOMPtr<nsIObserver> mSRGBOverrideObserver;
nsCOMPtr<nsIObserver> mFontPrefsObserver;
mozilla::widget::GfxInfoCollector<gfxPlatform> mAzureBackendCollector;
};
#endif /* GFX_PLATFORM_H */

View File

@ -139,12 +139,6 @@ gfxPlatformMac::CreateOffscreenSurface(const gfxIntSize& size,
return newSurface;
}
RefPtr<DrawTarget>
gfxPlatformMac::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
return Factory::CreateDrawTarget(BACKEND_SKIA, aSize, aFormat);
}
already_AddRefed<gfxASurface>
gfxPlatformMac::OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format)
@ -169,14 +163,14 @@ RefPtr<ScaledFont>
gfxPlatformMac::GetScaledFontForFont(gfxFont *aFont)
{
gfxMacFont *font = static_cast<gfxMacFont*>(aFont);
return font->GetScaledFont();
}
NativeFont nativeFont;
nativeFont.mType = NATIVE_FONT_MAC_FONT_FACE;
nativeFont.mFont = font->GetCGFontRef();
RefPtr<ScaledFont> scaledFont =
mozilla::gfx::Factory::CreateScaledFontForNativeFont(nativeFont, font->GetAdjustedSize());
return scaledFont;
bool
gfxPlatformMac::SupportsAzure(BackendType& aBackend)
{
aBackend = BACKEND_SKIA;
return true;
}
nsresult

View File

@ -63,15 +63,14 @@ public:
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
gfxASurface::gfxContentType contentType);
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
already_AddRefed<gfxASurface> OptimizeImage(gfxImageSurface *aSurface,
gfxASurface::gfxImageFormat format);
mozilla::RefPtr<mozilla::gfx::ScaledFont>
GetScaledFontForFont(gfxFont *aFont);
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend);
nsresult ResolveFontName(const nsAString& aFontName,
FontResolverCallback aCallback,
void *aClosure, bool& aAborted);

View File

@ -474,17 +474,6 @@ gfxWindowsPlatform::CreateOffscreenSurface(const gfxIntSize& size,
return surf;
}
RefPtr<DrawTarget>
gfxWindowsPlatform::CreateOffscreenDrawTarget(const IntSize& aSize, SurfaceFormat aFormat)
{
#ifdef CAIRO_HAS_D2D_SURFACE
if (mRenderMode == RENDER_DIRECT2D) {
return Factory::CreateDrawTarget(BACKEND_DIRECT2D, aSize, aFormat);
}
#endif
return NULL;
}
RefPtr<ScaledFont>
gfxWindowsPlatform::GetScaledFontForFont(gfxFont *aFont)
{
@ -500,7 +489,13 @@ gfxWindowsPlatform::GetScaledFontForFont(gfxFont *aFont)
return scaledFont;
}
return NULL;
NativeFont nativeFont;
nativeFont.mType = NATIVE_FONT_GDI_FONT_FACE;
nativeFont.mFont = aFont;
RefPtr<ScaledFont> scaledFont =
Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
return scaledFont;
}
already_AddRefed<gfxASurface>
@ -529,6 +524,23 @@ gfxWindowsPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
return gfxPlatform::GetThebesSurfaceForDrawTarget(aTarget);
}
bool
gfxWindowsPlatform::SupportsAzure(BackendType& aBackend)
{
#ifdef CAIRO_HAS_D2D_SURFACE
if (mRenderMode == RENDER_DIRECT2D) {
aBackend = BACKEND_DIRECT2D;
return true;
}
#endif
if (Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
aBackend = BACKEND_SKIA;
return true;
}
return false;
}
nsresult
gfxWindowsPlatform::GetFontList(nsIAtom *aLangGroup,
const nsACString& aGenericFamily,

View File

@ -131,8 +131,8 @@ public:
GetScaledFontForFont(gfxFont *aFont);
virtual already_AddRefed<gfxASurface>
GetThebesSurfaceForDrawTarget(mozilla::gfx::DrawTarget *aTarget);
virtual mozilla::RefPtr<mozilla::gfx::DrawTarget>
CreateOffscreenDrawTarget(const mozilla::gfx::IntSize& aSize, mozilla::gfx::SurfaceFormat aFormat);
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend);
enum RenderMode {
/* Use GDI and windows surfaces */

View File

@ -337,6 +337,20 @@ gfxWindowsSurface::GetDefaultContextFlags() const
return 0;
}
const gfxIntSize
gfxWindowsSurface::GetSize() const
{
if (!mSurfaceValid) {
NS_WARNING ("GetImageSurface on an invalid (null) surface; who's calling this without checking for surface errors?");
return gfxIntSize(-1, -1);
}
NS_ASSERTION(mSurface != nsnull, "CairoSurface() shouldn't be nsnull when mSurfaceValid is TRUE!");
return gfxIntSize(cairo_win32_surface_get_width(mSurface),
cairo_win32_surface_get_height(mSurface));
}
gfxASurface::MemoryLocation
gfxWindowsSurface::GetMemoryLocation() const
{

View File

@ -92,6 +92,8 @@ public:
virtual PRInt32 GetDefaultContextFlags() const;
const gfxIntSize GetSize() const;
void MovePixels(const nsIntRect& aSourceRect,
const nsIntPoint& aDestTopLeft)
{

View File

@ -3129,9 +3129,7 @@ struct JSClass {
object in prototype chain
passed in via *objp in/out
parameter */
#define JSCLASS_CONSTRUCT_PROTOTYPE (1<<6) /* call constructor on class
prototype */
#define JSCLASS_DOCUMENT_OBSERVER (1<<7) /* DOM document observer */
#define JSCLASS_DOCUMENT_OBSERVER (1<<6) /* DOM document observer */
/*
* To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or
@ -4975,50 +4973,6 @@ JS_IsConstructing(JSContext *cx, const jsval *vp)
return JSVAL_IS_MAGIC_IMPL(JSVAL_TO_IMPL(vp[1]));
}
/*
* In the case of a constructor called from JS_ConstructObject and
* JS_InitClass where the class has the JSCLASS_CONSTRUCT_PROTOTYPE flag set,
* the JS engine passes the constructor a non-standard 'this' object. In such
* cases, the following query provides the additional information of whether a
* special 'this' was supplied. E.g.:
*
* JSBool foo_native(JSContext *cx, uintN argc, jsval *vp) {
* JSObject *maybeThis;
* if (JS_IsConstructing_PossiblyWithGivenThisObject(cx, vp, &maybeThis)) {
* // native called as a constructor
* if (maybeThis)
* // native called as a constructor with maybeThis as 'this'
* } else {
* // native called as function, maybeThis is still uninitialized
* }
* }
*
* Note that embeddings do not need to use this query unless they use the
* aforementioned API/flags.
*/
static JS_ALWAYS_INLINE JSBool
JS_IsConstructing_PossiblyWithGivenThisObject(JSContext *cx, const jsval *vp,
JSObject **maybeThis)
{
jsval_layout l;
JSBool isCtor;
#ifdef DEBUG
JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
if (JS_ObjectIsFunction(cx, callee)) {
JSFunction *fun = JS_ValueToFunction(cx, JS_CALLEE(cx, vp));
JS_ASSERT((JS_GetFunctionFlags(fun) & JSFUN_CONSTRUCTOR) != 0);
} else {
JS_ASSERT(JS_GET_CLASS(cx, callee)->construct != NULL);
}
#endif
isCtor = JSVAL_IS_MAGIC_IMPL(JSVAL_TO_IMPL(vp[1]));
if (isCtor)
*maybeThis = MAGIC_JSVAL_TO_OBJECT_OR_NULL_IMPL(l);
return isCtor;
}
/*
* If a constructor does not have any static knowledge about the type of
* object to create, it can request that the JS engine create a default new

View File

@ -420,7 +420,7 @@ struct JS_FRIEND_API(JSCompartment) {
* Cleared on every GC, unless the GC happens during analysis (indicated
* by activeAnalysis, which is implied by activeInference).
*/
static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 256 * 1024;
static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 4 * 1024;
js::LifoAlloc typeLifoAlloc;
bool activeAnalysis;
bool activeInference;

View File

@ -4317,7 +4317,7 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
* inference may need to access these, and js_GetClassPrototype will
* fail if it tries to do a reentrant reconstruction of the class.
*/
if (key != JSProto_Null && !(clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE)) {
if (key != JSProto_Null) {
if (!SetClassObject(cx, obj, key, fun, proto))
goto bad;
cached = true;
@ -4334,16 +4334,6 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
* XML support requires.
*/
ctor = fun;
if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
Value rval;
if (!InvokeConstructorWithGivenThis(cx, proto, ObjectOrNullValue(ctor),
0, NULL, &rval)) {
goto bad;
}
if (rval.isObject() && &rval.toObject() != proto)
proto = &rval.toObject();
}
if (!LinkConstructorAndPrototype(cx, ctor, proto))
goto bad;
@ -4944,16 +4934,10 @@ js_ConstructObject(JSContext *cx, Class *clasp, JSObject *proto, JSObject *paren
/*
* If the instance's class differs from what was requested, throw a type
* error. If the given class has both the JSCLASS_HAS_PRIVATE and the
* JSCLASS_CONSTRUCT_PROTOTYPE flags, and the instance does not have its
* private data set at this point, then the constructor was replaced and
* we should throw a type error.
* error.
*/
obj = &rval.toObject();
if (obj->getClass() != clasp ||
(!(~clasp->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_CONSTRUCT_PROTOTYPE)) &&
!obj->getPrivate())) {
if (obj->getClass() != clasp) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_WRONG_CONSTRUCTOR, clasp->name);
return NULL;

View File

@ -3593,9 +3593,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
return NS_ERROR_GFX_PRINTER_DOC_IS_BUSY;
}
nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell));
if (!presShell || !mDocument || !mDeviceContext) {
if (!mDocument || !mDeviceContext) {
PR_PL(("Can't Print without pres shell, document etc"));
return NS_ERROR_FAILURE;
}

View File

@ -90,6 +90,7 @@
#include "nsIFileURL.h"
#include "nsDOMFile.h"
#include "nsEventStates.h"
#include "nsTextControlFrame.h"
#include "nsIDOMDOMStringList.h"
#include "nsIDOMDragEvent.h"
@ -108,8 +109,7 @@ NS_NewFileControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
NS_IMPL_FRAMEARENA_HELPERS(nsFileControlFrame)
nsFileControlFrame::nsFileControlFrame(nsStyleContext* aContext):
nsBlockFrame(aContext),
mTextFrame(nsnull)
nsBlockFrame(aContext)
{
AddStateBits(NS_BLOCK_FLOAT_MGR);
}
@ -134,7 +134,6 @@ nsFileControlFrame::Init(nsIContent* aContent,
void
nsFileControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
mTextFrame = nsnull;
ENSURE_TRUE(mContent);
// Remove the drag events
@ -453,8 +452,9 @@ nsFileControlFrame::CaptureMouseListener::HandleEvent(nsIDOMEvent* aMouseEvent)
rv = capturePicker->Init(win, title, mMode);
NS_ENSURE_SUCCESS(rv, rv);
// Tell our textframe to remember the currently focused value
mFrame->mTextFrame->InitFocusedValue();
// Tell our text control frame to remember the currently focused value.
nsTextControlFrame* textControlFrame = mFrame->GetTextControlFrame();
textControlFrame->InitFocusedValue();
// Show dialog
PRUint32 result;
@ -486,16 +486,16 @@ nsFileControlFrame::CaptureMouseListener::HandleEvent(nsIDOMEvent* aMouseEvent)
// uneditable text box with the file name inside.
// Set new selected files
if (newFiles.Count()) {
// Tell mTextFrame that this update of the value is a user initiated
// change. Otherwise it'll think that the value is being set by a script
// and not fire onchange when it should.
bool oldState = mFrame->mTextFrame->GetFireChangeEventState();
mFrame->mTextFrame->SetFireChangeEventState(true);
// Tell our text control frame that this update of the value is a user
// initiated change. Otherwise it'll think that the value is being set by
// a script and not fire onchange when it should.
bool oldState = textControlFrame->GetFireChangeEventState();
textControlFrame->SetFireChangeEventState(true);
inputElement->SetFiles(newFiles, true);
textControlFrame->SetFireChangeEventState(oldState);
mFrame->mTextFrame->SetFireChangeEventState(oldState);
// May need to fire an onchange here
mFrame->mTextFrame->CheckFireOnChange();
textControlFrame->CheckFireOnChange();
}
return NS_OK;
@ -556,11 +556,12 @@ nsFileControlFrame::BrowseMouseListener::HandleEvent(nsIDOMEvent* aEvent)
nsCOMPtr<nsIDOMFileList> fileList;
dataTransfer->GetFiles(getter_AddRefs(fileList));
bool oldState = mFrame->mTextFrame->GetFireChangeEventState();
mFrame->mTextFrame->SetFireChangeEventState(true);
nsTextControlFrame* textControlFrame = mFrame->GetTextControlFrame();
bool oldState = textControlFrame->GetFireChangeEventState();
textControlFrame->SetFireChangeEventState(true);
inputElement->SetFiles(fileList, true);
mFrame->mTextFrame->SetFireChangeEventState(oldState);
mFrame->mTextFrame->CheckFireOnChange();
textControlFrame->SetFireChangeEventState(oldState);
textControlFrame->CheckFireOnChange();
}
return NS_OK;
@ -594,55 +595,11 @@ nsFileControlFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
return result;
}
NS_IMETHODIMP nsFileControlFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
nsTextControlFrame*
nsFileControlFrame::GetTextControlFrame()
{
DO_GLOBAL_REFLOW_COUNT("nsFileControlFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
aStatus = NS_FRAME_COMPLETE;
if (mState & NS_FRAME_FIRST_REFLOW) {
mTextFrame = GetTextControlFrame(aPresContext, this);
NS_ENSURE_TRUE(mTextFrame, NS_ERROR_UNEXPECTED);
}
// nsBlockFrame takes care of all our reflow
return nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState,
aStatus);
}
nsNewFrame*
nsFileControlFrame::GetTextControlFrame(nsPresContext* aPresContext, nsIFrame* aStart)
{
nsNewFrame* result = nsnull;
#ifndef DEBUG_NEWFRAME
// find the text control frame.
nsIFrame* childFrame = aStart->GetFirstPrincipalChild();
while (childFrame) {
// see if the child is a text control
nsCOMPtr<nsIFormControl> formCtrl =
do_QueryInterface(childFrame->GetContent());
if (formCtrl && formCtrl->GetType() == NS_FORM_INPUT_TEXT) {
result = (nsNewFrame*)childFrame;
}
// if not continue looking
nsNewFrame* frame = GetTextControlFrame(aPresContext, childFrame);
if (frame)
result = frame;
childFrame = childFrame->GetNextSibling();
}
return result;
#else
return nsnull;
#endif
nsITextControlFrame* tc = do_QueryFrame(mTextContent->GetPrimaryFrame());
return static_cast<nsTextControlFrame*>(tc);
}
PRIntn

View File

@ -45,9 +45,7 @@
#include "nsICapturePicker.h"
#include "nsCOMPtr.h"
#include "nsTextControlFrame.h"
typedef nsTextControlFrame nsNewFrame;
class nsTextControlFrame;
class nsIDOMDragEvent;
class nsFileControlFrame : public nsBlockFrame,
@ -75,11 +73,6 @@ public:
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
NS_IMETHOD Reflow(nsPresContext* aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual void DestroyFrom(nsIFrame* aDestructRoot);
#ifdef NS_DEBUG
@ -106,8 +99,6 @@ public:
typedef bool (*AcceptAttrCallback)(const nsAString&, void*);
void ParseAcceptAttribute(AcceptAttrCallback aCallback, void* aClosure) const;
nsIFrame* GetTextFrame() { return mTextFrame; }
protected:
class MouseListener;
@ -173,11 +164,6 @@ protected:
virtual PRIntn GetSkipSides() const;
/**
* The text frame (populated on initial reflow).
* @see nsFileControlFrame::Reflow
*/
nsNewFrame* mTextFrame;
/**
* The text box input.
* @see nsFileControlFrame::CreateAnonymousContent
@ -201,19 +187,11 @@ protected:
nsRefPtr<BrowseMouseListener> mMouseListener;
nsRefPtr<CaptureMouseListener> mCaptureMouseListener;
private:
protected:
/**
* Find the first text frame child (first frame child whose content has input
* type=text) of a frame.
* XXX this is an awfully complicated implementation of something we could
* likely do by just doing GetPrimaryFrame on mTextContent
*
* @param aPresContext the current pres context
* @param aStart the parent frame to search children of
* @return the text control frame, or null if not found
*/
nsNewFrame* GetTextControlFrame(nsPresContext* aPresContext,
nsIFrame* aStart);
nsTextControlFrame* GetTextControlFrame();
/**
* Copy an attribute from file content to text and button content.

View File

@ -1531,10 +1531,9 @@ nsImageFrame::GetContentForEvent(nsEvent* aEvent,
nsIntPoint p;
TranslateEventCoords(
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this), p);
bool inside = false;
nsCOMPtr<nsIContent> area = map->GetArea(p.x, p.y);
if (area) {
area.swap(*aContent);
area.forget(aContent);
return NS_OK;
}
}

View File

@ -106,8 +106,8 @@ static void Scale(gfx3DMatrix& aTransform, double aXScale, double aYScale)
static void ReverseTranslate(gfx3DMatrix& aTransform, ViewTransform& aViewTransform)
{
aTransform._41 -= aViewTransform.mTranslation.x * aViewTransform.mXScale;
aTransform._42 -= aViewTransform.mTranslation.y * aViewTransform.mYScale;
aTransform._41 -= aViewTransform.mTranslation.x / aViewTransform.mXScale;
aTransform._42 -= aViewTransform.mTranslation.y / aViewTransform.mYScale;
}
@ -170,8 +170,8 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
nsFrameLoader* aRootFrameLoader,
const FrameMetrics* aMetrics,
const ViewConfig& aConfig,
float aInverseScaleX,
float aInverseScaleY)
float aTempScaleX = 1.0,
float aTempScaleY = 1.0)
{
// |aMetrics->mViewportScrollOffset| The frame's scroll offset when it was
// painted, in content document pixels.
@ -194,8 +194,8 @@ ComputeShadowTreeTransform(nsIFrame* aContainerFrame,
// synchronously scrolled for identifying a scroll area before it is
// being actively scrolled.
nsIntPoint scrollCompensation(
scrollOffset.x * aInverseScaleX - metricsScrollOffset.x * aConfig.mXScale,
scrollOffset.y * aInverseScaleY - metricsScrollOffset.y * aConfig.mYScale);
(scrollOffset.x / aTempScaleX - metricsScrollOffset.x) * aConfig.mXScale,
(scrollOffset.y / aTempScaleY - metricsScrollOffset.y) * aConfig.mYScale);
return ViewTransform(-scrollCompensation, aConfig.mXScale, aConfig.mYScale);
} else {
@ -266,7 +266,9 @@ BuildListForLayer(Layer* aLayer,
static void
TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
nsIFrame* aFrame, Layer* aLayer,
const ViewTransform& aTransform)
const ViewTransform& aTransform,
float aTempScaleDiffX = 1.0,
float aTempScaleDiffY = 1.0)
{
ShadowLayer* shadow = aLayer->AsShadowLayer();
shadow->SetShadowClipRect(aLayer->GetClipRect());
@ -274,7 +276,7 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
gfx3DMatrix shadowTransform;
gfx3DMatrix shadowTransform = aLayer->GetTransform();
ViewTransform layerTransform = aTransform;
if (metrics && metrics->IsScrollable()) {
@ -284,26 +286,26 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree");
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
const ViewConfig& config = view->GetViewConfig();
// With temporary scale we should compensate translation
// using temporary scale value
aTempScaleDiffX *= GetXScale(shadowTransform) * config.mXScale;
aTempScaleDiffY *= GetYScale(shadowTransform) * config.mYScale;
ViewTransform viewTransform = ComputeShadowTreeTransform(
aFrame, aFrameLoader, metrics, view->GetViewConfig(),
1 / (GetXScale(currentTransform)*layerTransform.mXScale),
1 / (GetYScale(currentTransform)*layerTransform.mYScale)
aTempScaleDiffX, aTempScaleDiffY
);
// Apply the layer's own transform *before* the view transform
shadowTransform = gfx3DMatrix(viewTransform) * currentTransform;
layerTransform = viewTransform;
if (metrics->IsRootScrollable()) {
layerTransform.mTranslation = viewTransform.mTranslation;
// Apply the root frame translation *before* we do the rest of the transforms.
nsIntPoint rootFrameOffset = GetRootFrameOffset(aFrame, aBuilder);
shadowTransform = shadowTransform *
gfx3DMatrix::Translation(float(rootFrameOffset.x), float(rootFrameOffset.y), 0.0);
layerTransform.mXScale *= GetXScale(currentTransform);
layerTransform.mYScale *= GetYScale(currentTransform);
}
} else {
shadowTransform = aLayer->GetTransform();
}
if (aLayer->GetIsFixedPosition() &&
@ -320,7 +322,8 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
shadow->SetShadowTransform(shadowTransform);
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform);
TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform,
aTempScaleDiffX, aTempScaleDiffY);
}
}
@ -352,7 +355,8 @@ IsTempLayerManager(LayerManager* aManager)
static void
BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
nsFrameLoader* aFrameLoader, Layer* aLayer,
float aXScale = 1, float aYScale = 1)
float aXScale = 1, float aYScale = 1,
float aAccConfigXScale = 1, float aAccConfigYScale = 1)
{
ContainerLayer* container = aLayer->AsContainerLayer();
if (!container)
@ -374,6 +378,22 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
aXScale *= config.mXScale;
aYScale *= config.mYScale;
view->mFrameLoader = aFrameLoader;
// If scale has changed, then we should update
// current scroll offset to new scaled value
if (aAccConfigXScale != view->mParentScaleX ||
aAccConfigYScale != view->mParentScaleY) {
float xscroll = 0, yscroll = 0;
view->GetScrollX(&xscroll);
view->GetScrollY(&yscroll);
xscroll = xscroll * (aAccConfigXScale / view->mParentScaleX);
yscroll = yscroll * (aAccConfigYScale / view->mParentScaleY);
view->ScrollTo(xscroll, yscroll);
view->mParentScaleX = aAccConfigXScale;
view->mParentScaleY = aAccConfigYScale;
}
// Collect only config scale values for scroll compensation
aAccConfigXScale *= config.mXScale;
aAccConfigYScale *= config.mYScale;
} else {
// View doesn't exist, so generate one. We start the view scroll offset at
// the same position as the framemetric's scroll offset from the layer.
@ -383,6 +403,8 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.x, auPerDevPixel) * aXScale,
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.y, auPerDevPixel) * aYScale);
view = new nsContentView(aFrameLoader, scrollId, config);
view->mParentScaleX = aAccConfigXScale;
view->mParentScaleY = aAccConfigYScale;
}
view->mViewportSize = nsSize(
@ -398,7 +420,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
BuildViewMap(oldContentViews, newContentViews, aFrameLoader, child,
aXScale, aYScale);
aXScale, aYScale, aAccConfigXScale, aAccConfigYScale);
}
}

View File

@ -6,10 +6,12 @@
</head>
<body>
<div>
<span>test</span>
<!-- Need the non-breaking spaces to avoid some reftest badness due to
the 't' extending outside its nominal metrics -->
<span>&#xA0;test</span>
</div>
<div>
<span>test</span>
<span>&#xA0;test</span>
</div>
</body>
</html>

View File

@ -15,7 +15,7 @@
<script src="data:text/javascript,document.body.offsetWidth;"/>
<!-- The whitespace here is important... or this comment will do
the trick too -->
<span>test</span>
<span>&#xA0;test</span>
</div>
<script>
function runTest() {
@ -28,7 +28,7 @@
function makeSpan() {
var s = document.createElementNS("http://www.w3.org/1999/xhtml",
"span");
s.appendChild(document.createTextNode("test"));
s.appendChild(document.createTextNode("&#xA0;test"));
return s;
}
</script>

View File

@ -1,22 +1,22 @@
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="test">
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml"
style="color: red; -moz-binding: url(403962-1xbl.xml#test-base)">
<children/>
</html:div>
</content>
</binding>
<binding id="test-base">
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml" style="color: green">
<children includes="span"/>
</html:div>
<html:div xmlns:html="http://www.w3.org/1999/xhtml" style="color: red">
<children/>
</html:div>
</content>
</binding>
</bindings>
<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="test">
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml"
style="color: red; -moz-binding: url(403962-1xbl.xml#test-base)">
<children/>
</html:div>
</content>
</binding>
<binding id="test-base">
<content>
<html:div xmlns:html="http://www.w3.org/1999/xhtml" style="color: green">
<children includes="span"/>
</html:div>
<html:div xmlns:html="http://www.w3.org/1999/xhtml" style="color: red">
<children/>
</html:div>
</content>
</binding>
</bindings>

View File

@ -28,7 +28,7 @@ canvas {
<script>
var ctx = document.getElementById("c").getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(2, 2, 6, 6);
ctx.fillRect(0, 0, 10, 10);
</script>
</body>
</html>

View File

@ -31,7 +31,7 @@ canvas {
<script>
var ctx = document.getElementById("c").getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(2, 2, 6, 6);
ctx.fillRect(0, 0, 10, 10);
</script>
</body>
</html>

View File

@ -1,7 +1,7 @@
== default-size.html default-size-ref.html
== size-1.html size-1-ref.html
== image-rendering-test.html image-rendering-ref.html
fails-if(Android) == image-rendering-test.html image-rendering-ref.html # bug 698985
== image-shadow.html image-shadow-ref.html
asserts-if(cocoaWidget,0-2) == size-change-1.html size-change-1-ref.html

View File

@ -170,7 +170,7 @@ fails == collapsed-border-top-6.html border-top-10-ref.html
fails-if(cocoaWidget) == background-image-tiling.html background-image-tiling-ref.html # probably bug 379317
!= border-image-width-0.html border-image-width-10.html
== border-image-width-4.html border-image-width-0.html
== border-image-width-9.html border-image-width-0.html
random-if(Android) == border-image-width-4.html border-image-width-0.html # bug 661996
random-if(Android) == border-image-width-9.html border-image-width-0.html # bug 661996
== iframe-1.html iframe-1-ref.html

View File

@ -39,6 +39,7 @@
@import url(chrome://global/content/xul.css);
@namespace parsererror url(http://www.mozilla.org/newlayout/xml/parsererror.xml);
@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
/* magic -- some of these rules are important to keep pages from overriding
them
@ -253,8 +254,9 @@
}
/* If there is a full-screen element that is not the root then
we should hide the viewport scrollbar. */
*|*:root:-moz-full-screen-ancestor {
we should hide the viewport scrollbar. We exclude the chrome
document to prevent reframing of contained plugins. */
:not(xul|*):root:-moz-full-screen-ancestor {
overflow: hidden !important;
}

View File

@ -84,15 +84,30 @@ nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
return NS_OK;
}
// XXX hack until handle release is actually called in nsframe.
if (aEvent->message == NS_MOUSE_EXIT_SYNTH ||
aEvent->message == NS_MOUSE_BUTTON_UP)
HandleRelease(aPresContext, aEvent, aEventStatus);
// if we didn't handle the press ourselves, pass it on to the superclass
if (!HandleButtonPress(aPresContext, aEvent, aEventStatus))
return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
return NS_OK;
switch (aEvent->message) {
case NS_MOUSE_BUTTON_DOWN:
mCursorOnThis = true;
// if we didn't handle the press ourselves, pass it on to the superclass
if (HandleButtonPress(aPresContext, aEvent, aEventStatus)) {
return NS_OK;
}
break;
case NS_MOUSE_BUTTON_UP:
HandleRelease(aPresContext, aEvent, aEventStatus);
break;
case NS_MOUSE_EXIT_SYNTH:
mCursorOnThis = false;
break;
case NS_MOUSE_MOVE: {
nsPoint cursor =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
nsRect frameRect(nsPoint(0, 0), GetSize());
mCursorOnThis = frameRect.Contains(cursor);
break;
}
}
return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
@ -103,18 +118,13 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
{
// Get the desired action for the scrollbar button.
LookAndFeel::IntID tmpAction;
if (aEvent->eventStructType == NS_MOUSE_EVENT &&
aEvent->message == NS_MOUSE_BUTTON_DOWN) {
PRUint16 button = static_cast<nsMouseEvent*>(aEvent)->button;
if (button == nsMouseEvent::eLeftButton) {
tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
} else if (button == nsMouseEvent::eMiddleButton) {
tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
} else if (button == nsMouseEvent::eRightButton) {
tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
} else {
return false;
}
PRUint16 button = static_cast<nsMouseEvent*>(aEvent)->button;
if (button == nsMouseEvent::eLeftButton) {
tmpAction = LookAndFeel::eIntID_ScrollButtonLeftMouseButtonAction;
} else if (button == nsMouseEvent::eMiddleButton) {
tmpAction = LookAndFeel::eIntID_ScrollButtonMiddleMouseButtonAction;
} else if (button == nsMouseEvent::eRightButton) {
tmpAction = LookAndFeel::eIntID_ScrollButtonRightMouseButtonAction;
} else {
return false;
}
@ -180,6 +190,8 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
nsWeakFrame weakFrame(this);
mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::active, NS_LITERAL_STRING("true"), true);
nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED);
if (weakFrame.IsAlive()) {
DoButtonAction(smoothScroll);
}
@ -193,6 +205,7 @@ nsScrollbarButtonFrame::HandleRelease(nsPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
nsIPresShell::SetCapturingContent(nsnull, 0);
// we're not active anymore
mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::active, true);
StopRepeat();
@ -203,7 +216,11 @@ void nsScrollbarButtonFrame::Notify()
{
// Since this is only going to get called if we're scrolling a page length
// or a line increment, we will always use smooth scrolling.
DoButtonAction(true);
if (mCursorOnThis ||
LookAndFeel::GetInt(
LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) {
DoButtonAction(true);
}
}
void

View File

@ -57,7 +57,7 @@ public:
NS_DECL_FRAMEARENA_HELPERS
nsScrollbarButtonFrame(nsIPresShell* aPresShell, nsStyleContext* aContext):
nsButtonBoxFrame(aPresShell, aContext) {}
nsButtonBoxFrame(aPresShell, aContext), mCursorOnThis(false) {}
// Overrides
virtual void DestroyFrom(nsIFrame* aDestructRoot);
@ -105,6 +105,7 @@ protected:
}
PRInt32 mIncrement;
bool mCursorOnThis;
};
#endif

View File

@ -51,6 +51,7 @@ _TEST_FILES =\
$(NULL)
_CHROME_FILES = \
test_bug159346.xul \
test_bug372685.xul \
test_bug398982-1.xul \
test_bug398982-2.xul \

View File

@ -0,0 +1,132 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="Test for Bug 159346">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=159346
-->
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<scrollbar id="scrollbar" curpos="0" maxpos="500"/>
<script class="testbody" type="application/javascript">
<![CDATA[
var scrollbar = document.getElementById("scrollbar");
var downButton =
document.getAnonymousElementByAttribute(scrollbar, "sbattr",
"scrollbar-down-bottom");
function init()
{
downButton.style.display = "-moz-box";
SimpleTest.executeSoon(doTest1);
}
function doTest1()
{
var lastPos = 0;
synthesizeMouseAtCenter(downButton, { type: "mousedown" });
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by mousedown #1");
lastPos = scrollbar.getAttribute("curpos");
setTimeout(function () {
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by auto repeat #1");
synthesizeMouseAtCenter(downButton, { type: "mouseup" });
lastPos = scrollbar.getAttribute("curpos");
setTimeout(function () {
is(scrollbar.getAttribute("curpos"), lastPos,
"scrollbar changed curpos after mouseup #1");
SimpleTest.executeSoon(doTest2);
}, 1000);
}, 1000);
}
function doTest2()
{
SpecialPowers.setIntPref("ui.scrollbarButtonAutoRepeatBehavior", 0);
scrollbar.setAttribute("curpos", 0);
var lastPos = 0;
synthesizeMouseAtCenter(downButton, { type: "mousedown" });
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by mousedown #2");
lastPos = scrollbar.getAttribute("curpos");
synthesizeMouse(downButton, -10, -10, { type: "mousemove" });
lastPos = scrollbar.getAttribute("curpos");
setTimeout(function () {
is(scrollbar.getAttribute("curpos"), lastPos,
"scrollbar changed curpos by auto repeat when cursor is outside of scrollbar button #2");
synthesizeMouseAtCenter(downButton, { type: "mousemove" });
lastPos = scrollbar.getAttribute("curpos");
setTimeout(function () {
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by mousemove after cursor is back on the scrollbar button #2");
synthesizeMouseAtCenter(downButton, { type: "mouseup" });
SimpleTest.executeSoon(doTest3);
}, 1000);
}, 1000);
}
function doTest3()
{
SpecialPowers.setIntPref("ui.scrollbarButtonAutoRepeatBehavior", 1);
scrollbar.setAttribute("curpos", 0);
var lastPos = 0;
synthesizeMouseAtCenter(downButton, { type: "mousedown" });
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by mousedown #3");
lastPos = scrollbar.getAttribute("curpos");
synthesizeMouse(downButton, -10, -10, { type: "mousemove" });
lastPos = scrollbar.getAttribute("curpos");
setTimeout(function () {
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by auto repeat when cursor is outside of scrollbar button #3");
synthesizeMouseAtCenter(downButton, { type: "mousemove" });
lastPos = scrollbar.getAttribute("curpos");
setTimeout(function () {
ok(scrollbar.getAttribute("curpos") > lastPos,
"scrollbar didn't change curpos by mousemove after cursor is back on the scrollbar button #3");
synthesizeMouseAtCenter(downButton, { type: "mouseup" });
SpecialPowers.clearUserPref("ui.scrollbarButtonAutoRepeatBehavior");
SimpleTest.finish();
}, 1000);
}, 1000);
}
SimpleTest.waitForExplicitFinish();
]]>
</script>
<body id="html_body" xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=159346">Mozilla Bug 159346</a>
<p id="display"></p>
<pre id="test">
</pre>
<script>
addLoadEvent(init);
</script>
</body>
</window>

View File

@ -702,7 +702,9 @@ let ContentActive = {
case "Content:Deactivate":
docShell.isActive = false;
let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
cwu.setDisplayPortForElement(0,0,0,0,content.document.documentElement);
if (json.keepviewport)
break;
cwu.setDisplayPortForElement(0, 0, 0, 0, content.document.documentElement);
break;
case "Content:Activate":

View File

@ -1117,7 +1117,18 @@
<property name="active" onget="return this._active;">
<setter><![CDATA[
this._active = val;
this.messageManager.sendAsyncMessage((val ? "Content:Activate" : "Content:Deactivate"), {});
let keepVisible = false;
#if MOZ_PLATFORM_MAEMO == 6
if (!val) {
// In task switcher, but display is on, keep visible
if ((ActivityObserver._inBackground && !ActivityObserver._isDisplayOff) ||
// If not active, app in foreground and display is on
(!ActivityObserver._inBackground && !ActivityObserver._isDisplayOff && ActivityObserver._notActive)) {
keepVisible = true;
}
}
#endif
this.messageManager.sendAsyncMessage((val ? "Content:Activate" : "Content:Deactivate"), { keepviewport: keepVisible });
if (val)
this.getRootView()._updateCacheViewport();
]]></setter>

View File

@ -61,6 +61,7 @@ const kBrowserViewZoomLevelPrecision = 10000;
// allow panning after this timeout on pages with registered touch listeners
const kTouchTimeout = 300;
const kSetInactiveStateTimeout = 100;
const kDefaultMetadata = { autoSize: false, allowZoom: true, autoScale: true };
@ -2701,7 +2702,7 @@ var ActivityObserver = {
// On Maemo all backgrounded applications getting portrait orientation
// so if browser had landscape mode then we need timeout in order
// to finish last rotate/paint operation and have nice lookine browser in TS
setTimeout(function() { Browser.selectedTab.active = activeTabState; }, 0);
setTimeout(function() { Browser.selectedTab.active = activeTabState; }, activeTabState ? 0 : kSetInactiveStateTimeout);
}
}
};

View File

@ -41,7 +41,7 @@ chrome.jar:
* content/bindings.xml (content/bindings.xml)
content/tabs.xml (content/tabs.xml)
content/bindings/checkbox.xml (content/bindings/checkbox.xml)
content/bindings/browser.xml (content/bindings/browser.xml)
* content/bindings/browser.xml (content/bindings/browser.xml)
content/bindings/browser.js (content/bindings/browser.js)
content/notification.xml (content/notification.xml)
content/bindings/extensions.xml (content/bindings/extensions.xml)

View File

@ -315,7 +315,7 @@ nsHttpConnection::SupportsPipelining(nsHttpResponseHead *responseHead)
// known to return their identifier as the first thing in the server string,
// so we can do a leading match.
static const char *bad_servers[26][5] = {
static const char *bad_servers[26][6] = {
{ nsnull }, { nsnull }, { nsnull }, { nsnull }, // a - d
{ "EFAServer/", nsnull }, // e
{ nsnull }, { nsnull }, { nsnull }, { nsnull }, // f - i
@ -325,7 +325,8 @@ nsHttpConnection::SupportsPipelining(nsHttpResponseHead *responseHead)
"Netscape-Enterprise/5.", "Netscape-Enterprise/6.", nsnull }, // n
{ nsnull }, { nsnull }, { nsnull }, { nsnull }, // o - r
{ nsnull }, { nsnull }, { nsnull }, { nsnull }, // s - v
{ "WebLogic 3.", "WebLogic 4.","WebLogic 5.", "WebLogic 6.", nsnull }, // w
{ "WebLogic 3.", "WebLogic 4.","WebLogic 5.", "WebLogic 6.",
"Winstone Servlet Engine v0.", nsnull }, // w
{ nsnull }, { nsnull }, { nsnull } // x - z
};

View File

@ -358,7 +358,7 @@ mozTXTToHTMLConv::FindURLEnd(const PRUnichar * aInString, PRInt32 aInStringLengt
while (--i > pos && (
aInString[i] == '.' || aInString[i] == ',' || aInString[i] == ';' ||
aInString[i] == '!' || aInString[i] == '?' || aInString[i] == '-' ||
aInString[i] == '\''
aInString[i] == ':' || aInString[i] == '\''
))
;
if (i > pos)

View File

@ -499,21 +499,7 @@ SimpleTest.waitForFocus = function (callback, targetWindow, expectBlankPage) {
return SpecialPowers.getPrivilegedProps(aWindow, 'location.href');
}
function debugFocusLog(prefix) {
info(prefix + " -- loaded: " + targetWindow.document.readyState +
" active window: " +
(SpecialPowers.activeWindow() ? "(" + SpecialPowers.activeWindow() + ") " + getHref(SpecialPowers.activeWindow()) : "<no window active>") +
" focused window: " +
(SpecialPowers.focusedWindow() ? "(" + SpecialPowers.focusedWindow() + ") " + getHref(SpecialPowers.focusedWindow()) : "<no window focused>") +
" desired window: (" + targetWindow + ") " + getHref(targetWindow) +
" child window: (" + childTargetWindow + ") " + getHref(childTargetWindow));
}
debugFocusLog("before wait for focus");
function maybeRunTests() {
debugFocusLog("maybe run tests <load:" +
SimpleTest.waitForFocus_loaded + ", focus:" + SimpleTest.waitForFocus_focused + ">");
if (SimpleTest.waitForFocus_loaded &&
SimpleTest.waitForFocus_focused &&
!SimpleTest.waitForFocus_started) {
@ -524,8 +510,6 @@ SimpleTest.waitForFocus = function (callback, targetWindow, expectBlankPage) {
function waitForEvent(event) {
try {
debugFocusLog("waitForEvent called <type:" + event.type + ", target" + event.target + ">");
// Check to make sure that this isn't a load event for a blank or
// non-blank page that wasn't desired.
if (event.type == "load" && (expectBlankPage != (event.target.location == "about:blank")))
@ -564,7 +548,6 @@ SimpleTest.waitForFocus = function (callback, targetWindow, expectBlankPage) {
// If this is a child frame, ensure that the frame is focused.
SimpleTest.waitForFocus_focused = (focusedChildWindow == childTargetWindow);
if (SimpleTest.waitForFocus_focused) {
info("already focused");
// If the frame is already focused and loaded, call the callback directly.
maybeRunTests();
}

View File

@ -418,43 +418,6 @@ nsNavBookmarks::CreateRoot(const nsCString& name,
return NS_OK;
}
bool
nsNavBookmarks::IsRealBookmark(PRInt64 aPlaceId)
{
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
"SELECT id "
"FROM moz_bookmarks "
"WHERE fk = :page_id "
"AND type = :item_type "
"AND parent NOT IN ("
"SELECT a.item_id "
"FROM moz_items_annos a "
"JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id "
"WHERE n.name = :anno_name"
") "
);
NS_ENSURE_TRUE(stmt, false);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("page_id"), aPlaceId);
NS_ENSURE_SUCCESS(rv, false);
rv = stmt->BindInt32ByName(NS_LITERAL_CSTRING("item_type"), TYPE_BOOKMARK);
NS_ENSURE_SUCCESS(rv, false);
rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("anno_name"),
NS_LITERAL_CSTRING(LMANNO_FEEDURI));
NS_ENSURE_SUCCESS(rv, false);
// If we get any rows, then there exists at least one bookmark corresponding
// to aPlaceId that is not a livemark item.
bool isBookmark = false;
rv = stmt->ExecuteStep(&isBookmark);
NS_ENSURE_SUCCESS(rv, false);
return isBookmark;
}
// nsNavBookmarks::IsBookmarkedInDatabase
//
// This checks to see if the specified place_id is actually bookmarked.

View File

@ -225,15 +225,6 @@ public:
PRInt32* aIndex,
PRInt64* aNewFolder);
/**
* Determines if we have a real bookmark or not (not a livemark).
*
* @param aPlaceId
* The place_id of the location to check against.
* @return true if it's a real bookmark, false otherwise.
*/
bool IsRealBookmark(PRInt64 aPlaceId);
/**
* Fetches information about the specified id from the database.
*

View File

@ -90,6 +90,7 @@ function run_test()
timesUsed = stmt.getInt32(0);
firstUsed = stmt.getInt64(1);
lastUsed = stmt.getInt64(2);
stmt.finalize();
do_check_eq(1, timesUsed);
do_check_true(firstUsed == lastUsed);
@ -122,6 +123,7 @@ function run_test()
timesUsed = stmt.getInt32(0);
firstUsed = stmt.getInt64(1);
lastUsed = stmt.getInt64(2);
stmt.finalize();
do_check_eq(1, timesUsed);
do_check_true(firstUsed == lastUsed);
@ -158,6 +160,7 @@ function delayed_test() {
timesUsed = stmt.getInt32(0);
var firstUsed2 = stmt.getInt64(1);
var lastUsed2 = stmt.getInt64(2);
stmt.finalize();
do_check_eq(2, timesUsed);
do_check_true(is_about_now(lastUsed2));

View File

@ -91,6 +91,7 @@ function run_test()
timesUsed = stmt.getInt32(0);
firstUsed = stmt.getInt64(1);
lastUsed = stmt.getInt64(2);
stmt.finalize();
do_check_eq(1, timesUsed);
do_check_true(firstUsed == lastUsed);
@ -110,6 +111,7 @@ function run_test()
timesUsed = stmt.getInt32(0);
firstUsed = stmt.getInt64(1);
lastUsed = stmt.getInt64(2);
stmt.finalize();
do_check_eq(1, timesUsed);
do_check_eq(lastUsed, 1231984073012182);

View File

@ -180,6 +180,14 @@ function populateGraphicsSection() {
]));
}
}
function pushLiteralInfoRow(table, name, value)
{
table.push(createParentElement("tr", [
createHeader(name),
createElement("td", value),
]));
}
function errorMessageForFeature(feature) {
var errorMessage;
@ -308,6 +316,15 @@ function populateGraphicsSection() {
pushFeatureInfoRow(trGraphics, "webglRenderer", webglfeature, webglenabled, webglrenderer);
appendChildren(graphics_tbody, trGraphics);
// display registered graphics properties
let graphics_info_properties = document.getElementById("graphics-info-properties");
var info = gfxInfo.getInfo();
let trGraphicsProperties = [];
for (var property in info) {
pushLiteralInfoRow(trGraphicsProperties, property, info[property]);
}
appendChildren(graphics_info_properties, trGraphicsProperties);
// display any failures that have occurred
let graphics_failures_tbody = document.getElementById("graphics-failures-tbody");
@ -318,6 +335,8 @@ function populateGraphicsSection() {
);
appendChildren(graphics_failures_tbody, trGraphicsFailures);
} // end if (gfxInfo)
let windows = Services.ww.getWindowEnumerator();

View File

@ -225,6 +225,11 @@
</tbody>
</table>
<table>
<tbody id="graphics-info-properties">
</tbody>
</table>
<table>
<tbody id="graphics-failures-tbody">
</tbody>

View File

@ -362,7 +362,7 @@ ifdef HAVE_CLOCK_MONOTONIC
EXTRA_DSO_LDOPTS += $(REALTIME_LIBS)
endif
ifeq (,$(filter-out cocoa android,$(MOZ_WIDGET_TOOLKIT)))
ifeq (,$(filter-out cocoa android windows,$(MOZ_WIDGET_TOOLKIT)))
EXTRA_DSO_LDOPTS += $(MOZ_SKIA_LIBS)
endif

View File

@ -979,6 +979,37 @@ var AddonManagerInternal = {
});
},
/**
* Asynchronously get an add-on with a specific Sync GUID.
*
* @param aGUID
* String GUID of add-on to retrieve
* @param aCallback
* The callback to pass the retrieved add-on to.
* @throws if the aGUID or aCallback arguments are not specified
*/
getAddonBySyncGUID: function AMI_getAddonBySyncGUID(aGUID, aCallback) {
if (!aGUID || !aCallback) {
throw Cr.NS_ERROR_INVALID_ARG;
}
new AsyncObjectCaller(this.providers, "getAddonBySyncGUID", {
nextObject: function(aCaller, aProvider) {
callProvider(aProvider, "getAddonBySyncGUID", null, aGUID, function(aAddon) {
if (aAddon) {
safeCall(aCallback, aAddon);
} else {
aCaller.callNext();
}
});
},
noMoreObjects: function(aCaller) {
safeCall(aCallback, null);
}
});
},
/**
* Asynchronously gets an array of add-ons.
*
@ -1377,6 +1408,10 @@ var AddonManager = {
AddonManagerInternal.getAddonByID(aId, aCallback);
},
getAddonBySyncGUID: function AM_getAddonBySyncGUID(aId, aCallback) {
AddonManagerInternal.getAddonBySyncGUID(aId, aCallback);
},
getAddonsByIDs: function AM_getAddonsByIDs(aIds, aCallback) {
AddonManagerInternal.getAddonsByIDs(aIds, aCallback);
},

View File

@ -127,7 +127,7 @@ const TOOLKIT_ID = "toolkit@mozilla.org";
const BRANCH_REGEXP = /^([^\.]+\.[0-9]+[a-z]*).*/gi;
const DB_SCHEMA = 8;
const DB_SCHEMA = 9;
const REQ_VERSION = 2;
#ifdef MOZ_COMPATIBILITY_NIGHTLY
@ -147,8 +147,13 @@ const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
// Properties that only exist in the database
const DB_METADATA = ["installDate", "updateDate", "size", "sourceURI",
"releaseNotesURI", "applyBackgroundUpdates"];
const DB_METADATA = ["syncGUID",
"installDate",
"updateDate",
"size",
"sourceURI",
"releaseNotesURI",
"applyBackgroundUpdates"];
const DB_BOOL_METADATA = ["visible", "active", "userDisabled", "appDisabled",
"pendingUninstall", "bootstrap", "skinnable",
"softDisabled", "foreignInstall",
@ -2471,6 +2476,7 @@ var XPIProvider = {
// the applyBlocklistChanges code
let newAddon = new AddonInternal();
newAddon.id = aOldAddon.id;
newAddon.syncGUID = aOldAddon.syncGUID;
newAddon.version = aOldAddon.version;
newAddon.type = aOldAddon.type;
newAddon.appDisabled = !isUsableAddon(aOldAddon);
@ -2641,6 +2647,8 @@ var XPIProvider = {
// preference which is read in loadManifestFromRDF
if (newAddon.type != "theme")
newAddon.userDisabled = aMigrateData.userDisabled;
if ("syncGUID" in aMigrateData)
newAddon.syncGUID = aMigrateData.syncGUID;
if ("installDate" in aMigrateData)
newAddon.installDate = aMigrateData.installDate;
if ("softDisabled" in aMigrateData)
@ -3190,6 +3198,23 @@ var XPIProvider = {
});
},
/**
* Obtain an Addon having the specified Sync GUID.
*
* @param aGUID
* String GUID of add-on to retrieve
* @param aCallback
* A callback to pass the Addon to. Receives null if not found.
*/
getAddonBySyncGUID: function XPI_getAddonBySyncGUID(aGUID, aCallback) {
XPIDatabase.getAddonBySyncGUID(aGUID, function(aAddon) {
if (aAddon)
aCallback(createWrapper(aAddon));
else
aCallback(null);
});
},
/**
* Called to get Addons that have pending operations.
*
@ -3917,10 +3942,11 @@ var XPIProvider = {
}
};
const FIELDS_ADDON = "internal_id, id, location, version, type, internalName, " +
"updateURL, updateKey, optionsURL, optionsType, aboutURL, " +
"iconURL, icon64URL, defaultLocale, visible, active, " +
"userDisabled, appDisabled, pendingUninstall, descriptor, " +
const FIELDS_ADDON = "internal_id, id, syncGUID, location, version, type, " +
"internalName, updateURL, updateKey, optionsURL, " +
"optionsType, aboutURL, iconURL, icon64URL, " +
"defaultLocale, visible, active, userDisabled, " +
"appDisabled, pendingUninstall, descriptor, " +
"installDate, updateDate, applyBackgroundUpdates, bootstrap, " +
"skinnable, size, sourceURI, releaseNotesURI, softDisabled, " +
"foreignInstall, hasBinaryComponents, strictCompatibility";
@ -4063,9 +4089,10 @@ var XPIDatabase = {
_readLocaleStrings: "SELECT locale_id, type, value FROM locale_strings " +
"WHERE locale_id=:id",
addAddonMetadata_addon: "INSERT INTO addon VALUES (NULL, :id, :location, " +
":version, :type, :internalName, :updateURL, " +
":updateKey, :optionsURL, :optionsType, :aboutURL, " +
addAddonMetadata_addon: "INSERT INTO addon VALUES (NULL, :id, :syncGUID, " +
":location, :version, :type, :internalName, " +
":updateURL, :updateKey, :optionsURL, " +
":optionsType, :aboutURL, " +
":iconURL, :icon64URL, :locale, :visible, :active, " +
":userDisabled, :appDisabled, :pendingUninstall, " +
":descriptor, :installDate, :updateDate, " +
@ -4112,7 +4139,8 @@ var XPIDatabase = {
"addon WHERE visible=1 " +
"AND (pendingUninstall=1 OR " +
"MAX(userDisabled,appDisabled)=active)",
getAddonBySyncGUID: "SELECT " + FIELDS_ADDON + " FROM addon " +
"WHERE syncGUID=:syncGUID",
makeAddonVisible: "UPDATE addon SET visible=1 WHERE internal_id=:internal_id",
removeAddonMetadata: "DELETE FROM addon WHERE internal_id=:internal_id",
// Equates to active = visible && !userDisabled && !softDisabled &&
@ -4127,6 +4155,8 @@ var XPIDatabase = {
"internal_id=:internal_id",
setAddonDescriptor: "UPDATE addon SET descriptor=:descriptor WHERE " +
"internal_id=:internal_id",
setAddonSyncGUID: "UPDATE addon SET syncGUID=:syncGUID WHERE " +
"internal_id=:internal_id",
updateTargetApplications: "UPDATE targetApplication SET " +
"minVersion=:minVersion, maxVersion=:maxVersion " +
"WHERE addon_internal_id=:internal_id AND id=:id",
@ -4449,6 +4479,9 @@ var XPIDatabase = {
// Build a list of sql statements that might recover useful data from this
// and future versions of the schema
var sql = [];
sql.push("SELECT internal_id, id, syncGUID, location, userDisabled, " +
"softDisabled, installDate, version, applyBackgroundUpdates, " +
"sourceURI, releaseNotesURI, foreignInstall FROM addon");
sql.push("SELECT internal_id, id, location, userDisabled, " +
"softDisabled, installDate, version, applyBackgroundUpdates, " +
"sourceURI, releaseNotesURI, foreignInstall FROM addon");
@ -4486,6 +4519,8 @@ var XPIDatabase = {
targetApplications: []
};
if ("syncGUID" in row)
migrateData[row.location][row.id].syncGUID = row.syncGUID;
if ("softDisabled" in row)
migrateData[row.location][row.id].softDisabled = row.softDisabled == 1;
if ("applyBackgroundUpdates" in row)
@ -4603,7 +4638,8 @@ var XPIDatabase = {
try {
this.connection.createTable("addon",
"internal_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id TEXT, location TEXT, version TEXT, " +
"id TEXT, syncGUID TEXT, " +
"location TEXT, version TEXT, " +
"type TEXT, internalName TEXT, updateURL TEXT, " +
"updateKey TEXT, optionsURL TEXT, " +
"optionsType TEXT, aboutURL TEXT, iconURL TEXT, " +
@ -4619,7 +4655,8 @@ var XPIDatabase = {
"foreignInstall INTEGER, " +
"hasBinaryComponents INTEGER, " +
"strictCompatibility INTEGER, " +
"UNIQUE (id, location)");
"UNIQUE (id, location), " +
"UNIQUE (syncGUID)");
this.connection.createTable("targetApplication",
"addon_internal_id INTEGER, " +
"id TEXT, minVersion TEXT, maxVersion TEXT, " +
@ -5203,6 +5240,29 @@ var XPIDatabase = {
stmt.executeAsync(new AsyncAddonListCallback(aCallback));
},
/**
* Asynchronously get an add-on by its Sync GUID.
*
* @param aGUID
* Sync GUID of add-on to fetch
* @param aCallback
* A callback to pass the DBAddonInternal record to. Receives null
* if no add-on with that GUID is found.
*
*/
getAddonBySyncGUID: function XPIDB_getAddonBySyncGUID(aGUID, aCallback) {
let stmt = this.getStatement("getAddonBySyncGUID");
stmt.params.syncGUID = aGUID;
stmt.executeAsync(new AsyncAddonListCallback(function(aAddons) {
if (aAddons.length == 0) {
aCallback(null);
return;
}
aCallback(aAddons[0]);
}));
},
/**
* Synchronously gets all add-ons in the database.
*
@ -5226,6 +5286,18 @@ var XPIDatabase = {
* The file descriptor of the add-on
*/
addAddonMetadata: function XPIDB_addAddonMetadata(aAddon, aDescriptor) {
// Create a GUID if one does not exist
if (!aAddon.syncGUID) {
let rng = Cc["@mozilla.org/security/random-generator;1"].
createInstance(Ci.nsIRandomGenerator);
let bytes = rng.generateRandomBytes(9);
let byte_string = [String.fromCharCode(byte) for each (byte in bytes)]
.join("");
// Base64 encode
aAddon.syncGUID = btoa(byte_string).replace('+', '-', 'g')
.replace('/', '_', 'g');
}
// If there is no DB yet then forcibly create one
if (!this.connection)
this.openConnection(false, true);
@ -5330,11 +5402,13 @@ var XPIDatabase = {
// Any errors in here should rollback the transaction
try {
this.removeAddonMetadata(aOldAddon);
aNewAddon.syncGUID = aOldAddon.syncGUID;
aNewAddon.installDate = aOldAddon.installDate;
aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates;
aNewAddon.foreignInstall = aOldAddon.foreignInstall;
aNewAddon.active = (aNewAddon.visible && !aNewAddon.userDisabled &&
!aNewAddon.appDisabled)
this.addAddonMetadata(aNewAddon, aDescriptor);
this.commitTransaction();
}
@ -5445,6 +5519,22 @@ var XPIDatabase = {
executeStatement(stmt);
},
/**
* Synchronously sets the Sync GUID for an add-on.
*
* @param aAddon
* The DBAddonInternal being updated
* @param aGUID
* GUID string to set the value to
*/
setAddonSyncGUID: function XPIDB_setAddonSyncGUID(aAddon, aGUID) {
let stmt = this.getStatement("setAddonSyncGUID");
stmt.params.internal_id = aAddon._internal_id;
stmt.params.syncGUID = aGUID;
executeStatement(stmt);
},
/**
* Synchronously sets the file descriptor for an add-on.
*
@ -7267,7 +7357,7 @@ function AddonWrapper(aAddon) {
return [objValue, false];
}
["id", "version", "type", "isCompatible", "isPlatformCompatible",
["id", "syncGUID", "version", "type", "isCompatible", "isPlatformCompatible",
"providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
"softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents",
"strictCompatibility"].forEach(function(aProp) {
@ -7449,6 +7539,16 @@ function AddonWrapper(aAddon) {
return val;
});
this.__defineSetter__("syncGUID", function(val) {
if (aAddon.syncGUID == val)
return val;
XPIDatabase.setAddonSyncGUID(aAddon, val);
aAddon.syncGUID = val;
return val;
});
this.__defineGetter__("install", function() {
if (!("_install" in aAddon) || !aAddon._install)
return null;

View File

@ -72,6 +72,7 @@ function run_test_1() {
do_check_eq(install.name, "Test 1");
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
do_check_true(install.addon.hasResource("install.rdf"));
do_check_eq(install.addon.syncGUID, null);
do_check_eq(install.addon.install, install);
do_check_eq(install.addon.size, ADDON1_SIZE);
do_check_true(hasFlag(install.addon.operationsRequiringRestart,
@ -157,6 +158,8 @@ function check_test_1() {
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
do_check_neq(a1, null);
do_check_neq(a1.syncGUID, null);
do_check_true(a1.syncGUID.length >= 9);
do_check_eq(a1.type, "extension");
do_check_eq(a1.version, "1.0");
do_check_eq(a1.name, "Test 1");
@ -274,6 +277,7 @@ function check_test_3(aInstall) {
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
do_check_neq(a2, null);
do_check_neq(a2.syncGUID, null);
do_check_eq(a2.type, "extension");
do_check_eq(a2.version, "2.0");
do_check_eq(a2.name, "Real Test 2");
@ -462,6 +466,7 @@ function check_test_7() {
AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
do_check_neq(a3, null);
do_check_neq(a3.syncGUID, null);
do_check_eq(a3.type, "extension");
do_check_eq(a3.version, "1.0");
do_check_eq(a3.name, "Real Test 4");
@ -506,6 +511,7 @@ function check_test_8() {
AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
do_check_neq(a3, null);
do_check_neq(a3.syncGUID, null);
do_check_eq(a3.type, "extension");
do_check_eq(a3.version, "1.0");
do_check_eq(a3.name, "Real Test 4");

View File

@ -82,6 +82,8 @@ profileDir.append("extensions");
do_load_httpd_js();
var testserver;
let oldSyncGUIDs = {};
function prepare_profile() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
@ -114,7 +116,11 @@ function prepare_profile() {
a2.applyBackgroundUpdates = false;
a4.userDisabled = true;
a6.userDisabled = true;
for each (let addon in [a1, a2, a3, a4, a5, a6]) {
oldSyncGUIDs[addon.id] = addon.syncGUID;
}
a6.findUpdates({
onUpdateAvailable: function(aAddon, aInstall6) {
AddonManager.getInstallForURL("http://localhost:4444/addons/test_migrate4_7.xpi", function(aInstall7) {
@ -180,6 +186,7 @@ function test_results() {
function([a1, a2, a3, a4, a5, a6, a7, a8]) {
// addon1 was enabled
do_check_neq(a1, null);
do_check_eq(a1.syncGUID, oldSyncGUIDs[a1.id]);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
@ -190,6 +197,7 @@ function test_results() {
// addon2 was disabled
do_check_neq(a2, null);
do_check_eq(a2.syncGUID, oldSyncGUIDs[a2.id]);
do_check_true(a2.userDisabled);
do_check_false(a2.appDisabled);
do_check_false(a2.isActive);
@ -200,6 +208,7 @@ function test_results() {
// addon3 was pending-disable in the database
do_check_neq(a3, null);
do_check_eq(a3.syncGUID, oldSyncGUIDs[a3.id]);
do_check_true(a3.userDisabled);
do_check_false(a3.appDisabled);
do_check_false(a3.isActive);
@ -210,6 +219,7 @@ function test_results() {
// addon4 was pending-enable in the database
do_check_neq(a4, null);
do_check_eq(a4.syncGUID, oldSyncGUIDs[a4.id]);
do_check_false(a4.userDisabled);
do_check_false(a4.appDisabled);
do_check_true(a4.isActive);
@ -230,6 +240,7 @@ function test_results() {
// addon6 was disabled and compatible but a new version has been installed
do_check_neq(a6, null);
do_check_eq(a6.syncGUID, oldSyncGUIDs[a6.id]);
do_check_eq(a6.version, "2.0");
do_check_true(a6.userDisabled);
do_check_false(a6.appDisabled);

View File

@ -208,6 +208,8 @@ function run_test_1() {
do_check_neq(a1, null);
do_check_eq(a1.id, "addon1@tests.mozilla.org");
do_check_neq(a1.syncGUID, null);
do_check_true(a1.syncGUID.length >= 9);
do_check_eq(a1.version, "1.0");
do_check_eq(a1.name, "Test 1");
do_check_true(isExtensionInAddonsList(profileDir, a1.id));
@ -220,6 +222,8 @@ function run_test_1() {
do_check_neq(a2, null);
do_check_eq(a2.id, "addon2@tests.mozilla.org");
do_check_neq(a2.syncGUID, null);
do_check_true(a2.syncGUID.length >= 9);
do_check_eq(a2.version, "2.0");
do_check_eq(a2.name, "Test 2");
do_check_true(isExtensionInAddonsList(profileDir, a2.id));
@ -232,6 +236,8 @@ function run_test_1() {
do_check_neq(a3, null);
do_check_eq(a3.id, "addon3@tests.mozilla.org");
do_check_neq(a3.syncGUID, null);
do_check_true(a3.syncGUID.length >= 9);
do_check_eq(a3.version, "3.0");
do_check_eq(a3.name, "Test 3");
do_check_true(isExtensionInAddonsList(profileDir, a3.id));

View File

@ -0,0 +1,151 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
Components.utils.import("resource://gre/modules/Services.jsm");
// restartManager() mucks with XPIProvider.jsm importing, so we hack around.
this.__defineGetter__("XPIProvider", function () {
let scope = {};
return Components.utils.import("resource://gre/modules/XPIProvider.jsm", scope)
.XPIProvider;
});
const addonId = "addon1@tests.mozilla.org";
function run_test() {
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
startupManager();
run_next_test();
}
add_test(function test_getter_and_setter() {
// Our test add-on requires a restart.
let listener = {
onInstallEnded: function onInstallEnded() {
restartManager();
AddonManager.getAddonByID(addonId, function(addon) {
do_check_neq(addon, null);
do_check_neq(addon.syncGUID, null);
do_check_true(addon.syncGUID.length >= 9);
let oldGUID = addon.SyncGUID;
let newGUID = "foo";
addon.syncGUID = newGUID;
do_check_eq(newGUID, addon.syncGUID);
// Verify change made it to DB.
AddonManager.getAddonByID(addonId, function(newAddon) {
do_check_neq(newAddon, null);
do_check_eq(newGUID, newAddon.syncGUID);
});
AddonManager.removeInstallListener(listener);
run_next_test();
});
}
};
AddonManager.addInstallListener(listener);
AddonManager.getInstallForFile(do_get_addon("test_install1"),
function(install) {
install.install();
});
});
add_test(function test_fetch_by_guid_unknown_guid() {
XPIProvider.getAddonBySyncGUID("XXXX", function(addon) {
do_check_eq(null, addon);
run_next_test();
});
});
// Ensure setting an extension to an existing syncGUID results in error.
add_test(function test_error_on_duplicate_syncguid_insert() {
const installNames = ["test_install1", "test_install2_1"];
const installIDs = ["addon1@tests.mozilla.org", "addon2@tests.mozilla.org"];
let installCount = 0;
let listener = {
onInstallEnded: function onInstallEnded() {
installCount++;
if (installCount == installNames.length) {
AddonManager.removeInstallListener(listener);
restartManager();
AddonManager.getAddonsByIDs(installIDs, function(addons) {
let initialGUID = addons[1].syncGUID;
try {
addons[1].syncGUID = addons[0].syncGUID;
do_throw("Should not get here.");
}
catch (e) {
do_check_eq(e.result,
Components.results.NS_ERROR_STORAGE_CONSTRAINT);
restartManager();
AddonManager.getAddonByID(installIDs[1], function(addon) {
do_check_eq(initialGUID, addon.syncGUID);
run_next_test();
});
}
});
}
}
};
AddonManager.addInstallListener(listener);
let getInstallCB = function(install) { install.install(); };
for each (let name in installNames) {
AddonManager.getInstallForFile(do_get_addon(name), getInstallCB);
}
});
add_test(function test_fetch_by_guid_known_guid() {
AddonManager.getAddonByID(addonId, function(addon) {
do_check_neq(null, addon);
do_check_neq(null, addon.syncGUID);
let syncGUID = addon.syncGUID;
XPIProvider.getAddonBySyncGUID(syncGUID, function(newAddon) {
do_check_neq(null, newAddon);
do_check_eq(syncGUID, newAddon.syncGUID);
run_next_test();
});
});
});
add_test(function test_addon_manager_get_by_sync_guid() {
AddonManager.getAddonByID(addonId, function(addon) {
do_check_neq(null, addon.syncGUID);
let syncGUID = addon.syncGUID;
AddonManager.getAddonBySyncGUID(syncGUID, function(newAddon) {
do_check_neq(null, newAddon);
do_check_eq(addon.id, newAddon.id);
do_check_eq(syncGUID, newAddon.syncGUID);
AddonManager.getAddonBySyncGUID("DOES_NOT_EXIST", function(missing) {
do_check_eq(undefined, missing);
run_next_test();
});
});
});
});

View File

@ -27,6 +27,8 @@ var testserver;
const profileDir = gProfD.clone();
profileDir.append("extensions");
let originalSyncGUID;
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, false);
@ -92,7 +94,9 @@ function run_test_1() {
do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_eq(a1.releaseNotesURI, null);
do_check_true(a1.foreignInstall);
do_check_neq(a1.syncGUID, null);
originalSyncGUID = a1.syncGUID;
a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
prepare_test({
@ -222,6 +226,8 @@ function check_test_2() {
do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
do_check_eq(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
do_check_true(a1.foreignInstall);
do_check_neq(a1.syncGUID, null);
do_check_eq(originalSyncGUID, a1.syncGUID);
a1.uninstall();
restartManager();
@ -1016,6 +1022,45 @@ function check_test_15(aInstall) {
restartManager();
end_test();
run_test_16();
});
}
function run_test_16() {
restartManager();
let url = "http://localhost:4444/addons/test_install2_1.xpi";
AddonManager.getInstallForURL(url, function(aInstall) {
aInstall.addListener({
onInstallEnded: function() {
restartManager();
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a1) {
do_check_neq(a1.syncGUID, null);
let oldGUID = a1.syncGUID;
let url = "http://localhost:4444/addons/test_install2_2.xpi";
AddonManager.getInstallForURL(url, function(aInstall) {
aInstall.addListener({
onInstallEnded: function() {
restartManager();
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
do_check_neq(a2.syncGUID, null);
do_check_eq(oldGUID, a2.syncGUID);
a2.uninstall();
restartManager();
end_test();
});
}
});
aInstall.install();
}, "application/x-xpinstall");
});
}
});
aInstall.install();
}, "application/x-xpinstall");
}

View File

@ -95,6 +95,9 @@ function check_test_1(install) {
do_check_neq(a1.pendingUpgrade, null);
do_check_eq(a1.pendingUpgrade.id, "addon2@tests.mozilla.org");
do_check_eq(a1.pendingUpgrade.install.existingAddon, a1);
do_check_neq(a1.syncGUID);
let a1SyncGUID = a1.syncGUID;
restartManager();
@ -103,6 +106,10 @@ function check_test_1(install) {
// Should have uninstalled the old and installed the new
do_check_eq(a1, null);
do_check_neq(a2, null);
do_check_neq(a2.syncGUID, null);
// The Sync GUID should change when the ID changes
do_check_neq(a1SyncGUID, a2.syncGUID);
a2.uninstall();
@ -283,6 +290,7 @@ function run_test_4() {
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
do_check_neq(a2, null);
do_check_neq(a2.syncGUID, null);
do_check_eq(a2.version, "2.0");
a2.findUpdates({

View File

@ -183,6 +183,7 @@ fail-if = os == "android"
[test_startup.js]
# Bug 676992: test consistently fails on Android
fail-if = os == "android"
[test_syncGUID.js]
[test_strictcompatibility.js]
[test_targetPlatforms.js]
[test_theme.js]

View File

@ -71,10 +71,10 @@ nsNativeAppSupportQt::displayStateChanged(MeeGo::QmDisplayState::DisplayState st
os->NotifyObservers(nsnull, "system-display-on", nsnull);
break;
case MeeGo::QmDisplayState::Off:
os->NotifyObservers(nsnull, "system-display-dimmed", nsnull);
os->NotifyObservers(nsnull, "system-display-off", nsnull);
break;
case MeeGo::QmDisplayState::Dimmed:
os->NotifyObservers(nsnull, "system-display-off", nsnull);
os->NotifyObservers(nsnull, "system-display-dimmed", nsnull);
break;
default:
NS_WARNING("Unknown display state");

View File

@ -370,7 +370,12 @@ public:
/**
* Return the appropriate WindowsThemeIdentifier for the current theme.
*/
eIntID_WindowsThemeIdentifier
eIntID_WindowsThemeIdentifier,
/**
* 0: scrollbar button repeats to scroll only when cursor is on the button.
* 1: scrollbar button repeats to scroll even if cursor is outside of it.
*/
eIntID_ScrollbarButtonAutoRepeatBehavior
};
/**

View File

@ -1303,6 +1303,14 @@ AndroidBridge::HandleGeckoMessage(const nsAString &aMessage, nsAString &aRet)
ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
}
static nsCOMPtr<nsIAndroidDrawMetadataProvider> gDrawMetadataProvider = NULL;
nsCOMPtr<nsIAndroidDrawMetadataProvider>
AndroidBridge::GetDrawMetadataProvider()
{
return gDrawMetadataProvider;
}
void
AndroidBridge::CheckURIVisited(const nsAString& aURI)
{
@ -1455,3 +1463,11 @@ NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(const nsAString & message, nsA
AndroidBridge::Bridge()->HandleGeckoMessage(message, aRet);
return NS_OK;
}
/* void SetDrawMetadataProvider (in nsIAndroidDrawMetadataProvider message); */
NS_IMETHODIMP nsAndroidBridge::SetDrawMetadataProvider(nsIAndroidDrawMetadataProvider *aProvider)
{
gDrawMetadataProvider = aProvider;
return NS_OK;
}

View File

@ -300,6 +300,8 @@ public:
void HandleGeckoMessage(const nsAString& message, nsAString &aRet);
nsCOMPtr<nsIAndroidDrawMetadataProvider> GetDrawMetadataProvider();
void EmitGeckoAccessibilityEvent (PRInt32 eventType, const nsAString& role, const nsAString& text, const nsAString& description, bool enabled, bool checked, bool password);
void CheckURIVisited(const nsAString& uri);

View File

@ -325,7 +325,7 @@ AndroidGeckoSoftwareLayerClient::InitGeckoSoftwareLayerClientClass(JNIEnv *jEnv)
jLockBufferMethod = getMethod("lockBuffer", "()Ljava/nio/ByteBuffer;");
jUnlockBufferMethod = getMethod("unlockBuffer", "()V");
jBeginDrawingMethod = getMethod("beginDrawing", "()V");
jEndDrawingMethod = getMethod("endDrawing", "(IIII)V");
jEndDrawingMethod = getMethod("endDrawing", "(IIIILjava/lang/String;)V");
#endif
}
@ -616,12 +616,13 @@ AndroidGeckoSoftwareLayerClient::BeginDrawing()
}
void
AndroidGeckoSoftwareLayerClient::EndDrawing(const nsIntRect &aRect)
AndroidGeckoSoftwareLayerClient::EndDrawing(const nsIntRect &aRect, const nsAString &aMetadata)
{
NS_ASSERTION(!isNull(), "EndDrawing() called on null software layer client!");
AndroidBridge::AutoLocalJNIFrame(1);
jstring jMetadata = JNI()->NewString(nsPromiseFlatString(aMetadata).get(), aMetadata.Length());
return JNI()->CallVoidMethod(wrapped_obj, jEndDrawingMethod, aRect.x, aRect.y, aRect.width,
aRect.height);
aRect.height, jMetadata);
}
jobject

View File

@ -162,7 +162,7 @@ public:
unsigned char *LockBufferBits();
void UnlockBuffer();
void BeginDrawing();
void EndDrawing(const nsIntRect &aRect);
void EndDrawing(const nsIntRect &aRect, const nsAString &aMetadata);
private:
static jclass jGeckoSoftwareLayerClientClass;

View File

@ -1,7 +1,13 @@
#include "nsISupports.idl"
[scriptable, uuid(32c345d4-9f45-446a-8a93-8939f3453e87)]
[scriptable, function, uuid(9feed1e5-bb90-4663-b70a-e03cb27a9e8b)]
interface nsIAndroidDrawMetadataProvider : nsISupports {
AString getDrawMetadata();
};
[scriptable, uuid(7dd8441a-4f38-49b2-bd90-da69d02a96cf)]
interface nsIAndroidBridge : nsISupports
{
AString handleGeckoMessage(in AString message);
void setDrawMetadataProvider(in nsIAndroidDrawMetadataProvider provider);
};

Some files were not shown because too many files have changed in this diff Show More