зеркало из https://github.com/mozilla/pjs.git
Merge last green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
06b1076330
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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())) { }
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -260,10 +260,10 @@ var gTests = [
|
|||
function nextTest() {
|
||||
if (gTests.length) {
|
||||
var test = gTests.shift();
|
||||
waitForFocus(function() {
|
||||
info("Start of test: " + test.desc);
|
||||
test.run();
|
||||
|
||||
waitForFocus(nextTest);
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Collapse the personal toolbar if needed.
|
||||
|
@ -283,6 +283,6 @@ function test() {
|
|||
if (wasCollapsed)
|
||||
setToolbarVisibility(toolbar, true);
|
||||
|
||||
waitForFocus(nextTest);
|
||||
nextTest();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const Cu = Components.utils;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/tabview/utils.jsm");
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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:
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,9 +107,13 @@ CPPSRCS += \
|
|||
SourceSurfaceD2DTarget.cpp \
|
||||
PathD2D.cpp \
|
||||
ScaledFontDWrite.cpp \
|
||||
SourceSurfaceSkia.cpp \
|
||||
DrawTargetSkia.cpp \
|
||||
PathSkia.cpp \
|
||||
ScaledFontSkia.cpp \
|
||||
ScaledFontWin.cpp \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -DWIN32
|
||||
DEFINES += -DWIN32 -DUSE_SKIA
|
||||
endif
|
||||
|
||||
#ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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_ */
|
|
@ -129,6 +129,12 @@ SourceSurfaceSkia::DrawTargetWillChange()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::DrawTargetDestroyed()
|
||||
{
|
||||
mDrawTarget = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceSkia::MarkIndependent()
|
||||
{
|
||||
|
@ -138,6 +144,5 @@ SourceSurfaceSkia::MarkIndependent()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ private:
|
|||
friend class DrawTargetSkia;
|
||||
|
||||
void DrawTargetWillChange();
|
||||
void DrawTargetDestroyed();
|
||||
void MarkIndependent();
|
||||
|
||||
SkBitmap mBitmap;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
bool
|
||||
static inline bool
|
||||
IsOperatorBoundByMask(CompositionOp aOp) {
|
||||
switch (aOp) {
|
||||
case OP_IN:
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -85,6 +85,7 @@ protected:
|
|||
nsRefPtr<gfxASurface> mSurface;
|
||||
nsRefPtr<GLContext> mGLContext;
|
||||
nsRefPtr<IDirect3DTexture9> mTexture;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
PRUint32 mCanvasFramebuffer;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
|
@ -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,7 +1655,71 @@ public:
|
|||
return kRadial2_GradientType;
|
||||
}
|
||||
|
||||
virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
|
||||
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;
|
||||
}
|
||||
|
||||
// we don't have a span16 proc
|
||||
fFlags &= ~kHasSpan16_Flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(Two_Point_Radial_Gradient, (buffer));
|
||||
}
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& buffer) {
|
||||
this->INHERITED::flatten(buffer);
|
||||
buffer.writeScalar(fCenter1.fX);
|
||||
buffer.writeScalar(fCenter1.fY);
|
||||
buffer.writeScalar(fCenter2.fX);
|
||||
buffer.writeScalar(fCenter2.fY);
|
||||
buffer.writeScalar(fRadius1);
|
||||
buffer.writeScalar(fRadius2);
|
||||
}
|
||||
|
||||
protected:
|
||||
Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer)
|
||||
: Gradient_Shader(buffer),
|
||||
fCenter1(unflatten_point(buffer)),
|
||||
fCenter2(unflatten_point(buffer)),
|
||||
fRadius1(buffer.readScalar()),
|
||||
fRadius2(buffer.readScalar()) {
|
||||
init();
|
||||
};
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
typedef Gradient_Shader INHERITED;
|
||||
const SkPoint fCenter1;
|
||||
const SkPoint fCenter2;
|
||||
const SkScalar fRadius1;
|
||||
const SkScalar fRadius2;
|
||||
SkPoint fDiff;
|
||||
SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
|
||||
|
||||
void init() {
|
||||
fDiff = fCenter1 - fCenter2;
|
||||
fDiffRadius = fRadius2 - fRadius1;
|
||||
SkScalar inv = SkScalarInvert(fDiffRadius);
|
||||
fDiff.fX = SkScalarMul(fDiff.fX, inv);
|
||||
fDiff.fY = SkScalarMul(fDiff.fY, inv);
|
||||
fStartRadius = SkScalarMul(fRadius1, inv);
|
||||
fSr2D2 = SkScalarSquare(fStartRadius);
|
||||
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.
|
||||
|
@ -1747,68 +1813,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual bool setContext(const SkBitmap& device,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix& matrix) {
|
||||
if (!this->INHERITED::setContext(device, paint, matrix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we don't have a span16 proc
|
||||
fFlags &= ~kHasSpan16_Flag;
|
||||
return true;
|
||||
}
|
||||
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
|
||||
return SkNEW_ARGS(Two_Point_Radial_Gradient, (buffer));
|
||||
}
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& buffer) {
|
||||
this->INHERITED::flatten(buffer);
|
||||
buffer.writeScalar(fCenter1.fX);
|
||||
buffer.writeScalar(fCenter1.fY);
|
||||
buffer.writeScalar(fCenter2.fX);
|
||||
buffer.writeScalar(fCenter2.fY);
|
||||
buffer.writeScalar(fRadius1);
|
||||
buffer.writeScalar(fRadius2);
|
||||
}
|
||||
|
||||
protected:
|
||||
Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer)
|
||||
: Gradient_Shader(buffer),
|
||||
fCenter1(unflatten_point(buffer)),
|
||||
fCenter2(unflatten_point(buffer)),
|
||||
fRadius1(buffer.readScalar()),
|
||||
fRadius2(buffer.readScalar()) {
|
||||
init();
|
||||
};
|
||||
virtual Factory getFactory() { return CreateProc; }
|
||||
|
||||
private:
|
||||
typedef Gradient_Shader INHERITED;
|
||||
const SkPoint fCenter1;
|
||||
const SkPoint fCenter2;
|
||||
const SkScalar fRadius1;
|
||||
const SkScalar fRadius2;
|
||||
SkPoint fDiff;
|
||||
SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
|
||||
|
||||
void init() {
|
||||
fDiff = fCenter1 - fCenter2;
|
||||
fDiffRadius = fRadius2 - fRadius1;
|
||||
SkScalar inv = SkScalarInvert(fDiffRadius);
|
||||
fDiff.fX = SkScalarMul(fDiff.fX, inv);
|
||||
fDiff.fY = SkScalarMul(fDiff.fY, inv);
|
||||
fStartRadius = SkScalarMul(fRadius1, inv);
|
||||
fSr2D2 = SkScalarSquare(fStartRadius);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Sweep_Gradient : public Gradient_Shader {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -151,6 +151,11 @@ EXPORTS += \
|
|||
WGLLibrary.h \
|
||||
gfxDWriteFonts.h \
|
||||
gfxD2DSurface.h \
|
||||
gfxGDIFont.h \
|
||||
gfxGDIFontList.h \
|
||||
gfxPlatformFontList.h \
|
||||
gfxAtoms.h \
|
||||
gfxAtomList.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,14 +539,20 @@ 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)
|
||||
{
|
||||
BackendType backend;
|
||||
if (!SupportsAzure(backend)) {
|
||||
return NULL;
|
||||
}
|
||||
return Factory::CreateDrawTarget(backend, aSize, aFormat);
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPlatform::GetFontList(nsIAtom *aLangGroup,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -92,6 +92,8 @@ public:
|
|||
|
||||
virtual PRInt32 GetDefaultContextFlags() const;
|
||||
|
||||
const gfxIntSize GetSize() const;
|
||||
|
||||
void MovePixels(const nsIntRect& aSourceRect,
|
||||
const nsIntPoint& aDestTopLeft)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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> test</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>test</span>
|
||||
<span> test</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -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> 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(" test"));
|
||||
return s;
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,16 +84,31 @@ 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);
|
||||
|
||||
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 nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
|
@ -103,8 +118,6 @@ 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;
|
||||
|
@ -115,9 +128,6 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext,
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the button action metric from the pres. shell.
|
||||
PRInt32 pressedButtonAction;
|
||||
|
@ -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,8 +216,12 @@ 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.
|
||||
if (mCursorOnThis ||
|
||||
LookAndFeel::GetInt(
|
||||
LookAndFeel::eIntID_ScrollbarButtonAutoRepeatBehavior, 0)) {
|
||||
DoButtonAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsScrollbarButtonFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -51,6 +51,7 @@ _TEST_FILES =\
|
|||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
test_bug159346.xul \
|
||||
test_bug372685.xul \
|
||||
test_bug398982-1.xul \
|
||||
test_bug398982-2.xul \
|
||||
|
|
|
@ -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>
|
|
@ -702,6 +702,8 @@ let ContentActive = {
|
|||
case "Content:Deactivate":
|
||||
docShell.isActive = false;
|
||||
let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (json.keepviewport)
|
||||
break;
|
||||
cwu.setDisplayPortForElement(0, 0, 0, 0, content.document.documentElement);
|
||||
break;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -181,6 +181,14 @@ function populateGraphicsSection() {
|
|||
}
|
||||
}
|
||||
|
||||
function pushLiteralInfoRow(table, name, value)
|
||||
{
|
||||
table.push(createParentElement("tr", [
|
||||
createHeader(name),
|
||||
createElement("td", value),
|
||||
]));
|
||||
}
|
||||
|
||||
function errorMessageForFeature(feature) {
|
||||
var errorMessage;
|
||||
var status;
|
||||
|
@ -309,6 +317,15 @@ function populateGraphicsSection() {
|
|||
|
||||
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");
|
||||
let trGraphicsFailures = gfxInfo.getFailures().map(function (value)
|
||||
|
@ -318,6 +335,8 @@ function populateGraphicsSection() {
|
|||
);
|
||||
appendChildren(graphics_failures_tbody, trGraphicsFailures);
|
||||
|
||||
|
||||
|
||||
} // end if (gfxInfo)
|
||||
|
||||
let windows = Services.ww.getWindowEnumerator();
|
||||
|
|
|
@ -225,6 +225,11 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody id="graphics-info-properties">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tbody id="graphics-failures-tbody">
|
||||
</tbody>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
@ -115,6 +117,10 @@ function prepare_profile() {
|
|||
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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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();
|
||||
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -430,6 +430,10 @@ nsLookAndFeel::GetIntImpl(IntID aID, PRInt32 &aResult)
|
|||
aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
|
||||
break;
|
||||
|
||||
case eIntID_ScrollbarButtonAutoRepeatBehavior:
|
||||
aResult = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
aResult = 0;
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче