From aa93536920cab7e6d777985b48dc248e09d41a66 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Wed, 24 Aug 2022 10:13:19 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1208300 (part 1) - Remove unused default arguments from ClearThebesSurface. r=jwatt. (bcb2009a23) - Bug 1208300 (part 2) - Convert gfxRGBA uses to gfx::Color in CompositorBench.cpp. r=jwatt. (ea9b6e5e4e) - Bug 1208300 (part 3) - Convert gfxRGBA uses to gfx::Color in LayerScope.cpp. r=jwatt. (cdee85cd56) - Bg 1155249 - Prescale image with an intermediate surface if repeated often on OS X. r=mstange (de799a164a) - Bug 1181554 - Snap the spread radius for inset box shadows to device pixels. (af015ea088) - Bug 1137148. Fix painting of ridge/groove borders for border-collapsed tables. r=jwatt (702e4fbe9b) - Bug 1185636 - Part 4b - don't use a css border skirt when printing. r=mstange (2e66f01772) - Bug 1178575 - Intersect the clip rect with aDirtyRect. r=roc (88848e836a) - Bug 1193519 pt 1 - Update coordinate conversions in WritingModes.h to account for sideways-lr writing mode. r=dholbert (b89824bcb6) - Bug 1193519 pt 2 - Handle sideways-left orientation in gfx text-drawing code. r=dholbert (4cdc8e0c38) - Bug 1193519 pt 3 - Handle writing-mode:sideways-lr in nsTextFrame selection and rendering. r=dholbert (b774d26992) - Bug 1159729 - Use the adjusted |offset| value in GetTextDecorationRectInternal, instead of ignoring it. r=smontagu (b1c735a0b0) - Bug 1193519 pt 4 - Reverse the direction of text-decoration offsets in sideways-lr mode. r=dholbert (585bcf555a) - Bug 1205787 - Map the writing-mode values from SVG1.1 to their CSS equivalents. r=heycam (dd8e0d9767) - Bug 1193488 - Update values of writing-mode and text-orientation to reflect the CSS WG decision to revise them in the Writing Modes spec. r=dholbert (4399949445) - Bug 1193519 pt 5 - Expose the sideways-lr value for writing-mode to CSS. r=dholbert (ece6e331d1) - Bug 1193519 pt 6 - Adjust the position of the caret bidi indicator appropriately for sideways-lr mode. r=dholbert (b09478c428) - Bug 1205787 - Reftest using legacy SVG1.1 writing-mode values. r=heycam (062df44279) - Bug 1193519 pt 7 - Basic reftests for sideways-lr writing mode. r=dholbert (2c66b9e399) - Bug 1180528 - Reftest for table row progression in vertical-rl writing mode with ltr and rtl directionality. r=dholbert (e2a5c6cadb) - Bug 1193519 pt 8 - Reftests for table row and cell ordering in sideways-* writing modes. r=dholbert (6487fce57d) - Bug 1193519 pt 9 - Reftests with floats in writing-mode: sideways-lr. r=dholbert (9f51c048c6) - Bug 1193519 pt 10 - Clean up remaining mentions of 'sideways-left' in code comments. r=dholbert (8483886936) - Bug 1193519 pt 11 - Reftest for sideways-lr writing mode with text-decoration. r=dholbert (bcfd28b4e8) - Bug 1193519 followup - annotate test for antialiasing fuzz on OS X. (1b8a465d1f) - Bug 1155828 - Draw box-shadows using an approach inspired by border-image. r=mstange (744997a069) - Bug 1162824 - Change box shadow cache to cache the colored blurred box shadow. r=mstange (813107388f) - convert TemporaryRef to already_AddRefed (626bbcb2ec) - Bug 1179049. Properly null check for draw target in box shadow code. r=mstange (8f3c03253c) - Bug 1188075 - Speed up inner box-shadow drawing by using a border-image style approach. r=mstange (61e4564172) - Bug 1208345 - Remove gfxContext::GraphicsOperator. r=jwatt. (884be741db) - Bug 1199534. Only set TabChild canvas background for the background of root PresContexts. r=mats (9a37268f31) - remove special transparent case, not found in FF45/52 nor TFF (a2577d8a0c) - Bug 1202320 - Fall back to platform APZ enabled in PresShell. r=kats (5a62e3e058) - bug 1171131 - Make dom/plugins/ipc build for iOS. r=jimm (cba4193b6e) - Bug 1207741 - Remove gfxIntSize. r=nical. (13b99abb9c) - Bug 591600 - CSS gradients should work on premultiplied colors. r=mstange (b0c6e73961) --- dom/camera/CameraPreviewMediaStream.cpp | 2 +- dom/camera/CameraPreviewMediaStream.h | 2 +- dom/camera/DOMCameraControlListener.cpp | 2 +- dom/canvas/CanvasImageCache.cpp | 4 +- dom/canvas/CanvasImageCache.h | 2 +- dom/canvas/CanvasRenderingContext2D.cpp | 6 +- dom/html/HTMLMediaElement.cpp | 8 +- dom/ipc/ContentChild.cpp | 2 +- dom/ipc/ContentChild.h | 6 +- dom/ipc/ContentParent.cpp | 2 +- dom/ipc/PContent.ipdl | 4 +- dom/ipc/TabParent.cpp | 2 +- dom/media/VideoFrameContainer.cpp | 6 +- dom/media/VideoFrameContainer.h | 10 +- dom/media/VideoSegment.cpp | 6 +- dom/media/VideoSegment.h | 8 +- dom/media/encoder/TrackEncoder.cpp | 2 +- dom/media/encoder/VP8TrackEncoder.cpp | 2 +- dom/media/ogg/OggReader.cpp | 2 +- dom/media/omx/MediaCodecReader.cpp | 2 +- dom/media/omx/MediaOmxReader.cpp | 2 +- dom/plugins/base/nsPluginInstanceOwner.cpp | 4 +- dom/plugins/ipc/PPluginInstance.ipdl | 4 +- dom/plugins/ipc/PluginInstanceChild.cpp | 31 +- dom/plugins/ipc/PluginInstanceChild.h | 4 +- dom/plugins/ipc/PluginInstanceParent.cpp | 12 +- dom/plugins/ipc/PluginInstanceParent.h | 2 +- dom/plugins/ipc/PluginModuleChild.cpp | 4 +- dom/plugins/ipc/PluginSurfaceParent.cpp | 2 +- dom/plugins/ipc/PluginSurfaceParent.h | 2 +- gfx/2d/PathHelpers.h | 7 + gfx/layers/LayerScope.cpp | 15 +- gfx/layers/Layers.cpp | 6 - gfx/layers/Layers.h | 8 +- gfx/layers/basic/BasicImplData.h | 4 - gfx/layers/basic/BasicLayerManager.cpp | 6 +- gfx/layers/basic/BasicLayers.h | 2 +- gfx/layers/basic/BasicLayersImpl.h | 9 +- gfx/layers/basic/BasicPaintedLayer.cpp | 5 +- gfx/layers/ipc/CompositorBench.cpp | 28 +- gfx/layers/ipc/ISurfaceAllocator.cpp | 2 +- gfx/src/nsFontMetrics.cpp | 2 +- gfx/src/nsSize.h | 1 - gfx/thebes/gfx2DGlue.h | 114 +-- gfx/thebes/gfxBlur.cpp | 798 +++++++++++++++--- gfx/thebes/gfxBlur.h | 38 +- gfx/thebes/gfxContext.cpp | 10 +- gfx/thebes/gfxContext.h | 47 +- gfx/thebes/gfxDrawable.cpp | 5 +- gfx/thebes/gfxFont.cpp | 29 +- gfx/thebes/gfxFont.h | 13 +- gfx/thebes/gfxTextRun.cpp | 2 +- gfx/thebes/gfxUtils.cpp | 131 ++- gfx/thebes/gfxUtils.h | 4 +- gfx/thebes/gfxXlibNativeRenderer.cpp | 2 +- image/DynamicImage.cpp | 10 +- image/OrientedImage.cpp | 2 +- image/imgFrame.cpp | 5 +- layout/base/nsCSSRendering.cpp | 379 ++++++--- layout/base/nsCSSRendering.h | 95 ++- layout/base/nsCSSRenderingBorders.cpp | 13 +- layout/base/nsCSSRenderingBorders.h | 7 +- layout/base/nsCaret.cpp | 22 +- layout/base/nsDisplayList.cpp | 15 +- layout/base/nsLayoutUtils.cpp | 41 +- layout/base/nsLayoutUtils.h | 2 +- layout/base/nsPresShell.cpp | 18 +- layout/generic/WritingModes.h | 182 ++-- layout/generic/nsImageFrame.cpp | 2 +- layout/generic/nsTextFrame.cpp | 53 +- layout/generic/nsTextFrame.h | 1 + .../boxshadow-color-rounding-middle-ref.html | 23 + .../boxshadow-color-rounding-middle.html | 11 + layout/reftests/box-shadow/reftest.list | 1 + layout/reftests/bugs/1155828-1-ref.html | 25 + layout/reftests/bugs/1155828-1.html | 26 + layout/reftests/bugs/reftest.list | 1 + .../css-gradients/linear-premul-ref.html | 1 + .../reftests/css-gradients/linear-premul.html | 1 + .../css-gradients/radial-premul-ref.html | 1 + .../reftests/css-gradients/radial-premul.html | 1 + layout/reftests/css-gradients/reftest.list | 2 + .../floats/float-in-rtl-slr-1-ref.html | 21 + .../reftests/floats/float-in-rtl-slr-1a.html | 21 + .../reftests/floats/float-in-rtl-slr-1b.html | 21 + .../reftests/floats/float-in-rtl-slr-1c.html | 21 + .../reftests/floats/float-in-rtl-slr-1d.html | 23 + .../floats/float-in-rtl-slr-2-ref.html | 23 + .../reftests/floats/float-in-rtl-slr-2a.html | 21 + .../reftests/floats/float-in-rtl-slr-2b.html | 21 + .../reftests/floats/float-in-rtl-slr-2c.html | 21 + .../reftests/floats/float-in-rtl-slr-2d.html | 23 + .../floats/float-in-rtl-slr-3-ref.html | 23 + .../reftests/floats/float-in-rtl-slr-3a.html | 23 + .../reftests/floats/float-in-rtl-slr-3b.html | 23 + .../reftests/floats/float-in-rtl-slr-3c.html | 23 + .../reftests/floats/float-in-rtl-slr-3d.html | 25 + .../floats/float-in-rtl-slr-4-ref.html | 24 + .../reftests/floats/float-in-rtl-slr-4a.html | 24 + .../reftests/floats/float-in-rtl-slr-4b.html | 24 + .../reftests/floats/float-in-rtl-slr-4c.html | 24 + .../reftests/floats/float-in-rtl-slr-4d.html | 26 + layout/reftests/floats/reftest.list | 17 + .../border-style-inset-becomes-ridge-ref.html | 10 + .../border-style-inset-becomes-ridge.html | 12 + ...order-style-outset-becomes-groove-ref.html | 10 + .../border-style-outset-becomes-groove.html | 12 + .../table-bordercollapse/reftest.list | 10 +- .../1193519-sideways-lr-1-ref.html | 24 + .../writing-mode/1193519-sideways-lr-1.html | 28 + .../1193519-sideways-lr-2-ref.html | 24 + .../writing-mode/1193519-sideways-lr-2.html | 28 + .../1193519-sideways-lr-3-ref.html | 21 + .../writing-mode/1193519-sideways-lr-3.html | 21 + .../1193519-sideways-lr-4-ref.html | 27 + .../writing-mode/1193519-sideways-lr-4.html | 27 + .../1193519-sideways-lr-decoration-1-ref.html | 10 + .../1193519-sideways-lr-decoration-1.html | 10 + .../1205787-legacy-svg-values-1-ref.html | 25 + .../1205787-legacy-svg-values-1.html | 25 + layout/reftests/writing-mode/reftest.list | 9 + .../reftests/writing-mode/tables/reftest.list | 7 + .../sideways-lr-row-progression-1-ref.html | 51 ++ .../sideways-lr-row-progression-1a.html | 68 ++ .../sideways-lr-row-progression-1b.html | 69 ++ .../sideways-rl-row-progression-1-ref.html | 54 ++ .../sideways-rl-row-progression-1a.html | 68 ++ .../sideways-rl-row-progression-1b.html | 68 ++ .../vertical-rl-row-progression-1-ref.html | 50 ++ .../vertical-rl-row-progression-1a.html | 57 ++ .../vertical-rl-row-progression-1b.html | 57 ++ layout/style/nsCSSKeywordList.h | 13 +- layout/style/nsCSSProps.cpp | 13 +- layout/style/nsRuleNode.cpp | 2 + layout/style/nsStyleConsts.h | 19 +- layout/style/test/property_database.js | 75 +- .../style/test/test_logical_properties.html | 67 +- layout/svg/nsFilterInstance.cpp | 2 +- layout/svg/nsSVGImageFrame.cpp | 2 +- layout/svg/nsSVGIntegrationUtils.cpp | 6 +- layout/svg/nsSVGIntegrationUtils.h | 12 +- layout/svg/nsSVGUtils.cpp | 4 +- layout/svg/nsSVGUtils.h | 4 +- .../signaling/test/FakeMediaStreamsImpl.h | 9 +- widget/cocoa/nsCocoaUtils.mm | 3 +- widget/gtk/nsWindow.cpp | 6 +- widget/nsShmImage.cpp | 4 +- widget/nsShmImage.h | 8 +- widget/qt/nsWindow.cpp | 4 +- widget/uikit/nsWindow.h | 2 +- widget/windows/TaskbarPreview.cpp | 2 +- widget/windows/nsWindow.cpp | 4 +- widget/windows/nsWindowGfx.cpp | 18 +- widget/windows/nsWindowGfx.h | 6 +- 154 files changed, 3116 insertions(+), 898 deletions(-) create mode 100644 layout/reftests/box-shadow/boxshadow-color-rounding-middle-ref.html create mode 100644 layout/reftests/box-shadow/boxshadow-color-rounding-middle.html create mode 100644 layout/reftests/bugs/1155828-1-ref.html create mode 100644 layout/reftests/bugs/1155828-1.html create mode 100644 layout/reftests/css-gradients/linear-premul-ref.html create mode 100644 layout/reftests/css-gradients/linear-premul.html create mode 100644 layout/reftests/css-gradients/radial-premul-ref.html create mode 100644 layout/reftests/css-gradients/radial-premul.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-1-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-1a.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-1b.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-1c.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-1d.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-2-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-2a.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-2b.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-2c.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-2d.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-3-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-3a.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-3b.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-3c.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-3d.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-4-ref.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-4a.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-4b.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-4c.html create mode 100644 layout/reftests/floats/float-in-rtl-slr-4d.html create mode 100644 layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge-ref.html create mode 100644 layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge.html create mode 100644 layout/reftests/table-bordercollapse/border-style-outset-becomes-groove-ref.html create mode 100644 layout/reftests/table-bordercollapse/border-style-outset-becomes-groove.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-1-ref.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-1.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-2-ref.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-2.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-3-ref.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-3.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-4-ref.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-4.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-decoration-1-ref.html create mode 100644 layout/reftests/writing-mode/1193519-sideways-lr-decoration-1.html create mode 100644 layout/reftests/writing-mode/1205787-legacy-svg-values-1-ref.html create mode 100644 layout/reftests/writing-mode/1205787-legacy-svg-values-1.html create mode 100644 layout/reftests/writing-mode/tables/sideways-lr-row-progression-1-ref.html create mode 100644 layout/reftests/writing-mode/tables/sideways-lr-row-progression-1a.html create mode 100644 layout/reftests/writing-mode/tables/sideways-lr-row-progression-1b.html create mode 100644 layout/reftests/writing-mode/tables/sideways-rl-row-progression-1-ref.html create mode 100644 layout/reftests/writing-mode/tables/sideways-rl-row-progression-1a.html create mode 100644 layout/reftests/writing-mode/tables/sideways-rl-row-progression-1b.html create mode 100644 layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html create mode 100644 layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html create mode 100644 layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html diff --git a/dom/camera/CameraPreviewMediaStream.cpp b/dom/camera/CameraPreviewMediaStream.cpp index 0695fd721d..9db1d206e5 100644 --- a/dom/camera/CameraPreviewMediaStream.cpp +++ b/dom/camera/CameraPreviewMediaStream.cpp @@ -161,7 +161,7 @@ CameraPreviewMediaStream::RateLimit(bool aLimit) } void -CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage) +CameraPreviewMediaStream::SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage) { { MutexAutoLock lock(mMutex); diff --git a/dom/camera/CameraPreviewMediaStream.h b/dom/camera/CameraPreviewMediaStream.h index 359f814d78..c7cc6fa127 100644 --- a/dom/camera/CameraPreviewMediaStream.h +++ b/dom/camera/CameraPreviewMediaStream.h @@ -57,7 +57,7 @@ public: void Invalidate(); // Call these on any thread. - void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage); + void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage); void ClearCurrentFrame(); void RateLimit(bool aLimit); diff --git a/dom/camera/DOMCameraControlListener.cpp b/dom/camera/DOMCameraControlListener.cpp index 049e56038e..0818952487 100644 --- a/dom/camera/DOMCameraControlListener.cpp +++ b/dom/camera/DOMCameraControlListener.cpp @@ -311,7 +311,7 @@ DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWid { DOM_CAMERA_LOGI("OnNewPreviewFrame: got %d x %d frame\n", aWidth, aHeight); - mStream->SetCurrentFrame(gfxIntSize(aWidth, aHeight), aImage); + mStream->SetCurrentFrame(gfx::IntSize(aWidth, aHeight), aImage); return true; } diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp index 79a4ee6d90..a4f66bda10 100644 --- a/dom/canvas/CanvasImageCache.cpp +++ b/dom/canvas/CanvasImageCache.cpp @@ -53,7 +53,7 @@ struct ImageCacheEntryData { // Value nsCOMPtr mRequest; RefPtr mSourceSurface; - gfxIntSize mSize; + IntSize mSize; nsExpirationState mState; }; @@ -237,7 +237,7 @@ CanvasImageCache::NotifyDrawImage(Element* aImage, HTMLCanvasElement* aCanvas, imgIRequest* aRequest, SourceSurface* aSource, - const gfxIntSize& aSize) + const IntSize& aSize) { if (!gImageCache) { gImageCache = new ImageCache(); diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h index 6b5fb3cfaa..836368c6c3 100644 --- a/dom/canvas/CanvasImageCache.h +++ b/dom/canvas/CanvasImageCache.h @@ -33,7 +33,7 @@ public: dom::HTMLCanvasElement* aCanvas, imgIRequest* aRequest, SourceSurface* aSource, - const gfxIntSize& aSize); + const gfx::IntSize& aSize); /** * Check whether aImage has recently been drawn into aCanvas. If we return diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 24d5d916df..57ecf006a2 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4807,7 +4807,7 @@ CanvasRenderingContext2D::DrawWindow(nsGlobalWindow& window, double x, { // protect against too-large surfaces that will cause allocation // or overflow issues - if (!gfxASurface::CheckSurfaceSize(gfxIntSize(int32_t(w), int32_t(h)), + if (!gfxASurface::CheckSurfaceSize(gfx::IntSize(int32_t(w), int32_t(h)), 0xffff)) { error.Throw(NS_ERROR_FAILURE); return; @@ -4996,7 +4996,7 @@ CanvasRenderingContext2D::AsyncDrawXULElement(nsXULElement& elem, // protect against too-large surfaces that will cause allocation // or overflow issues - if (!gfxASurface::CheckSurfaceSize(gfxIntSize(w, h), 0xffff)) { + if (!gfxASurface::CheckSurfaceSize(gfx::IntSize(w, h), 0xffff)) { error.Throw(NS_ERROR_FAILURE); return; } @@ -5456,7 +5456,7 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w uint32_t copyWidth = dirtyRect.Width(); uint32_t copyHeight = dirtyRect.Height(); - nsRefPtr imgsurf = new gfxImageSurface(gfxIntSize(copyWidth, copyHeight), + nsRefPtr imgsurf = new gfxImageSurface(gfx::IntSize(copyWidth, copyHeight), gfxImageFormat::ARGB32, false); if (!imgsurf || imgsurf->CairoStatus()) { diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 5e9db41711..50dcf19cc3 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -3020,7 +3020,7 @@ public: if (!mElement) { return; } - gfxIntSize size; + gfx::IntSize size; { MutexAutoLock lock(mMutex); size = mInitialSize; @@ -3034,13 +3034,13 @@ public: const MediaSegment& aQueuedMedia) override { MutexAutoLock lock(mMutex); - if (mInitialSize != gfxIntSize(0,0) || + if (mInitialSize != gfx::IntSize(0,0) || aQueuedMedia.GetType() != MediaSegment::VIDEO) { return; } const VideoSegment& video = static_cast(aQueuedMedia); for (VideoSegment::ConstChunkIterator c(video); !c.IsEnded(); c.Next()) { - if (c->mFrame.GetIntrinsicSize() != gfxIntSize(0,0)) { + if (c->mFrame.GetIntrinsicSize() != gfx::IntSize(0,0)) { mInitialSize = c->mFrame.GetIntrinsicSize(); nsCOMPtr event = NS_NewRunnableMethod(this, &StreamSizeListener::ReceivedSize); @@ -3055,7 +3055,7 @@ private: // mMutex protects the fields below; they can be accessed on any thread Mutex mMutex; - gfxIntSize mInitialSize; + gfx::IntSize mInitialSize; }; class HTMLMediaElement::MediaStreamTracksAvailableCallback: diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 34521a10a7..6286b390c9 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2191,7 +2191,7 @@ ContentChild::RecvAddPermission(const IPC::Permission& permission) } bool -ContentChild::RecvScreenSizeChanged(const gfxIntSize& size) +ContentChild::RecvScreenSizeChanged(const gfx::IntSize& size) { #ifdef ANDROID mScreenSize = size; diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index d069044c53..e5cd3a44bc 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -329,7 +329,7 @@ public: virtual bool RecvAddPermission(const IPC::Permission& permission) override; - virtual bool RecvScreenSizeChanged(const gfxIntSize &size) override; + virtual bool RecvScreenSizeChanged(const gfx::IntSize &size) override; virtual bool RecvFlushMemory(const nsString& reason) override; @@ -404,7 +404,7 @@ public: virtual bool RecvEndDragSession(const bool& aDoneDrag, const bool& aUserCancelled) override; #ifdef ANDROID - gfxIntSize GetScreenSize() { return mScreenSize; } + gfx::IntSize GetScreenSize() { return mScreenSize; } #endif // Get the directory for IndexedDB files. We query the parent for this and @@ -499,7 +499,7 @@ private: AppInfo mAppInfo; #ifdef ANDROID - gfxIntSize mScreenSize; + gfx::IntSize mScreenSize; #endif bool mIsForApp; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 11fc3b2ac5..e1fb5bb3f9 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2696,7 +2696,7 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer, item.flavor().EqualsLiteral(kPNGImageMime) || item.flavor().EqualsLiteral(kGIFImageMime)) { const IPCDataTransferImage& imageDetails = item.imageDetails(); - const gfxIntSize size(imageDetails.width(), imageDetails.height()); + const gfx::IntSize size(imageDetails.width(), imageDetails.height()); if (!size.width || !size.height) { return true; } diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index e13f89a14f..d99a705d30 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -84,7 +84,7 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h"; using mozilla::dom::quota::PersistenceType from "mozilla/dom/quota/PersistenceType.h"; using mozilla::hal::ProcessPriority from "mozilla/HalTypes.h"; -using gfxIntSize from "nsSize.h"; +using mozilla::gfx::IntSize from "mozilla/gfx/2D.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h"; using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h"; @@ -545,7 +545,7 @@ child: // nsIPermissionManager messages AddPermission(Permission permission); - ScreenSizeChanged(gfxIntSize size); + ScreenSizeChanged(IntSize size); Volumes(VolumeInfo[] volumes); diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 63e717cec0..945e1ecb00 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -1950,7 +1950,7 @@ TabParent::RecvSetCustomCursor(const nsCString& aCursorData, } if (mTabSetsCursor) { - const gfxIntSize size(aWidth, aHeight); + const gfx::IntSize size(aWidth, aHeight); mozilla::RefPtr customCursor = new mozilla::gfx::SourceSurfaceRawData(); mozilla::gfx::SourceSurfaceRawData* raw = static_cast(customCursor.get()); diff --git a/dom/media/VideoFrameContainer.cpp b/dom/media/VideoFrameContainer.cpp index 5cf3c868c5..2ece19ad2c 100644 --- a/dom/media/VideoFrameContainer.cpp +++ b/dom/media/VideoFrameContainer.cpp @@ -29,7 +29,7 @@ VideoFrameContainer::VideoFrameContainer(dom::HTMLMediaElement* aElement, VideoFrameContainer::~VideoFrameContainer() {} -void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, +void VideoFrameContainer::SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage, const TimeStamp& aTargetTime) { @@ -44,14 +44,14 @@ void VideoFrameContainer::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, } } -void VideoFrameContainer::SetCurrentFrames(const gfxIntSize& aIntrinsicSize, +void VideoFrameContainer::SetCurrentFrames(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages) { MutexAutoLock lock(mMutex); SetCurrentFramesLocked(aIntrinsicSize, aImages); } -void VideoFrameContainer::SetCurrentFramesLocked(const gfxIntSize& aIntrinsicSize, +void VideoFrameContainer::SetCurrentFramesLocked(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages) { mMutex.AssertCurrentThreadOwns(); diff --git a/dom/media/VideoFrameContainer.h b/dom/media/VideoFrameContainer.h index 795def76c1..8d96a79468 100644 --- a/dom/media/VideoFrameContainer.h +++ b/dom/media/VideoFrameContainer.h @@ -42,11 +42,11 @@ public: already_AddRefed aContainer); // Call on any thread - B2G_ACL_EXPORT void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage, + B2G_ACL_EXPORT void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage, const TimeStamp& aTargetTime); - void SetCurrentFrames(const gfxIntSize& aIntrinsicSize, + void SetCurrentFrames(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages); - void ClearCurrentFrame(const gfxIntSize& aIntrinsicSize) + void ClearCurrentFrame(const gfx::IntSize& aIntrinsicSize) { SetCurrentFrames(aIntrinsicSize, nsTArray()); } @@ -79,7 +79,7 @@ public: void ForgetElement() { mElement = nullptr; } protected: - void SetCurrentFramesLocked(const gfxIntSize& aIntrinsicSize, + void SetCurrentFramesLocked(const gfx::IntSize& aIntrinsicSize, const nsTArray& aImages); // Non-addreffed pointer to the element. The element calls ForgetElement @@ -94,7 +94,7 @@ protected: // This can differ from the Image's actual size when the media resource // specifies that the Image should be stretched to have the correct aspect // ratio. - gfxIntSize mIntrinsicSize; + gfx::IntSize mIntrinsicSize; // We maintain our own mFrameID which is auto-incremented at every // SetCurrentFrame() or NewFrameID() call. ImageContainer::FrameID mFrameID; diff --git a/dom/media/VideoSegment.cpp b/dom/media/VideoSegment.cpp index 41cf8ca9f0..c5420173cc 100644 --- a/dom/media/VideoSegment.cpp +++ b/dom/media/VideoSegment.cpp @@ -14,7 +14,7 @@ namespace mozilla { using namespace layers; VideoFrame::VideoFrame(already_AddRefed& aImage, - const gfxIntSize& aIntrinsicSize) + const gfx::IntSize& aIntrinsicSize) : mImage(aImage), mIntrinsicSize(aIntrinsicSize), mForceBlack(false) {} @@ -28,7 +28,7 @@ VideoFrame::~VideoFrame() void VideoFrame::SetNull() { mImage = nullptr; - mIntrinsicSize = gfxIntSize(0, 0); + mIntrinsicSize = gfx::IntSize(0, 0); } void @@ -41,7 +41,7 @@ VideoFrame::TakeFrom(VideoFrame* aFrame) #if !defined(MOZILLA_XPCOMRT_API) /* static */ already_AddRefed -VideoFrame::CreateBlackImage(const gfxIntSize& aSize) +VideoFrame::CreateBlackImage(const gfx::IntSize& aSize) { nsRefPtr container; nsRefPtr image; diff --git a/dom/media/VideoSegment.h b/dom/media/VideoSegment.h index 36def06d9b..7a761d3828 100644 --- a/dom/media/VideoSegment.h +++ b/dom/media/VideoSegment.h @@ -30,7 +30,7 @@ public: typedef mozilla::layers::Image Image; #endif - VideoFrame(already_AddRefed& aImage, const gfxIntSize& aIntrinsicSize); + VideoFrame(already_AddRefed& aImage, const gfx::IntSize& aIntrinsicSize); VideoFrame(); ~VideoFrame(); @@ -48,13 +48,13 @@ public: Image* GetImage() const { return mImage; } void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; } bool GetForceBlack() const { return mForceBlack; } - const gfxIntSize& GetIntrinsicSize() const { return mIntrinsicSize; } + const gfx::IntSize& GetIntrinsicSize() const { return mIntrinsicSize; } void SetNull(); void TakeFrom(VideoFrame* aFrame); #if !defined(MOZILLA_XPCOMRT_API) // Create a planar YCbCr black image. - static already_AddRefed CreateBlackImage(const gfxIntSize& aSize); + static already_AddRefed CreateBlackImage(const gfx::IntSize& aSize); #endif // !defined(MOZILLA_XPCOMRT_API) protected: @@ -62,7 +62,7 @@ protected: // still have an intrinsic size in this case. nsRefPtr mImage; // The desired size to render the video frame at. - gfxIntSize mIntrinsicSize; + gfx::IntSize mIntrinsicSize; bool mForceBlack; }; diff --git a/dom/media/encoder/TrackEncoder.cpp b/dom/media/encoder/TrackEncoder.cpp index b0cddbfef0..9735325696 100644 --- a/dom/media/encoder/TrackEncoder.cpp +++ b/dom/media/encoder/TrackEncoder.cpp @@ -197,7 +197,7 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, VideoChunk chunk = *iter; if (!chunk.IsNull()) { gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize(); - gfxIntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize(); + gfx::IntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize(); nsresult rv = Init(imgsize.width, imgsize.height, intrinsicSize.width, intrinsicSize.height, aGraph->GraphRate()); diff --git a/dom/media/encoder/VP8TrackEncoder.cpp b/dom/media/encoder/VP8TrackEncoder.cpp index 75120524c5..b52870fdcf 100644 --- a/dom/media/encoder/VP8TrackEncoder.cpp +++ b/dom/media/encoder/VP8TrackEncoder.cpp @@ -251,7 +251,7 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk) nsRefPtr img; if (aChunk.mFrame.GetForceBlack() || aChunk.IsNull()) { if (!mMuteFrame) { - mMuteFrame = VideoFrame::CreateBlackImage(gfxIntSize(mFrameWidth, mFrameHeight)); + mMuteFrame = VideoFrame::CreateBlackImage(gfx::IntSize(mFrameWidth, mFrameHeight)); MOZ_ASSERT(mMuteFrame); } img = mMuteFrame; diff --git a/dom/media/ogg/OggReader.cpp b/dom/media/ogg/OggReader.cpp index 5dffe19638..8f74dbd4bb 100644 --- a/dom/media/ogg/OggReader.cpp +++ b/dom/media/ogg/OggReader.cpp @@ -240,7 +240,7 @@ void OggReader::SetupTargetTheora(TheoraState* aTheoraState) VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { - container->ClearCurrentFrame(gfxIntSize(displaySize.width, displaySize.height)); + container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height)); } // Copy Theora info data for time computations on other threads. diff --git a/dom/media/omx/MediaCodecReader.cpp b/dom/media/omx/MediaCodecReader.cpp index aee16b3eb6..60790d83a5 100644 --- a/dom/media/omx/MediaCodecReader.cpp +++ b/dom/media/omx/MediaCodecReader.cpp @@ -744,7 +744,7 @@ MediaCodecReader::HandleResourceAllocated() VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { container->ClearCurrentFrame( - gfxIntSize(mInfo.mVideo.mDisplay.width, mInfo.mVideo.mDisplay.height)); + gfx::IntSize(mInfo.mVideo.mDisplay.width, mInfo.mVideo.mDisplay.height)); } nsRefPtr metadata = new MetadataHolder(); diff --git a/dom/media/omx/MediaOmxReader.cpp b/dom/media/omx/MediaOmxReader.cpp index 40422834c6..5fb0c261f7 100644 --- a/dom/media/omx/MediaOmxReader.cpp +++ b/dom/media/omx/MediaOmxReader.cpp @@ -308,7 +308,7 @@ void MediaOmxReader::HandleResourceAllocated() mInitialFrame = frameSize; VideoFrameContainer* container = mDecoder->GetVideoFrameContainer(); if (container) { - container->ClearCurrentFrame(gfxIntSize(displaySize.width, displaySize.height)); + container->ClearCurrentFrame(IntSize(displaySize.width, displaySize.height)); } } diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index c5c0540f0b..25ad6261d9 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -2567,7 +2567,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, aFrameRect.width != pluginSurface->Width() || aFrameRect.height != pluginSurface->Height()) { - pluginSurface = new gfxImageSurface(gfxIntSize(aFrameRect.width, aFrameRect.height), + pluginSurface = new gfxImageSurface(gfx::IntSize(aFrameRect.width, aFrameRect.height), gfxImageFormat::ARGB32); if (!pluginSurface) return; @@ -2597,7 +2597,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, mInstance->HandleEvent(&event, nullptr); - aContext->SetOperator(gfxContext::OPERATOR_SOURCE); + aContext->SetOp(gfx::CompositionOp::OP_SOURCE); aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y)); aContext->Clip(aFrameRect); aContext->Paint(); diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index a162d3639e..3187ca5371 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -22,7 +22,7 @@ using NPCoordinateSpace from "npapi.h"; using NPNVariable from "npapi.h"; using mozilla::plugins::NativeWindowHandle from "mozilla/plugins/PluginMessageUtils.h"; using gfxSurfaceType from "gfxTypes.h"; -using gfxIntSize from "nsSize.h"; +using mozilla::gfx::IntSize from "mozilla/gfx/2D.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using mozilla::plugins::WindowsSharedMemoryHandle from "mozilla/plugins/PluginMessageUtils.h"; using mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h"; @@ -189,7 +189,7 @@ parent: returns (SurfaceDescriptor prevSurface); async PPluginSurface(WindowsSharedMemoryHandle handle, - gfxIntSize size, + IntSize size, bool transparent); intr NPN_PushPopupsEnabledState(bool aState); diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index e2fbe42dc2..92df0d5f9c 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -130,7 +130,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface, , mMode(aMode) , mNames(aNames) , mValues(aValues) -#if defined(XP_MACOSX) +#if defined(XP_DARWIN) , mContentsScaleFactor(1.0) #endif , mDrawingModel(kDefaultDrawingModel) @@ -1337,6 +1337,8 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow) // TODO: Need Android impl #elif defined(MOZ_WIDGET_QT) // TODO: Need QT-nonX impl +#elif defined(MOZ_WIDGET_UIKIT) + // Don't care #else # error Implement me for your OS #endif @@ -2867,8 +2869,7 @@ PluginInstanceChild::CreateOptSurface(void) Visual* defaultVisual = DefaultVisualOfScreen(screen); mCurrentSurface = gfxXlibSurface::Create(screen, defaultVisual, - gfxIntSize(mWindow.width, - mWindow.height)); + IntSize(mWindow.width, mWindow.height)); return mCurrentSurface != nullptr; } @@ -2879,8 +2880,7 @@ PluginInstanceChild::CreateOptSurface(void) } mCurrentSurface = gfxXlibSurface::Create(screen, xfmt, - gfxIntSize(mWindow.width, - mWindow.height)); + IntSize(mWindow.width, mWindow.height)); return mCurrentSurface != nullptr; } #endif @@ -2904,7 +2904,7 @@ PluginInstanceChild::CreateOptSurface(void) // Make common shmem implementation working for any platform mCurrentSurface = - gfxSharedImageSurface::CreateUnsafe(this, gfxIntSize(mWindow.width, mWindow.height), format); + gfxSharedImageSurface::CreateUnsafe(this, IntSize(mWindow.width, mWindow.height), format); return !!mCurrentSurface; } @@ -2970,9 +2970,9 @@ PluginInstanceChild::MaybeCreatePlatformHelperSurface(void) bool PluginInstanceChild::EnsureCurrentBuffer(void) { -#ifndef XP_MACOSX +#ifndef XP_DARWIN nsIntRect toInvalidate(0, 0, 0, 0); - gfxIntSize winSize = gfxIntSize(mWindow.width, mWindow.height); + IntSize winSize = IntSize(mWindow.width, mWindow.height); if (mBackground && mBackground->GetSize() != winSize) { // It would be nice to keep the old background here, but doing @@ -2984,7 +2984,7 @@ PluginInstanceChild::EnsureCurrentBuffer(void) } if (mCurrentSurface) { - gfxIntSize surfSize = mCurrentSurface->GetSize(); + IntSize surfSize = mCurrentSurface->GetSize(); if (winSize != surfSize || (mBackground && !CanPaintOnBackground()) || (mBackground && @@ -3016,7 +3016,7 @@ PluginInstanceChild::EnsureCurrentBuffer(void) } return true; -#else // XP_MACOSX +#elif defined(XP_MACOSX) if (!mDoubleBufferCARenderer.HasCALayer()) { void *caLayer = nullptr; @@ -3070,9 +3070,8 @@ PluginInstanceChild::EnsureCurrentBuffer(void) nsIntRect toInvalidate(0, 0, mWindow.width, mWindow.height); mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate); } - - return true; #endif + return true; } void @@ -3299,7 +3298,7 @@ PluginInstanceChild::PaintRectWithAlphaExtraction(const nsIntRect& aRect, nsRefPtr whiteImage; nsRefPtr blackImage; gfxRect targetRect(rect.x, rect.y, rect.width, rect.height); - gfxIntSize targetSize(rect.width, rect.height); + IntSize targetSize(rect.width, rect.height); gfxPoint deviceOffset = -targetRect.TopLeft(); // We always use a temporary "white image" @@ -3477,7 +3476,7 @@ PluginInstanceChild::ShowPluginFrame() // Fix up old invalidations that might have been made when our // surface was a different size - gfxIntSize surfaceSize = mCurrentSurface->GetSize(); + IntSize surfaceSize = mCurrentSurface->GetSize(); rect.IntersectRect(rect, nsIntRect(0, 0, surfaceSize.width, surfaceSize.height)); @@ -3737,7 +3736,7 @@ PluginInstanceChild::RecvUpdateBackground(const SurfaceDescriptor& aBackground, return false; } - gfxIntSize bgSize = mBackground->GetSize(); + IntSize bgSize = mBackground->GetSize(); mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, nsIntRect(0, 0, bgSize.width, bgSize.height)); AsyncShowPluginFrame(); @@ -3774,7 +3773,7 @@ PluginInstanceChild::RecvPPluginBackgroundDestroyerConstructor( // alpha values. (We should be notified of that invalidation soon // too, but we don't assume that here.) if (mBackground) { - gfxIntSize bgsize = mBackground->GetSize(); + IntSize bgsize = mBackground->GetSize(); mAccumulatedInvalidRect.UnionRect( nsIntRect(0, 0, bgsize.width, bgsize.height), mAccumulatedInvalidRect); diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index 39c7ff3c86..54657f87e5 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -113,7 +113,7 @@ protected: virtual PPluginSurfaceChild* AllocPPluginSurfaceChild(const WindowsSharedMemoryHandle&, - const gfxIntSize&, const bool&) override { + const gfx::IntSize&, const bool&) override { return new PPluginSurfaceChild(); } @@ -380,7 +380,7 @@ private: InfallibleTArray mValues; NPP_t mData; NPWindow mWindow; -#if defined(XP_MACOSX) +#if defined(XP_DARWIN) double mContentsScaleFactor; #endif int16_t mDrawingModel; diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index eb0287f8c3..63b9f02fe4 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -272,7 +272,7 @@ PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* HWND id; #elif defined(MOZ_X11) XID id; -#elif defined(XP_MACOSX) +#elif defined(XP_DARWIN) intptr_t id; #elif defined(ANDROID) // TODO: Need Android impl @@ -745,7 +745,7 @@ nsresult PluginInstanceParent::GetImageSize(nsIntSize* aSize) { if (mFrontSurface) { - gfxIntSize size = mFrontSurface->GetSize(); + mozilla::gfx::IntSize size = mFrontSurface->GetSize(); *aSize = nsIntSize(size.width, size.height); return NS_OK; } @@ -814,7 +814,7 @@ PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect, } } - gfxIntSize sz = mBackground->GetSize(); + mozilla::gfx::IntSize sz = mBackground->GetSize(); #ifdef DEBUG MOZ_ASSERT(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect), "Update outside of background area"); @@ -871,7 +871,7 @@ PluginInstanceParent::CreateBackground(const nsIntSize& aSize) Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay()); Visual* visual = DefaultVisualOfScreen(screen); mBackground = gfxXlibSurface::Create(screen, visual, - gfxIntSize(aSize.width, aSize.height)); + mozilla::gfx::IntSize(aSize.width, aSize.height)); return !!mBackground; #elif defined(XP_WIN) @@ -880,7 +880,7 @@ PluginInstanceParent::CreateBackground(const nsIntSize& aSize) mBackground = gfxSharedImageSurface::CreateUnsafe( this, - gfxIntSize(aSize.width, aSize.height), + mozilla::gfx::IntSize(aSize.width, aSize.height), gfxImageFormat::RGB24); return !!mBackground; #else @@ -1613,7 +1613,7 @@ PluginInstanceParent::GetActorForNPObject(NPObject* aObject) PPluginSurfaceParent* PluginInstanceParent::AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const mozilla::gfx::IntSize& size, const bool& transparent) { #ifdef XP_WIN diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index 84c467da21..01b9c8c2f2 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -169,7 +169,7 @@ public: virtual PPluginSurfaceParent* AllocPPluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const mozilla::gfx::IntSize& size, const bool& transparent) override; virtual bool diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index fcc2ee1499..59e3a5d864 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -269,7 +269,7 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename, nsPluginFile pluginFile(localFile); -#if defined(MOZ_X11) || defined(OS_MACOSX) +#if defined(MOZ_X11) || defined(XP_MACOSX) nsPluginInfo info = nsPluginInfo(); if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary))) { return false; @@ -280,7 +280,7 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename, if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) { AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION); } -#else // defined(OS_MACOSX) +#else // defined(XP_MACOSX) const char* namePrefix = "Plugin Content"; char nameBuffer[80]; snprintf(nameBuffer, sizeof(nameBuffer), "%s (%s)", namePrefix, info.fName); diff --git a/dom/plugins/ipc/PluginSurfaceParent.cpp b/dom/plugins/ipc/PluginSurfaceParent.cpp index a9087cb1f4..1d5e19ad64 100644 --- a/dom/plugins/ipc/PluginSurfaceParent.cpp +++ b/dom/plugins/ipc/PluginSurfaceParent.cpp @@ -12,7 +12,7 @@ namespace mozilla { namespace plugins { PluginSurfaceParent::PluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const gfx::IntSize& size, bool transparent) { SharedDIBSurface* dibsurf = new SharedDIBSurface(); diff --git a/dom/plugins/ipc/PluginSurfaceParent.h b/dom/plugins/ipc/PluginSurfaceParent.h index 07f1423cbb..12dab7e728 100644 --- a/dom/plugins/ipc/PluginSurfaceParent.h +++ b/dom/plugins/ipc/PluginSurfaceParent.h @@ -23,7 +23,7 @@ class PluginSurfaceParent : public PPluginSurfaceParent { public: PluginSurfaceParent(const WindowsSharedMemoryHandle& handle, - const gfxIntSize& size, + const gfx::IntSize& size, const bool transparent); ~PluginSurfaceParent(); diff --git a/gfx/2d/PathHelpers.h b/gfx/2d/PathHelpers.h index c1a8ffc36f..6127f2c3d0 100644 --- a/gfx/2d/PathHelpers.h +++ b/gfx/2d/PathHelpers.h @@ -216,6 +216,13 @@ struct RectCornerRadii { return radii[aCorner]; } + bool operator==(const RectCornerRadii& aOther) const { + for (size_t i = 0; i < RectCorner::Count; i++) { + if (radii[i] != aOther.radii[i]) return false; + } + return true; + } + void Scale(Float aXScale, Float aYScale) { for (int i = 0; i < RectCorner::Count; i++) { radii[i].Scale(aXScale, aYScale); diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index 35dc5ec5e3..b78b445b24 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -599,12 +599,12 @@ protected: class DebugGLColorData final: public DebugGLData { public: DebugGLColorData(void* layerRef, - const gfxRGBA& color, + const Color& color, int width, int height) : DebugGLData(Packet::COLOR), mLayerRef(reinterpret_cast(layerRef)), - mColor(color.Packed()), + mColor(color.ToABGR()), mSize(width, height) { } @@ -902,7 +902,7 @@ public: // Sender private functions private: static void SendColor(void* aLayerRef, - const gfxRGBA& aColor, + const Color& aColor, int aWidth, int aHeight); static void SendTextureSource(GLContext* aGLContext, @@ -1004,7 +1004,7 @@ SenderHelper::SendLayer(LayerComposite* aLayer, void SenderHelper::SendColor(void* aLayerRef, - const gfxRGBA& aColor, + const Color& aColor, int aWidth, int aHeight) { @@ -1179,11 +1179,8 @@ SenderHelper::SendEffectChain(GLContext* aGLContext, case EffectTypes::SOLID_COLOR: { const EffectSolidColor* solidColorEffect = static_cast(primaryEffect); - gfxRGBA color(solidColorEffect->mColor.r, - solidColorEffect->mColor.g, - solidColorEffect->mColor.b, - solidColorEffect->mColor.a); - SendColor(aEffectChain.mLayerRef, color, aWidth, aHeight); + SendColor(aEffectChain.mLayerRef, solidColorEffect->mColor, + aWidth, aHeight); break; } case EffectTypes::COMPONENT_ALPHA: diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 2c5f590787..32e3d982f8 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -935,12 +935,6 @@ Layer::GetEffectiveMixBlendMode() return mMixBlendMode; } -gfxContext::GraphicsOperator -Layer::DeprecatedGetEffectiveMixBlendMode() -{ - return ThebesOp(GetEffectiveMixBlendMode()); -} - void Layer::ComputeEffectiveTransformForMaskLayers(const gfx::Matrix4x4& aTransformToSurface) { diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 533c22615e..2b177249e7 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -11,7 +11,7 @@ #include // for int32_t, int64_t #include "FrameMetrics.h" // for FrameMetrics #include "Units.h" // for LayerMargin, LayerPoint, ParentLayerIntRect -#include "gfxContext.h" // for GraphicsOperator +#include "gfxContext.h" #include "gfxTypes.h" #include "gfxColor.h" // for gfxRGBA #include "GraphicsFilter.h" // for GraphicsFilter @@ -978,11 +978,6 @@ public: } } - void DeprecatedSetMixBlendMode(gfxContext::GraphicsOperator aMixBlendMode) - { - SetMixBlendMode(gfx::CompositionOpForOp(aMixBlendMode)); - } - void SetForceIsolatedGroup(bool aForceIsolatedGroup) { if(mForceIsolatedGroup != aForceIsolatedGroup) { @@ -1500,7 +1495,6 @@ public: * Returns the blendmode of this layer. */ gfx::CompositionOp GetEffectiveMixBlendMode(); - gfxContext::GraphicsOperator DeprecatedGetEffectiveMixBlendMode(); /** * This returns the effective transform computed by diff --git a/gfx/layers/basic/BasicImplData.h b/gfx/layers/basic/BasicImplData.h index f127121de1..2ffa310a91 100644 --- a/gfx/layers/basic/BasicImplData.h +++ b/gfx/layers/basic/BasicImplData.h @@ -104,10 +104,6 @@ public: } gfx::CompositionOp GetOperator() const { return mOperator; } - gfxContext::GraphicsOperator DeprecatedGetOperator() const - { - return gfx::ThebesOp(mOperator); - } /** * Return a surface for this layer. Will use an existing surface, if diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp index 1177850d88..1bca29b3f2 100644 --- a/gfx/layers/basic/BasicLayerManager.cpp +++ b/gfx/layers/basic/BasicLayerManager.cpp @@ -425,8 +425,8 @@ ApplyDoubleBuffering(Layer* aLayer, const IntRect& aVisibleRect) BasicContainerLayer* container = static_cast(aLayer->AsContainerLayer()); // Layers that act as their own backbuffers should be drawn to the destination - // using OPERATOR_SOURCE to ensure that alpha values in a transparent window - // are cleared. This can also be faster than OPERATOR_OVER. + // using OP_SOURCE to ensure that alpha values in a transparent window are + // cleared. This can also be faster than OP_OVER. if (!container) { data->SetOperator(CompositionOp::OP_SOURCE); data->SetDrawAtomically(true); @@ -845,7 +845,7 @@ BasicLayerManager::FlushGroup(PaintLayerContext& aPaintContext, bool aNeedsClipT } CompositionOp op = GetEffectiveOperator(aPaintContext.mLayer); - AutoSetOperator setOperator(aPaintContext.mTarget, ThebesOp(op)); + AutoSetOperator setOperator(aPaintContext.mTarget, op); PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(), aPaintContext.mLayer->GetMaskLayer()); diff --git a/gfx/layers/basic/BasicLayers.h b/gfx/layers/basic/BasicLayers.h index 6450e6a1d0..4b3f378ea4 100644 --- a/gfx/layers/basic/BasicLayers.h +++ b/gfx/layers/basic/BasicLayers.h @@ -84,7 +84,7 @@ public: * temporary results to aContext and then overpainting them with final * results, by using a temporary buffer when necessary. In BUFFERED * mode we always completely overwrite the contents of aContext's - * destination surface (within the clip region) using OPERATOR_SOURCE. + * destination surface (within the clip region) using OP_SOURCE. */ void SetDefaultTarget(gfxContext* aContext); virtual void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering, ScreenRotation aRotation); diff --git a/gfx/layers/basic/BasicLayersImpl.h b/gfx/layers/basic/BasicLayersImpl.h index 2bafd068b4..b1381e6598 100644 --- a/gfx/layers/basic/BasicLayersImpl.h +++ b/gfx/layers/basic/BasicLayersImpl.h @@ -28,16 +28,17 @@ class AutoMoz2DMaskData; class Layer; class AutoSetOperator { + typedef mozilla::gfx::CompositionOp CompositionOp; public: - AutoSetOperator(gfxContext* aContext, gfxContext::GraphicsOperator aOperator) { - if (aOperator != gfxContext::OPERATOR_OVER) { - aContext->SetOperator(aOperator); + AutoSetOperator(gfxContext* aContext, CompositionOp aOperator) { + if (aOperator != CompositionOp::OP_OVER) { + aContext->SetOp(aOperator); mContext = aContext; } } ~AutoSetOperator() { if (mContext) { - mContext->SetOperator(gfxContext::OPERATOR_OVER); + mContext->SetOp(CompositionOp::OP_OVER); } } private: diff --git a/gfx/layers/basic/BasicPaintedLayer.cpp b/gfx/layers/basic/BasicPaintedLayer.cpp index 74b5bc48ef..8ce4d57ec5 100644 --- a/gfx/layers/basic/BasicPaintedLayer.cpp +++ b/gfx/layers/basic/BasicPaintedLayer.cpp @@ -98,7 +98,7 @@ BasicPaintedLayer::PaintThebes(gfxContext* aContext, if (needsClipToVisibleRegion) { gfxUtils::ClipToRegion(aContext, toDraw); } - AutoSetOperator setOptimizedOperator(aContext, ThebesOp(effectiveOperator)); + AutoSetOperator setOptimizedOperator(aContext, effectiveOperator); PaintWithMask(aContext, opacity, aMaskLayer); } @@ -212,8 +212,7 @@ BasicPaintedLayer::Validate(LayerManager::DrawPaintedLayerCallback aCallback, NS_ASSERTION(!GetMaskLayer(), "Should only read back layers without masks"); ctx->SetMatrix(ctx->CurrentMatrix().Translate(offset.x, offset.y)); mContentClient->DrawTo(this, ctx->GetDrawTarget(), 1.0, - CompositionOpForOp(ctx->CurrentOperator()), - nullptr, nullptr); + ctx->CurrentOp(), nullptr, nullptr); update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset); } } diff --git a/gfx/layers/ipc/CompositorBench.cpp b/gfx/layers/ipc/CompositorBench.cpp index 47f591ebf4..c568ea6611 100644 --- a/gfx/layers/ipc/CompositorBench.cpp +++ b/gfx/layers/ipc/CompositorBench.cpp @@ -96,15 +96,11 @@ public: {} void DrawFrame(Compositor* aCompositor, const gfx::Rect& aScreenRect, size_t aStep) { - float red; float tmp; - red = modf(aStep * 0.03f, &tmp); + float red = modff(aStep * 0.03f, &tmp); EffectChain effects; - gfxRGBA color(red, 0.4f, 0.4f, 1.0f); - effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(color.r, - color.g, - color.b, - color.a)); + effects.mPrimaryEffect = + new EffectSolidColor(gfx::Color(red, 0.4f, 0.4f, 1.0f)); const gfx::Rect& rect = aScreenRect; const gfx::Rect& clipRect = aScreenRect; @@ -130,15 +126,10 @@ public: } already_AddRefed CreateEffect(size_t i) { - float red; float tmp; - red = modf(i * 0.03f, &tmp); + float red = modff(i * 0.03f, &tmp); EffectChain effects; - gfxRGBA color(red, 0.4f, 0.4f, 1.0f); - return MakeAndAddRef(gfx::Color(color.r, - color.g, - color.b, - color.a)); + return MakeAndAddRef(gfx::Color(red, 0.4f, 0.4f, 1.0f)); } }; @@ -156,15 +147,10 @@ public: } already_AddRefed CreateEffect(size_t i) { - float red; float tmp; - red = modf(i * 0.03f, &tmp); + float red = modff(i * 0.03f, &tmp); EffectChain effects; - gfxRGBA color(red, 0.4f, 0.4f, 1.0f); - return MakeAndAddRef(gfx::Color(color.r, - color.g, - color.b, - color.a)); + return MakeAndAddRef(gfx::Color(red, 0.4f, 0.4f, 1.0f)); } }; diff --git a/gfx/layers/ipc/ISurfaceAllocator.cpp b/gfx/layers/ipc/ISurfaceAllocator.cpp index dbc07fbd8a..d724750fda 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.cpp +++ b/gfx/layers/ipc/ISurfaceAllocator.cpp @@ -122,7 +122,7 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfx::IntSize& aSize, GfxMemoryImageReporter::DidAlloc(data); #ifdef XP_MACOSX // Workaround a bug in Quartz where drawing an a8 surface to another a8 - // surface with OPERATOR_SOURCE still requires the destination to be clear. + // surface with OP_SOURCE still requires the destination to be clear. if (format == gfx::SurfaceFormat::A8) { memset(data, 0, size); } diff --git a/gfx/src/nsFontMetrics.cpp b/gfx/src/nsFontMetrics.cpp index 035f8eb01c..fe9d49f00e 100644 --- a/gfx/src/nsFontMetrics.cpp +++ b/gfx/src/nsFontMetrics.cpp @@ -66,7 +66,7 @@ private: case NS_STYLE_TEXT_ORIENTATION_UPRIGHT: flags |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT; break; - case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT: + case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS: flags |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT; break; } diff --git a/gfx/src/nsSize.h b/gfx/src/nsSize.h index 5535268c12..578cbaa195 100644 --- a/gfx/src/nsSize.h +++ b/gfx/src/nsSize.h @@ -14,7 +14,6 @@ #define NS_MAXSIZE nscoord_MAX typedef mozilla::gfx::IntSize nsIntSize; -typedef nsIntSize gfxIntSize; struct nsSize : public mozilla::gfx::BaseSize { typedef mozilla::gfx::BaseSize Super; diff --git a/gfx/thebes/gfx2DGlue.h b/gfx/thebes/gfx2DGlue.h index 0654aa2cb6..2a077635f6 100644 --- a/gfx/thebes/gfx2DGlue.h +++ b/gfx/thebes/gfx2DGlue.h @@ -40,7 +40,7 @@ inline Color ToColor(const gfxRGBA &aRGBA) Float(aRGBA.b), Float(aRGBA.a)); } -inline gfxRGBA ThebesColor(Color &aColor) +inline gfxRGBA ThebesColor(const Color &aColor) { return gfxRGBA(aColor.r, aColor.g, aColor.b, aColor.a); } @@ -207,118 +207,6 @@ inline gfxContentType ContentForFormat(const SurfaceFormat &aFormat) } } -inline CompositionOp CompositionOpForOp(gfxContext::GraphicsOperator aOp) -{ - switch (aOp) { - case gfxContext::OPERATOR_ADD: - return CompositionOp::OP_ADD; - case gfxContext::OPERATOR_ATOP: - return CompositionOp::OP_ATOP; - case gfxContext::OPERATOR_IN: - return CompositionOp::OP_IN; - case gfxContext::OPERATOR_OUT: - return CompositionOp::OP_OUT; - case gfxContext::OPERATOR_SOURCE: - return CompositionOp::OP_SOURCE; - case gfxContext::OPERATOR_DEST_IN: - return CompositionOp::OP_DEST_IN; - case gfxContext::OPERATOR_DEST_OUT: - return CompositionOp::OP_DEST_OUT; - case gfxContext::OPERATOR_DEST_ATOP: - return CompositionOp::OP_DEST_ATOP; - case gfxContext::OPERATOR_XOR: - return CompositionOp::OP_XOR; - case gfxContext::OPERATOR_MULTIPLY: - return CompositionOp::OP_MULTIPLY; - case gfxContext::OPERATOR_SCREEN: - return CompositionOp::OP_SCREEN; - case gfxContext::OPERATOR_OVERLAY: - return CompositionOp::OP_OVERLAY; - case gfxContext::OPERATOR_DARKEN: - return CompositionOp::OP_DARKEN; - case gfxContext::OPERATOR_LIGHTEN: - return CompositionOp::OP_LIGHTEN; - case gfxContext::OPERATOR_COLOR_DODGE: - return CompositionOp::OP_COLOR_DODGE; - case gfxContext::OPERATOR_COLOR_BURN: - return CompositionOp::OP_COLOR_BURN; - case gfxContext::OPERATOR_HARD_LIGHT: - return CompositionOp::OP_HARD_LIGHT; - case gfxContext::OPERATOR_SOFT_LIGHT: - return CompositionOp::OP_SOFT_LIGHT; - case gfxContext::OPERATOR_DIFFERENCE: - return CompositionOp::OP_DIFFERENCE; - case gfxContext::OPERATOR_EXCLUSION: - return CompositionOp::OP_EXCLUSION; - case gfxContext::OPERATOR_HUE: - return CompositionOp::OP_HUE; - case gfxContext::OPERATOR_SATURATION: - return CompositionOp::OP_SATURATION; - case gfxContext::OPERATOR_COLOR: - return CompositionOp::OP_COLOR; - case gfxContext::OPERATOR_LUMINOSITY: - return CompositionOp::OP_LUMINOSITY; - default: - return CompositionOp::OP_OVER; - } -} - -inline gfxContext::GraphicsOperator ThebesOp(CompositionOp aOp) -{ - switch (aOp) { - case CompositionOp::OP_ADD: - return gfxContext::OPERATOR_ADD; - case CompositionOp::OP_ATOP: - return gfxContext::OPERATOR_ATOP; - case CompositionOp::OP_IN: - return gfxContext::OPERATOR_IN; - case CompositionOp::OP_OUT: - return gfxContext::OPERATOR_OUT; - case CompositionOp::OP_SOURCE: - return gfxContext::OPERATOR_SOURCE; - case CompositionOp::OP_DEST_IN: - return gfxContext::OPERATOR_DEST_IN; - case CompositionOp::OP_DEST_OUT: - return gfxContext::OPERATOR_DEST_OUT; - case CompositionOp::OP_DEST_ATOP: - return gfxContext::OPERATOR_DEST_ATOP; - case CompositionOp::OP_XOR: - return gfxContext::OPERATOR_XOR; - case CompositionOp::OP_MULTIPLY: - return gfxContext::OPERATOR_MULTIPLY; - case CompositionOp::OP_SCREEN: - return gfxContext::OPERATOR_SCREEN; - case CompositionOp::OP_OVERLAY: - return gfxContext::OPERATOR_OVERLAY; - case CompositionOp::OP_DARKEN: - return gfxContext::OPERATOR_DARKEN; - case CompositionOp::OP_LIGHTEN: - return gfxContext::OPERATOR_LIGHTEN; - case CompositionOp::OP_COLOR_DODGE: - return gfxContext::OPERATOR_COLOR_DODGE; - case CompositionOp::OP_COLOR_BURN: - return gfxContext::OPERATOR_COLOR_BURN; - case CompositionOp::OP_HARD_LIGHT: - return gfxContext::OPERATOR_HARD_LIGHT; - case CompositionOp::OP_SOFT_LIGHT: - return gfxContext::OPERATOR_SOFT_LIGHT; - case CompositionOp::OP_DIFFERENCE: - return gfxContext::OPERATOR_DIFFERENCE; - case CompositionOp::OP_EXCLUSION: - return gfxContext::OPERATOR_EXCLUSION; - case CompositionOp::OP_HUE: - return gfxContext::OPERATOR_HUE; - case CompositionOp::OP_SATURATION: - return gfxContext::OPERATOR_SATURATION; - case CompositionOp::OP_COLOR: - return gfxContext::OPERATOR_COLOR; - case CompositionOp::OP_LUMINOSITY: - return gfxContext::OPERATOR_LUMINOSITY; - default: - return gfxContext::OPERATOR_OVER; - } -} - } // namespace gfx } // namespace mozilla diff --git a/gfx/thebes/gfxBlur.cpp b/gfx/thebes/gfxBlur.cpp index 81746ebf78..0e9ec3dc86 100644 --- a/gfx/thebes/gfxBlur.cpp +++ b/gfx/thebes/gfxBlur.cpp @@ -14,6 +14,7 @@ #include "mozilla/UniquePtr.h" #include "nsExpirationTracker.h" #include "nsClassHashtable.h" +#include "gfxUtils.h" using namespace mozilla; using namespace mozilla::gfx; @@ -164,46 +165,104 @@ struct BlurCacheKey : public PLDHashEntryHdr { typedef const BlurCacheKey* KeyTypePointer; enum { ALLOW_MEMMOVE = true }; - gfxRect mRect; + IntSize mMinSize; IntSize mBlurRadius; - gfxRect mSkipRect; + gfxRGBA mShadowColor; BackendType mBackend; + RectCornerRadii mCornerRadii; + bool mIsInset; - BlurCacheKey(const gfxRect& aRect, const IntSize &aBlurRadius, const gfxRect& aSkipRect, BackendType aBackend) - : mRect(aRect) - , mBlurRadius(aBlurRadius) - , mSkipRect(aSkipRect) - , mBackend(aBackend) - { } + // Only used for inset blurs + bool mHasBorderRadius; + IntSize mSpreadRadius; + IntSize mInnerMinSize; + + BlurCacheKey(IntSize aMinSize, IntSize aBlurRadius, + RectCornerRadii* aCornerRadii, gfxRGBA aShadowColor, + BackendType aBackendType) + : BlurCacheKey(aMinSize, IntSize(0, 0), + aBlurRadius, IntSize(0, 0), + aCornerRadii, aShadowColor, + false, false, aBackendType) + {} explicit BlurCacheKey(const BlurCacheKey* aOther) - : mRect(aOther->mRect) + : mMinSize(aOther->mMinSize) , mBlurRadius(aOther->mBlurRadius) - , mSkipRect(aOther->mSkipRect) + , mShadowColor(aOther->mShadowColor) , mBackend(aOther->mBackend) + , mCornerRadii(aOther->mCornerRadii) + , mIsInset(aOther->mIsInset) + , mHasBorderRadius(aOther->mHasBorderRadius) + , mSpreadRadius(aOther->mSpreadRadius) + , mInnerMinSize(aOther->mInnerMinSize) + { } + + explicit BlurCacheKey(IntSize aOuterMinSize, IntSize aInnerMinSize, + IntSize aBlurRadius, IntSize aSpreadRadius, + const RectCornerRadii* aCornerRadii, gfxRGBA aShadowColor, + bool aIsInset, + bool aHasBorderRadius, BackendType aBackendType) + : mMinSize(aOuterMinSize) + , mBlurRadius(aBlurRadius) + , mShadowColor(aShadowColor) + , mBackend(aBackendType) + , mCornerRadii(aCornerRadii ? *aCornerRadii : RectCornerRadii()) + , mIsInset(aIsInset) + , mHasBorderRadius(aHasBorderRadius) + , mSpreadRadius(aSpreadRadius) + , mInnerMinSize(aInnerMinSize) { } static PLDHashNumber HashKey(const KeyTypePointer aKey) { - PLDHashNumber hash = HashBytes(&aKey->mRect.x, 4 * sizeof(gfxFloat)); + PLDHashNumber hash = 0; + hash = AddToHash(hash, aKey->mMinSize.width, aKey->mMinSize.height); hash = AddToHash(hash, aKey->mBlurRadius.width, aKey->mBlurRadius.height); - hash = AddToHash(hash, HashBytes(&aKey->mSkipRect.x, 4 * sizeof(gfxFloat))); + + hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.r, sizeof(gfxFloat))); + hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.g, sizeof(gfxFloat))); + hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.b, sizeof(gfxFloat))); + hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.a, sizeof(gfxFloat))); + + for (int i = 0; i < 4; i++) { + hash = AddToHash(hash, aKey->mCornerRadii[i].width, aKey->mCornerRadii[i].height); + } + hash = AddToHash(hash, (uint32_t)aKey->mBackend); + + if (aKey->mIsInset) { + hash = AddToHash(hash, aKey->mSpreadRadius.width, aKey->mSpreadRadius.height); + hash = AddToHash(hash, aKey->mInnerMinSize.width, aKey->mInnerMinSize.height); + hash = AddToHash(hash, HashBytes(&aKey->mHasBorderRadius, sizeof(bool))); + } return hash; } - bool KeyEquals(KeyTypePointer aKey) const + bool + KeyEquals(KeyTypePointer aKey) const { - if (aKey->mRect.IsEqualInterior(mRect) && + if (aKey->mMinSize == mMinSize && aKey->mBlurRadius == mBlurRadius && - aKey->mSkipRect.IsEqualInterior(mSkipRect) && + aKey->mCornerRadii == mCornerRadii && + aKey->mShadowColor == mShadowColor && aKey->mBackend == mBackend) { + + if (mIsInset) { + return (mHasBorderRadius == aKey->mHasBorderRadius) && + (mInnerMinSize == aKey->mInnerMinSize) && + (mSpreadRadius == aKey->mSpreadRadius); + } + return true; - } - return false; + } + + return false; } - static KeyTypePointer KeyToPointer(KeyType aKey) + + static KeyTypePointer + KeyToPointer(KeyType aKey) { return &aKey; } @@ -214,17 +273,15 @@ struct BlurCacheKey : public PLDHashEntryHdr { * to the cache entry to be able to be tracked by the nsExpirationTracker. * */ struct BlurCacheData { - BlurCacheData(SourceSurface* aBlur, const IntPoint& aTopLeft, const gfxRect& aDirtyRect, const BlurCacheKey& aKey) + BlurCacheData(SourceSurface* aBlur, IntMargin aExtendDestBy, const BlurCacheKey& aKey) : mBlur(aBlur) - , mTopLeft(aTopLeft) - , mDirtyRect(aDirtyRect) + , mExtendDest(aExtendDestBy) , mKey(aKey) {} BlurCacheData(const BlurCacheData& aOther) : mBlur(aOther.mBlur) - , mTopLeft(aOther.mTopLeft) - , mDirtyRect(aOther.mDirtyRect) + , mExtendDest(aOther.mExtendDest) , mKey(aOther.mKey) { } @@ -234,8 +291,7 @@ struct BlurCacheData { nsExpirationState mExpirationState; RefPtr mBlur; - IntPoint mTopLeft; - gfxRect mDirtyRect; + IntMargin mExtendDest; BlurCacheKey mKey; }; @@ -259,19 +315,38 @@ class BlurCache final : public nsExpirationTracker mHashEntries.Remove(aObject->mKey); } - BlurCacheData* Lookup(const gfxRect& aRect, + BlurCacheData* Lookup(const IntSize aMinSize, const IntSize& aBlurRadius, - const gfxRect& aSkipRect, - BackendType aBackendType, - const gfxRect* aDirtyRect) + RectCornerRadii* aCornerRadii, + const gfxRGBA& aShadowColor, + BackendType aBackendType) { BlurCacheData* blur = - mHashEntries.Get(BlurCacheKey(aRect, aBlurRadius, aSkipRect, aBackendType)); - + mHashEntries.Get(BlurCacheKey(aMinSize, aBlurRadius, + aCornerRadii, aShadowColor, + aBackendType)); + if (blur) { + MarkUsed(blur); + } + + return blur; + } + + BlurCacheData* LookupInsetBoxShadow(const IntSize aOuterMinSize, + const IntSize aInnerMinSize, + const IntSize& aBlurRadius, + const IntSize& aSpreadRadius, + const RectCornerRadii* aCornerRadii, + const gfxRGBA& aShadowColor, + const bool& aHasBorderRadius, + BackendType aBackendType) + { + BlurCacheKey key(aOuterMinSize, aInnerMinSize, + aBlurRadius, aSpreadRadius, + aCornerRadii, aShadowColor, + true, aHasBorderRadius, aBackendType); + BlurCacheData* blur = mHashEntries.Get(key); if (blur) { - if (aDirtyRect && !blur->mDirtyRect.Contains(*aDirtyRect)) { - return nullptr; - } MarkUsed(blur); } @@ -306,52 +381,173 @@ class BlurCache final : public nsExpirationTracker static BlurCache* gBlurCache = nullptr; -SourceSurface* -GetCachedBlur(DrawTarget *aDT, - const gfxRect& aRect, - const IntSize& aBlurRadius, - const gfxRect& aSkipRect, - const gfxRect& aDirtyRect, - IntPoint* aTopLeft) +static IntSize +ComputeMinSizeForShadowShape(RectCornerRadii* aCornerRadii, + IntSize aBlurRadius, + IntMargin& aSlice, + const IntSize& aRectSize) +{ + float cornerWidth = 0; + float cornerHeight = 0; + if (aCornerRadii) { + RectCornerRadii corners = *aCornerRadii; + for (size_t i = 0; i < 4; i++) { + cornerWidth = std::max(cornerWidth, corners[i].width); + cornerHeight = std::max(cornerHeight, corners[i].height); + } + } + + aSlice = IntMargin(ceil(cornerHeight) + aBlurRadius.height, + ceil(cornerWidth) + aBlurRadius.width, + ceil(cornerHeight) + aBlurRadius.height, + ceil(cornerWidth) + aBlurRadius.width); + + IntSize minSize(aSlice.LeftRight() + 1, + aSlice.TopBottom() + 1); + + // If aRectSize is smaller than minSize, the border-image approach won't + // work; there's no way to squeeze parts of the min box-shadow source + // image such that the result looks correct. So we need to adjust minSize + // in such a way that we can later draw it without stretching in the affected + // dimension. We also need to adjust "slice" to ensure that we're not trying + // to slice away more than we have. + if (aRectSize.width < minSize.width) { + minSize.width = aRectSize.width; + aSlice.left = 0; + aSlice.right = 0; + } + if (aRectSize.height < minSize.height) { + minSize.height = aRectSize.height; + aSlice.top = 0; + aSlice.bottom = 0; + } + + MOZ_ASSERT(aSlice.LeftRight() <= minSize.width); + MOZ_ASSERT(aSlice.TopBottom() <= minSize.height); + return minSize; +} + +void +CacheBlur(DrawTarget& aDT, + const IntSize& aMinSize, + const IntSize& aBlurRadius, + RectCornerRadii* aCornerRadii, + const gfxRGBA& aShadowColor, + IntMargin aExtendDest, + SourceSurface* aBoxShadow) +{ + BlurCacheKey key(aMinSize, aBlurRadius, aCornerRadii, aShadowColor, aDT.GetBackendType()); + BlurCacheData* data = new BlurCacheData(aBoxShadow, aExtendDest, key); + if (!gBlurCache->RegisterEntry(data)) { + delete data; + } +} + +// Blurs a small surface and creates the mask. +static already_AddRefed +CreateBlurMask(const IntSize& aRectSize, + RectCornerRadii* aCornerRadii, + IntSize aBlurRadius, + IntMargin& aExtendDestBy, + IntMargin& aSliceBorder, + DrawTarget& aDestDrawTarget) +{ + IntMargin slice; + gfxAlphaBoxBlur blur; + IntSize minSize = + ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, slice, aRectSize); + IntRect minRect(IntPoint(), minSize); + + gfxContext* blurCtx = blur.Init(ThebesRect(Rect(minRect)), IntSize(), + aBlurRadius, nullptr, nullptr); + + if (!blurCtx) { + return nullptr; + } + + DrawTarget* blurDT = blurCtx->GetDrawTarget(); + ColorPattern black(Color(0.f, 0.f, 0.f, 1.f)); + + if (aCornerRadii) { + RefPtr roundedRect = + MakePathForRoundedRect(*blurDT, Rect(minRect), *aCornerRadii); + blurDT->Fill(roundedRect, black); + } else { + blurDT->FillRect(Rect(minRect), black); + } + + IntPoint topLeft; + RefPtr result = blur.DoBlur(&aDestDrawTarget, &topLeft); + + IntRect expandedMinRect(topLeft, result->GetSize()); + aExtendDestBy = expandedMinRect - minRect; + aSliceBorder = slice + aExtendDestBy; + + MOZ_ASSERT(aSliceBorder.LeftRight() <= expandedMinRect.width); + MOZ_ASSERT(aSliceBorder.TopBottom() <= expandedMinRect.height); + + return result.forget(); +} + +static already_AddRefed +CreateBoxShadow(SourceSurface* aBlurMask, const gfxRGBA& aShadowColor) +{ + IntSize blurredSize = aBlurMask->GetSize(); + gfxPlatform* platform = gfxPlatform::GetPlatform(); + RefPtr boxShadowDT = + platform->CreateOffscreenContentDrawTarget(blurredSize, SurfaceFormat::B8G8R8A8); + + if (!boxShadowDT) { + return nullptr; + } + + MOZ_ASSERT(boxShadowDT->GetType() == aDT.GetType()); + + ColorPattern shadowColor(ToDeviceColor(aShadowColor)); + boxShadowDT->MaskSurface(shadowColor, aBlurMask, Point(0, 0)); + return boxShadowDT->Snapshot(); +} + +static SourceSurface* +GetBlur(DrawTarget& aDT, + const IntSize& aRectSize, + const IntSize& aBlurRadius, + RectCornerRadii* aCornerRadii, + const gfxRGBA& aShadowColor, + IntMargin& aExtendDestBy, + IntMargin& aSlice) { if (!gBlurCache) { gBlurCache = new BlurCache(); } - BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect, - aDT->GetBackendType(), - &aDirtyRect); + + IntSize minSize = + ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, aSlice, aRectSize); + + BlurCacheData* cached = gBlurCache->Lookup(minSize, aBlurRadius, + aCornerRadii, aShadowColor, + aDT.GetBackendType()); if (cached) { - *aTopLeft = cached->mTopLeft; + // See CreateBlurMask() for these values + aExtendDestBy = cached->mExtendDest; + aSlice = aSlice + aExtendDestBy; return cached->mBlur; } - return nullptr; -} -void -CacheBlur(DrawTarget *aDT, - const gfxRect& aRect, - const IntSize& aBlurRadius, - const gfxRect& aSkipRect, - SourceSurface* aBlur, - const IntPoint& aTopLeft, - const gfxRect& aDirtyRect) -{ - // If we already had a cached value with this key, but an incorrect dirty region then just update - // the existing entry - if (BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect, - aDT->GetBackendType(), - nullptr)) { - cached->mBlur = aBlur; - cached->mTopLeft = aTopLeft; - cached->mDirtyRect = aDirtyRect; - return; + RefPtr blurMask = + CreateBlurMask(aRectSize, aCornerRadii, aBlurRadius, aExtendDestBy, aSlice, aDT); + + if (!blurMask) { + return nullptr; } - BlurCacheKey key(aRect, aBlurRadius, aSkipRect, aDT->GetBackendType()); - BlurCacheData* data = new BlurCacheData(aBlur, aTopLeft, aDirtyRect, key); - if (!gBlurCache->RegisterEntry(data)) { - delete data; + RefPtr boxShadow = CreateBoxShadow(blurMask, aShadowColor); + if (!boxShadow) { + return nullptr; } + + CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow); + return boxShadow; } void @@ -361,8 +557,127 @@ gfxAlphaBoxBlur::ShutdownBlurCache() gBlurCache = nullptr; } +static Rect +RectWithEdgesTRBL(Float aTop, Float aRight, Float aBottom, Float aLeft) +{ + return Rect(aLeft, aTop, aRight - aLeft, aBottom - aTop); +} + +static void +RepeatOrStretchSurface(DrawTarget& aDT, SourceSurface* aSurface, + const Rect& aDest, const Rect& aSrc, Rect& aSkipRect) +{ + if (aSkipRect.Contains(aDest)) { + return; + } + + if ((!aDT.GetTransform().IsRectilinear() && + aDT.GetBackendType() != BackendType::CAIRO) || + (aDT.GetBackendType() == BackendType::DIRECT2D)) { + // Use stretching if possible, since it leads to less seams when the + // destination is transformed. However, don't do this if we're using cairo, + // because if cairo is using pixman it won't render anything for large + // stretch factors because pixman's internal fixed point precision is not + // high enough to handle those scale factors. + // Calling FillRect on a D2D backend with a repeating pattern is much slower + // than DrawSurface, so special case the D2D backend here. + aDT.DrawSurface(aSurface, aDest, aSrc); + return; + } + + SurfacePattern pattern(aSurface, ExtendMode::REPEAT, + Matrix::Translation(aDest.TopLeft() - aSrc.TopLeft()), + Filter::GOOD, RoundedToInt(aSrc)); + aDT.FillRect(aDest, pattern); +} + +static void +DrawCorner(DrawTarget& aDT, SourceSurface* aSurface, + const Rect& aDest, const Rect& aSrc, Rect& aSkipRect) +{ + if (aSkipRect.Contains(aDest)) { + return; + } + + aDT.DrawSurface(aSurface, aDest, aSrc); +} + +static void +DrawBoxShadows(DrawTarget& aDestDrawTarget, SourceSurface* aSourceBlur, + Rect aDstOuter, Rect aDstInner, Rect aSrcOuter, Rect aSrcInner, + Rect aSkipRect) +{ + // Corners: top left, top right, bottom left, bottom right + DrawCorner(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstOuter.Y(), aDstInner.X(), + aDstInner.Y(), aDstOuter.X()), + RectWithEdgesTRBL(aSrcOuter.Y(), aSrcInner.X(), + aSrcInner.Y(), aSrcOuter.X()), + aSkipRect); + + DrawCorner(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstOuter.Y(), aDstOuter.XMost(), + aDstInner.Y(), aDstInner.XMost()), + RectWithEdgesTRBL(aSrcOuter.Y(), aSrcOuter.XMost(), + aSrcInner.Y(), aSrcInner.XMost()), + aSkipRect); + + DrawCorner(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstInner.YMost(), aDstInner.X(), + aDstOuter.YMost(), aDstOuter.X()), + RectWithEdgesTRBL(aSrcInner.YMost(), aSrcInner.X(), + aSrcOuter.YMost(), aSrcOuter.X()), + aSkipRect); + + DrawCorner(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstInner.YMost(), aDstOuter.XMost(), + aDstOuter.YMost(), aDstInner.XMost()), + RectWithEdgesTRBL(aSrcInner.YMost(), aSrcOuter.XMost(), + aSrcOuter.YMost(), aSrcInner.XMost()), + aSkipRect); + + // Edges: top, left, right, bottom + RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstOuter.Y(), aDstInner.XMost(), + aDstInner.Y(), aDstInner.X()), + RectWithEdgesTRBL(aSrcOuter.Y(), aSrcInner.XMost(), + aSrcInner.Y(), aSrcInner.X()), + aSkipRect); + RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstInner.Y(), aDstInner.X(), + aDstInner.YMost(), aDstOuter.X()), + RectWithEdgesTRBL(aSrcInner.Y(), aSrcInner.X(), + aSrcInner.YMost(), aSrcOuter.X()), + aSkipRect); + RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstInner.Y(), aDstOuter.XMost(), + aDstInner.YMost(), aDstInner.XMost()), + RectWithEdgesTRBL(aSrcInner.Y(), aSrcOuter.XMost(), + aSrcInner.YMost(), aSrcInner.XMost()), + aSkipRect); + RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, + RectWithEdgesTRBL(aDstInner.YMost(), aDstInner.XMost(), + aDstOuter.YMost(), aDstInner.X()), + RectWithEdgesTRBL(aSrcInner.YMost(), aSrcInner.XMost(), + aSrcOuter.YMost(), aSrcInner.X()), + aSkipRect); +} + + +/*** + * We draw a blurred a rectangle by only blurring a smaller rectangle and + * splitting the rectangle into 9 parts. + * First, a small minimum source rect is calculated and used to create a blur + * mask since the actual blurring itself is expensive. Next, we use the mask + * with the given shadow color to create a minimally-sized box shadow of the + * right color. Finally, we cut out the 9 parts from the box-shadow source and + * paint each part in the right place, stretching the non-corner parts to fill + * the space between the corners. + */ + + /* static */ void -gfxAlphaBoxBlur::BlurRectangle(gfxContext *aDestinationCtx, +gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx, const gfxRect& aRect, RectCornerRadii* aCornerRadii, const gfxPoint& aBlurStdDev, @@ -370,43 +685,320 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContext *aDestinationCtx, const gfxRect& aDirtyRect, const gfxRect& aSkipRect) { - DrawTarget& aDrawTarget = *aDestinationCtx->GetDrawTarget(); - + DrawTarget& destDrawTarget = *aDestinationCtx->GetDrawTarget(); IntSize blurRadius = CalculateBlurRadius(aBlurStdDev); - IntPoint topLeft; - RefPtr surface = GetCachedBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, aDirtyRect, &topLeft); - if (!surface) { - // Create the temporary surface for blurring - gfxAlphaBoxBlur blur; - gfxContext* blurCtx = blur.Init(aRect, IntSize(), blurRadius, &aDirtyRect, &aSkipRect); - if (!blurCtx) { - return; - } - DrawTarget* blurDT = blurCtx->GetDrawTarget(); + IntRect rect = RoundedToInt(ToRect(aRect)); + IntMargin extendDestBy; + IntMargin slice; - Rect shadowGfxRect = ToRect(aRect); - shadowGfxRect.Round(); - - ColorPattern black(Color(0.f, 0.f, 0.f, 1.f)); // For masking, so no ToDeviceColor! - if (aCornerRadii) { - RefPtr roundedRect = MakePathForRoundedRect(*blurDT, - shadowGfxRect, - *aCornerRadii); - blurDT->Fill(roundedRect, black); - } else { - blurDT->FillRect(shadowGfxRect, black); - } - - surface = blur.DoBlur(&aDrawTarget, &topLeft); - if (!surface) { - return; - } - CacheBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, surface, topLeft, aDirtyRect); + RefPtr boxShadow = GetBlur(destDrawTarget, + rect.Size(), blurRadius, + aCornerRadii, aShadowColor, + extendDestBy, slice); + if (!boxShadow) { + return; } - aDestinationCtx->SetColor(aShadowColor); - Rect dirtyRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); - DrawBlur(aDestinationCtx, surface, topLeft, &dirtyRect); + destDrawTarget.PushClipRect(ToRect(aDirtyRect)); + + // Copy the right parts from boxShadow into destDrawTarget. The middle parts + // will be stretched, border-image style. + + Rect srcOuter(Point(), Size(boxShadow->GetSize())); + Rect srcInner = srcOuter; + srcInner.Deflate(Margin(slice)); + + rect.Inflate(extendDestBy); + Rect dstOuter(rect); + Rect dstInner(rect); + dstInner.Deflate(Margin(slice)); + + Rect skipRect = ToRect(aSkipRect); + + if (srcInner.IsEqualInterior(srcOuter)) { + MOZ_ASSERT(dstInner.IsEqualInterior(dstOuter)); + // The target rect is smaller than the minimal size so just draw the surface + destDrawTarget.DrawSurface(boxShadow, dstInner, srcInner); + } else { + DrawBoxShadows(destDrawTarget, boxShadow, dstOuter, dstInner, + srcOuter, srcInner, skipRect); + + // Middle part + RepeatOrStretchSurface(destDrawTarget, boxShadow, + RectWithEdgesTRBL(dstInner.Y(), dstInner.XMost(), + dstInner.YMost(), dstInner.X()), + RectWithEdgesTRBL(srcInner.Y(), srcInner.XMost(), + srcInner.YMost(), srcInner.X()), + skipRect); + } + + // A note about anti-aliasing and seems between adjacent parts: + // We don't explicitly disable anti-aliasing in the DrawSurface calls above, + // so if there's a transform on destDrawTarget that is not pixel-aligned, + // there will be seams between adjacent parts of the box-shadow. It's hard to + // avoid those without the use of an intermediate surface. + // You might think that we could avoid those by just turning of AA, but there + // is a problem with that: Box-shadow rendering needs to clip out the + // element's border box, and we'd like that clip to have anti-aliasing - + // especially if the element has rounded corners! So we can't do that unless + // we have a way to say "Please anti-alias the clip, but don't antialias the + // destination rect of the DrawSurface call". + // On OS X there is an additional problem with turning off AA: CoreGraphics + // will not just fill the pixels that have their pixel center inside the + // filled shape. Instead, it will fill all the pixels which are partially + // covered by the shape. So for pixels on the edge between two adjacent parts, + // all those pixels will be painted to by both parts, which looks very bad. + + destDrawTarget.PopClip(); } +static already_AddRefed +GetBoxShadowInsetPath(DrawTarget* aDrawTarget, + const Rect aOuterRect, const Rect aInnerRect, + const bool aHasBorderRadius, const RectCornerRadii& aInnerClipRadii) +{ + /*** + * We create an inset path by having two rects. + * + * ----------------------- + * | ________________ | + * | | | | + * | | | | + * | ------------------ | + * |_____________________| + * + * The outer rect and the inside rect. The path + * creates a frame around the content where we draw the inset shadow. + */ + RefPtr builder = + aDrawTarget->CreatePathBuilder(FillRule::FILL_EVEN_ODD); + AppendRectToPath(builder, aOuterRect, true); + + if (aHasBorderRadius) { + AppendRoundedRectToPath(builder, aInnerRect, aInnerClipRadii, false); + } else { + AppendRectToPath(builder, aInnerRect, false); + } + return builder->Finish(); +} + +static void +ComputeRectsForInsetBoxShadow(IntSize aBlurRadius, + IntSize aSpreadRadius, + Rect& aOutOuterRect, + Rect& aOutInnerRect, + Margin& aOutPathMargins, + const Rect& aDestRect, + const Rect& aShadowClipRect) +{ + IntSize marginSize = aBlurRadius + aSpreadRadius; + aOutPathMargins.SizeTo(marginSize.height, marginSize.width, marginSize.height, marginSize.width); + aOutPathMargins += aOutPathMargins; + + aOutOuterRect.x = 0; + aOutInnerRect.x = marginSize.width; + + aOutOuterRect.y = 0; + aOutInnerRect.y = marginSize.height; + + // + 1 for the middle edges so we can sample them + aOutInnerRect.width = aOutPathMargins.LeftRight() + 1; + aOutInnerRect.height = aOutPathMargins.TopBottom() + 1; + + // The outer path rect needs to be 1 blur radius past the inner edges + aOutOuterRect.width = aOutInnerRect.XMost() + marginSize.width; + aOutOuterRect.height = aOutInnerRect.YMost() + marginSize.height; + + if ((aOutOuterRect.width >= aDestRect.width) || + (aOutOuterRect.height >= aDestRect.height) || + (aOutInnerRect.width >= aShadowClipRect.width) || + (aOutInnerRect.height >= aShadowClipRect.height)) + { + aOutOuterRect.width = aDestRect.width; + aOutOuterRect.height = aDestRect.height; + aOutInnerRect.width = aShadowClipRect.width; + aOutInnerRect.height = aShadowClipRect.height; + aOutPathMargins.SizeTo(0, 0, 0, 0); + } +} + +static void +FillDestinationPath(gfxContext* aDestinationCtx, + const Rect aDestinationRect, + const Rect aShadowClipRect, + const Color& aShadowColor, + const bool aHasBorderRadius, + const RectCornerRadii& aInnerClipRadii) +{ + // When there is no blur radius, fill the path onto the destination + // surface. + aDestinationCtx->SetColor(ThebesColor(aShadowColor)); + DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget(); + RefPtr shadowPath = GetBoxShadowInsetPath(destDrawTarget, aDestinationRect, + aShadowClipRect, aHasBorderRadius, + aInnerClipRadii); + + aDestinationCtx->SetPath(shadowPath); + aDestinationCtx->Fill(); +} + +void +CacheInsetBlur(const IntSize aMinOuterSize, + const IntSize aMinInnerSize, + const IntSize& aBlurRadius, + const IntSize& aSpreadRadius, + const RectCornerRadii* aCornerRadii, + const gfxRGBA& aShadowColor, + const bool& aHasBorderRadius, + BackendType aBackendType, + IntMargin aExtendBy, + SourceSurface* aBoxShadow) +{ + BlurCacheKey key(aMinOuterSize, aMinInnerSize, + aBlurRadius, aSpreadRadius, + aCornerRadii, aShadowColor, + true, aHasBorderRadius, aBackendType); + BlurCacheData* data = new BlurCacheData(aBoxShadow, aExtendBy, key); + if (!gBlurCache->RegisterEntry(data)) { + delete data; + } +} + +already_AddRefed +gfxAlphaBoxBlur::GetInsetBlur(Rect& aOuterRect, + Rect& aInnerRect, + const IntSize& aBlurRadius, + const IntSize& aSpreadRadius, + const RectCornerRadii& aInnerClipRadii, + const Color& aShadowColor, + const bool& aHasBorderRadius, + IntPoint& aOutTopLeft, + gfxContext* aDestinationCtx) + +{ + if (!gBlurCache) { + gBlurCache = new BlurCache(); + } + + IntSize outerRectSize = RoundedToInt(aOuterRect).Size(); + IntSize innerRectSize = RoundedToInt(aInnerRect).Size(); + DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget(); + + BlurCacheData* cached = + gBlurCache->LookupInsetBoxShadow(outerRectSize, innerRectSize, aBlurRadius, aSpreadRadius, + &aInnerClipRadii, ThebesColor(aShadowColor), + aHasBorderRadius, destDrawTarget->GetBackendType()); + + if (cached) { + IntMargin extends = cached->mExtendDest; + aOutTopLeft.x = extends.left; + aOutTopLeft.y = extends.top; + // So we don't forget the actual cached blur + RefPtr cachedBlur = cached->mBlur; + return cachedBlur.forget(); + } + + // Dirty rect and skip rect are null for the min inset shadow. + // When rendering inset box shadows, we respect the spread radius by changing + // the shape of the unblurred shadow, and can pass a spread radius of zero here. + IntSize zeroSpread(0, 0); + gfxContext* minGfxContext = Init(ThebesRect(aOuterRect), zeroSpread, aBlurRadius, nullptr, nullptr); + if (!minGfxContext) { + return nullptr; + } + + DrawTarget* minDrawTarget = minGfxContext->GetDrawTarget(); + RefPtr maskPath = GetBoxShadowInsetPath(minDrawTarget, aOuterRect, + aInnerRect, aHasBorderRadius, + aInnerClipRadii); + + minGfxContext->SetColor(ThebesColor(aShadowColor)); + minGfxContext->SetPath(maskPath); + minGfxContext->Fill(); + + RefPtr minMask = DoBlur(minDrawTarget, &aOutTopLeft); + if (!minMask) { + return nullptr; + } + + RefPtr minInsetBlur = CreateBoxShadow(minMask, ThebesColor(aShadowColor)); + if (!minInsetBlur) { + return nullptr; + } + + IntMargin extendBy(aOutTopLeft.y, 0, 0, aOutTopLeft.x); + CacheInsetBlur(outerRectSize, innerRectSize, + aBlurRadius, aSpreadRadius, + &aInnerClipRadii, ThebesColor(aShadowColor), + aHasBorderRadius, destDrawTarget->GetBackendType(), + extendBy, minInsetBlur); + return minInsetBlur.forget(); +} + +/*** + * Blur an inset box shadow by doing: + * 1) Create a minimal box shadow path that creates a frame. + * 2) Draw the box shadow portion over the destination surface. + * 3) The "inset" part is created by a clip rect that properly clips + * the alpha mask so that it has clean edges. We still create the full + * proper alpha mask, but let the clip deal with the clean edges. + * + * All parameters should already be in device pixels. + */ +void +gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx, + const Rect aDestinationRect, + const Rect aShadowClipRect, + const IntSize aBlurRadius, + const IntSize aSpreadRadius, + const Color& aShadowColor, + bool aHasBorderRadius, + const RectCornerRadii& aInnerClipRadii, + const Rect aSkipRect) +{ + // Blur inset shadows ALWAYS have a 0 spread radius. + if ((aBlurRadius.width <= 0 && aBlurRadius.height <= 0)) { + FillDestinationPath(aDestinationCtx, aDestinationRect, aShadowClipRect, + aShadowColor, aHasBorderRadius, aInnerClipRadii); + return; + } + + DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget(); + Rect outerRect; + Rect innerRect; + Margin pathMargins; + ComputeRectsForInsetBoxShadow(aBlurRadius, aSpreadRadius, + outerRect, innerRect, + pathMargins, + aDestinationRect, + aShadowClipRect); + + IntPoint topLeft; + RefPtr minInsetBlur = GetInsetBlur(outerRect, innerRect, + aBlurRadius, aSpreadRadius, + aInnerClipRadii, aShadowColor, + aHasBorderRadius, + topLeft, aDestinationCtx); + if (!minInsetBlur) { + return; + } + + Rect destRectOuter(aDestinationRect); + Rect destRectInner(destRectOuter); + destRectInner.Deflate(pathMargins); + + Rect srcRectOuter(outerRect); + srcRectOuter.MoveBy(abs(topLeft.x), abs(topLeft.y)); + Rect srcRectInner(srcRectOuter); + srcRectInner.Deflate(pathMargins); + + if (srcRectOuter.IsEqualInterior(srcRectInner)) { + destDrawTarget->DrawSurface(minInsetBlur, destRectOuter, srcRectOuter); + } else { + DrawBoxShadows(*destDrawTarget, minInsetBlur, + destRectOuter, destRectInner, + srcRectOuter, srcRectInner, + aSkipRect); + } +} diff --git a/gfx/thebes/gfxBlur.h b/gfx/thebes/gfxBlur.h index 57466d7d4f..e5a7a03aec 100644 --- a/gfx/thebes/gfxBlur.h +++ b/gfx/thebes/gfxBlur.h @@ -20,6 +20,7 @@ struct gfxRGBA; namespace mozilla { namespace gfx { class AlphaBoxBlur; + struct Color; struct RectCornerRadii; class SourceSurface; class DrawTarget; @@ -135,9 +136,44 @@ public: static void ShutdownBlurCache(); - + /*** + * Blurs an inset box shadow according to a given path. + * This is equivalent to calling Init(), drawing the inset path, + * and calling paint. Do not call Init() if using this method. + * + * @param aDestinationCtx The destination to blur to. + * @param aDestinationRect The destination rect in device pixels + * @param aShadowClipRect The destiniation inner rect of the + * inset path in device pixels. + * @param aBlurRadius The standard deviation of the blur. + * @param aSpreadRadius The spread radius in device pixels. + * @param aShadowColor The color of the blur. + * @param aHasBorderRadius If this element also has a border radius + * @param aInnerClipRadii Corner radii for the inside rect if it is a rounded rect. + * @param aSKipRect An area in device pixels we don't have to paint in. + */ + void BlurInsetBox(gfxContext* aDestinationCtx, + const mozilla::gfx::Rect aDestinationRect, + const mozilla::gfx::Rect aShadowClipRect, + const mozilla::gfx::IntSize aBlurRadius, + const mozilla::gfx::IntSize aSpreadRadius, + const mozilla::gfx::Color& aShadowColor, + const bool aHasBorderRadius, + const RectCornerRadii& aInnerClipRadii, + const mozilla::gfx::Rect aSkipRect); protected: + already_AddRefed + GetInsetBlur(mozilla::gfx::Rect& aOuterRect, + mozilla::gfx::Rect& aInnerRect, + const mozilla::gfx::IntSize& aBlurRadius, + const mozilla::gfx::IntSize& aSpreadRadius, + const RectCornerRadii& aInnerClipRadii, + const mozilla::gfx::Color& aShadowColor, + const bool& aHasBorderRadius, + mozilla::gfx::IntPoint& aOutTopLeft, + gfxContext* aDestinationCtx); + /** * The context of the temporary alpha surface. */ diff --git a/gfx/thebes/gfxContext.cpp b/gfx/thebes/gfxContext.cpp index e6c1f1bc15..611a629925 100644 --- a/gfx/thebes/gfxContext.cpp +++ b/gfx/thebes/gfxContext.cpp @@ -494,15 +494,15 @@ gfxContext::CurrentLineWidth() const } void -gfxContext::SetOperator(GraphicsOperator op) +gfxContext::SetOp(CompositionOp aOp) { - CurrentState().op = CompositionOpForOp(op); + CurrentState().op = aOp; } -gfxContext::GraphicsOperator -gfxContext::CurrentOperator() const +CompositionOp +gfxContext::CurrentOp() const { - return ThebesOp(CurrentState().op); + return CurrentState().op; } void diff --git a/gfx/thebes/gfxContext.h b/gfx/thebes/gfxContext.h index f57de3648f..15034715cf 100644 --- a/gfx/thebes/gfxContext.h +++ b/gfx/thebes/gfxContext.h @@ -44,6 +44,7 @@ struct RectCornerRadii; */ class gfxContext final { typedef mozilla::gfx::CapStyle CapStyle; + typedef mozilla::gfx::CompositionOp CompositionOp; typedef mozilla::gfx::JoinStyle JoinStyle; typedef mozilla::gfx::FillRule FillRule; typedef mozilla::gfx::Path Path; @@ -368,53 +369,14 @@ public: void SetFillRule(FillRule rule); FillRule CurrentFillRule() const; - /** - ** Operators and Rendering control - **/ - - // define enum for operators (clear, src, dst, etc) - enum GraphicsOperator { - OPERATOR_SOURCE, - - OPERATOR_OVER, - OPERATOR_IN, - OPERATOR_OUT, - OPERATOR_ATOP, - - OPERATOR_DEST, - OPERATOR_DEST_OVER, - OPERATOR_DEST_IN, - OPERATOR_DEST_OUT, - OPERATOR_DEST_ATOP, - - OPERATOR_XOR, - OPERATOR_ADD, - OPERATOR_SATURATE, - - OPERATOR_MULTIPLY, - OPERATOR_SCREEN, - OPERATOR_OVERLAY, - OPERATOR_DARKEN, - OPERATOR_LIGHTEN, - OPERATOR_COLOR_DODGE, - OPERATOR_COLOR_BURN, - OPERATOR_HARD_LIGHT, - OPERATOR_SOFT_LIGHT, - OPERATOR_DIFFERENCE, - OPERATOR_EXCLUSION, - OPERATOR_HUE, - OPERATOR_SATURATION, - OPERATOR_COLOR, - OPERATOR_LUMINOSITY - }; /** * Sets the operator used for all further drawing. The operator affects * how drawing something will modify the destination. For example, the * OVER operator will do alpha blending of source and destination, while * SOURCE will replace the destination with the source. */ - void SetOperator(GraphicsOperator op); - GraphicsOperator CurrentOperator() const; + void SetOp(CompositionOp op); + CompositionOp CurrentOp() const; void SetAntialiasMode(mozilla::gfx::AntialiasMode mode); mozilla::gfx::AntialiasMode CurrentAntialiasMode() const; @@ -470,7 +432,7 @@ public: * the correct results and using an opaque pushed surface gives better * quality and performance. * This API really only makes sense if you do a PopGroupToSource and - * immediate Paint with OPERATOR_OVER. + * immediate Paint with OP_OVER. */ void PushGroupAndCopyBackground(gfxContentType content = gfxContentType::COLOR); already_AddRefed PopGroup(); @@ -518,7 +480,6 @@ private: typedef mozilla::gfx::Color Color; typedef mozilla::gfx::StrokeOptions StrokeOptions; typedef mozilla::gfx::Float Float; - typedef mozilla::gfx::CompositionOp CompositionOp; typedef mozilla::gfx::PathBuilder PathBuilder; typedef mozilla::gfx::SourceSurface SourceSurface; diff --git a/gfx/thebes/gfxDrawable.cpp b/gfx/thebes/gfxDrawable.cpp index 91ed9f8e10..18a68bd0e6 100644 --- a/gfx/thebes/gfxDrawable.cpp +++ b/gfx/thebes/gfxDrawable.cpp @@ -97,15 +97,14 @@ gfxSurfaceDrawable::DrawInternal(gfxContext* aContext, Rect fillRect = ToRect(aFillRect); DrawTarget* dt = aContext->GetDrawTarget(); - if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE && + if (aContext->CurrentOp() == CompositionOp::OP_SOURCE && aOpacity == 1.0) { // Emulate cairo operator source which is bound by mask! dt->ClearRect(fillRect); dt->FillRect(fillRect, pattern); } else { dt->FillRect(fillRect, pattern, - DrawOptions(aOpacity, - CompositionOpForOp(aContext->CurrentOperator()), + DrawOptions(aOpacity, aContext->CurrentOp(), aContext->CurrentAntialiasMode())); } } diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 4105b5c8f8..ab03390afe 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -1735,7 +1735,8 @@ gfxFont::DrawGlyphs(gfxShapedText *aShapedText, gfxFloat& inlineCoord = aFontParams.isVerticalFont ? aPt->y : aPt->x; if (aRunParams.spacing) { - inlineCoord += aRunParams.direction * aRunParams.spacing[0].mBefore; + inlineCoord += aRunParams.isRTL ? -aRunParams.spacing[0].mBefore + : aRunParams.spacing[0].mBefore; } const gfxShapedText::CompressedGlyph *glyphData = @@ -1814,7 +1815,7 @@ gfxFont::DrawGlyphs(gfxShapedText *aShapedText, buffer, &emittedGlyphs); } - inlineCoord += aRunParams.direction * advance; + inlineCoord += aRunParams.isRTL ? -advance : advance; } } } @@ -1824,7 +1825,7 @@ gfxFont::DrawGlyphs(gfxShapedText *aShapedText, if (i + 1 < aCount) { space += aRunParams.spacing[i + 1].mBefore; } - inlineCoord += aRunParams.direction * space; + inlineCoord += aRunParams.isRTL ? -space : space; } } @@ -1867,10 +1868,15 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd, const Metrics& metrics = GetMetrics(eHorizontal); // Get a matrix we can use to draw the (horizontally-shaped) textrun // with 90-degree CW rotation. - gfxMatrix mat = aRunParams.context->CurrentMatrix(). - Translate(p). // translate origin for rotation - Rotate(M_PI / 2.0). // turn 90deg clockwise - Translate(-p); // undo the translation + const gfxFloat + rotation = (aOrientation == + gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT) + ? -M_PI / 2.0 : M_PI / 2.0; + gfxMatrix mat = + aRunParams.context->CurrentMatrix(). + Translate(p). // translate origin for rotation + Rotate(rotation). // turn 90deg CCW (sideways-left) or CW (*-right) + Translate(-p); // undo the translation // If we're drawing rotated horizontal text for an element styled // text-orientation:mixed, the dominant baseline will be vertical- @@ -1980,7 +1986,14 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd, if (sideways) { aRunParams.context->Restore(); - *aPt = gfxPoint(origPt.x, origPt.y + (aPt->x - origPt.x)); + // adjust updated aPt to account for the transform we were using + gfxFloat advance = aPt->x - origPt.x; + if (aOrientation == + gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT) { + *aPt = gfxPoint(origPt.x, origPt.y - advance); + } else { + *aPt = gfxPoint(origPt.x, origPt.y + advance); + } } } diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index 3145436bf6..e33dac3aa9 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -964,8 +964,19 @@ public: return (GetFlags() & gfxTextRunFactory::TEXT_IS_RTL) != 0; } + bool IsSidewaysLeft() const { + return (GetFlags() & gfxTextRunFactory::TEXT_ORIENT_MASK) == + gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT; + } + + // Return true if the logical inline direction is reversed compared to + // normal physical coordinates (i.e. if it is leftwards or upwards) + bool IsInlineReversed() const { + return IsSidewaysLeft() != IsRightToLeft(); + } + gfxFloat GetDirection() const { - return IsRightToLeft() ? -1.0f : 1.0f; + return IsInlineReversed() ? -1.0f : 1.0f; } bool DisableLigatures() const { diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index 1e503e9b19..bef318567e 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -552,7 +552,7 @@ struct BufferAlphaColor { { // pop the text, using the color alpha as the opacity mContext->PopGroupToSource(); - mContext->SetOperator(gfxContext::OPERATOR_OVER); + mContext->SetOp(CompositionOp::OP_OVER); mContext->Paint(mAlpha); mContext->Restore(); } diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 8449544ac4..954d4ce256 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -397,20 +397,17 @@ IsSafeImageTransformComponent(gfxFloat aValue) * alpha channel or their alpha channel is uniformly opaque. * This differs per render mode. */ -static gfxContext::GraphicsOperator -OptimalFillOperator() +static CompositionOp +OptimalFillOp() { #ifdef XP_WIN if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() == gfxWindowsPlatform::RENDER_DIRECT2D) { // D2D -really- hates operator source. - return gfxContext::OPERATOR_OVER; - } else { -#endif - return gfxContext::OPERATOR_SOURCE; -#ifdef XP_WIN + return CompositionOp::OP_OVER; } #endif + return CompositionOp::OP_SOURCE; } // EXTEND_PAD won't help us here; we have to create a temporary surface to hold @@ -449,7 +446,7 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable, } nsRefPtr tmpCtx = new gfxContext(target); - tmpCtx->SetOperator(OptimalFillOperator()); + tmpCtx->SetOp(OptimalFillOp()); aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true, GraphicsFilter::FILTER_FAST, 1.0, gfxMatrix::Translation(needed.TopLeft())); RefPtr surface = target->Snapshot(); @@ -500,7 +497,7 @@ struct MOZ_STACK_CLASS AutoCairoPixmanBugWorkaround mContext->Clip(bounds); mContext->SetMatrix(currentMatrix); mContext->PushGroup(gfxContentType::COLOR_ALPHA); - mContext->SetOperator(gfxContext::OPERATOR_OVER); + mContext->SetOp(CompositionOp::OP_OVER); mPushedGroup = true; } @@ -604,6 +601,101 @@ static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter, } #endif +#ifdef MOZ_WIDGET_COCOA +// Only prescale a temporary surface if we're going to repeat it often. +// Scaling is expensive on OS X and without prescaling, we'd scale +// every tile of the repeated rect. However, using a temp surface also potentially uses +// more memory if the scaled image is large. So only prescale on a temp +// surface if we know we're going to repeat the image in either the X or Y axis +// multiple times. +static bool +ShouldUseTempSurface(Rect aImageRect, Rect aNeededRect) +{ + int repeatX = aNeededRect.width / aImageRect.width; + int repeatY = aNeededRect.height / aImageRect.height; + return (repeatX >= 5) || (repeatY >= 5); +} + +static bool +PrescaleAndTileDrawable(gfxDrawable* aDrawable, + gfxContext* aContext, + const ImageRegion& aRegion, + Rect aImageRect, + const GraphicsFilter& aFilter, + const SurfaceFormat aFormat, + gfxFloat aOpacity) +{ + gfxSize scaleFactor = aContext->CurrentMatrix().ScaleFactors(true); + gfxMatrix scaleMatrix = gfxMatrix::Scaling(scaleFactor.width, scaleFactor.height); + const float fuzzFactor = 0.01; + + // If we aren't scaling or translating, don't go down this path + if ((FuzzyEqual(scaleFactor.width, 1.0, fuzzFactor) && + FuzzyEqual(scaleFactor.width, 1.0, fuzzFactor)) || + aContext->CurrentMatrix().HasNonAxisAlignedTransform()) { + return false; + } + + gfxRect clipExtents = aContext->GetClipExtents(); + + // Inflate by one pixel because bilinear filtering will sample at most + // one pixel beyond the computed image pixel coordinate. + clipExtents.Inflate(1.0); + + gfxRect needed = aRegion.IntersectAndRestrict(clipExtents); + Rect scaledNeededRect = ToMatrix(scaleMatrix).TransformBounds(ToRect(needed)); + scaledNeededRect.RoundOut(); + if (scaledNeededRect.IsEmpty()) { + return false; + } + + Rect scaledImageRect = ToMatrix(scaleMatrix).TransformBounds(aImageRect); + if (!ShouldUseTempSurface(scaledImageRect, scaledNeededRect)) { + return false; + } + + IntSize scaledImageSize((int32_t)scaledImageRect.width, + (int32_t)scaledImageRect.height); + if (scaledImageSize.width != scaledImageRect.width || + scaledImageSize.height != scaledImageRect.height) { + // If the scaled image isn't pixel aligned, we'll get artifacts + // so we have to take the slow path. + return false; + } + + RefPtr scaledDT = + gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(scaledImageSize, aFormat); + if (!scaledDT) { + return false; + } + + nsRefPtr tmpCtx = new gfxContext(scaledDT); + scaledDT->SetTransform(ToMatrix(scaleMatrix)); + gfxRect gfxImageRect(aImageRect.x, aImageRect.y, aImageRect.width, aImageRect.height); + aDrawable->Draw(tmpCtx, gfxImageRect, true, aFilter, 1.0, gfxMatrix()); + + RefPtr scaledImage = scaledDT->Snapshot(); + + { + gfxContextMatrixAutoSaveRestore autoSR(aContext); + Matrix withoutScale = ToMatrix(aContext->CurrentMatrix()); + DrawTarget* destDrawTarget = aContext->GetDrawTarget(); + + // The translation still is in scaled units + withoutScale.PreScale(1.0 / scaleFactor.width, 1.0 / scaleFactor.height); + aContext->SetMatrix(ThebesMatrix(withoutScale)); + + DrawOptions drawOptions(aOpacity, aContext->CurrentOp(), + aContext->CurrentAntialiasMode()); + + SurfacePattern scaledImagePattern(scaledImage, ExtendMode::REPEAT, + Matrix(), ToFilter(aFilter)); + destDrawTarget->FillRect(scaledNeededRect, scaledImagePattern, drawOptions); + } + return true; +} +#endif // MOZ_WIDGET_COCOA + /* static */ void gfxUtils::DrawPixelSnapped(gfxContext* aContext, gfxDrawable* aDrawable, @@ -649,6 +741,14 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext, return; } +#ifdef MOZ_WIDGET_COCOA + if (PrescaleAndTileDrawable(aDrawable, aContext, aRegion, + ToRect(imageRect), aFilter, + aFormat, aOpacity)) { + return; + } +#endif + // On Mobile, we don't ever want to do this; it has the potential for // allocating very large temporary surfaces, especially since we'll // do full-page snapshots often (see bug 749426). @@ -995,9 +1095,7 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, } } -/* static */ void gfxUtils::ClearThebesSurface(gfxASurface* aSurface, - IntRect* aRect, - const gfxRGBA& aColor) +/* static */ void gfxUtils::ClearThebesSurface(gfxASurface* aSurface) { if (aSurface->CairoStatus()) { return; @@ -1007,14 +1105,9 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, return; } cairo_t* ctx = cairo_create(surf); - cairo_set_source_rgba(ctx, aColor.r, aColor.g, aColor.b, aColor.a); + cairo_set_source_rgba(ctx, 0.0, 0.0, 0.0, 0.0); cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE); - IntRect bounds; - if (aRect) { - bounds = *aRect; - } else { - bounds = IntRect(nsIntPoint(0, 0), aSurface->GetSize()); - } + IntRect bounds(nsIntPoint(0, 0), aSurface->GetSize()); cairo_rectangle(ctx, bounds.x, bounds.y, bounds.width, bounds.height); cairo_fill(ctx); cairo_destroy(ctx); diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index e0d7b3d898..260132807d 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -161,9 +161,7 @@ public: /** * Clears surface to aColor (which defaults to transparent black). */ - static void ClearThebesSurface(gfxASurface* aSurface, - mozilla::gfx::IntRect* aRect = nullptr, - const gfxRGBA& aColor = gfxRGBA(0.0, 0.0, 0.0, 0.0)); + static void ClearThebesSurface(gfxASurface* aSurface); /** * Creates a copy of aSurface, but having the SurfaceFormat aFormat. diff --git a/gfx/thebes/gfxXlibNativeRenderer.cpp b/gfx/thebes/gfxXlibNativeRenderer.cpp index e9b69fb59b..28b44867f2 100644 --- a/gfx/thebes/gfxXlibNativeRenderer.cpp +++ b/gfx/thebes/gfxXlibNativeRenderer.cpp @@ -474,7 +474,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size, // would permit copying the background but not drawing direct.) bool matrixIsIntegerTranslation = !matrix.HasNonIntegerTranslation(); bool canDrawOverBackground = matrixIsIntegerTranslation && - ctx->CurrentOperator() == gfxContext::OPERATOR_OVER; + ctx->CurrentOp() == CompositionOp::OP_OVER; // The padding of 0.5 for non-pixel-exact transformations used here is // the same as what _cairo_pattern_analyze_filter uses. diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp index 87608f41bb..6aa1bfdffd 100644 --- a/image/DynamicImage.cpp +++ b/image/DynamicImage.cpp @@ -130,7 +130,7 @@ DynamicImage::GetHeight(int32_t* aHeight) NS_IMETHODIMP DynamicImage::GetIntrinsicSize(nsSize* aSize) { - gfxIntSize intSize(mDrawable->Size()); + IntSize intSize(mDrawable->Size()); *aSize = nsSize(intSize.width, intSize.height); return NS_OK; } @@ -138,7 +138,7 @@ DynamicImage::GetIntrinsicSize(nsSize* aSize) NS_IMETHODIMP DynamicImage::GetIntrinsicRatio(nsSize* aSize) { - gfxIntSize intSize(mDrawable->Size()); + IntSize intSize(mDrawable->Size()); *aSize = nsSize(intSize.width, intSize.height); return NS_OK; } @@ -167,7 +167,7 @@ NS_IMETHODIMP_(already_AddRefed) DynamicImage::GetFrame(uint32_t aWhichFrame, uint32_t aFlags) { - gfxIntSize size(mDrawable->Size()); + IntSize size(mDrawable->Size()); return GetFrameAtSize(IntSize(size.width, size.height), aWhichFrame, aFlags); @@ -225,7 +225,7 @@ DynamicImage::Draw(gfxContext* aContext, { MOZ_ASSERT(!aSize.IsEmpty(), "Unexpected empty size"); - gfxIntSize drawableSize(mDrawable->Size()); + IntSize drawableSize(mDrawable->Size()); if (aSize == drawableSize) { gfxUtils::DrawPixelSnapped(aContext, mDrawable, drawableSize, aRegion, @@ -327,7 +327,7 @@ DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags) { - gfxIntSize size(mDrawable->Size()); + IntSize size(mDrawable->Size()); return nsIntSize(size.width, size.height); } diff --git a/image/OrientedImage.cpp b/image/OrientedImage.cpp index 5de600b8b3..0ec6dfe1d7 100644 --- a/image/OrientedImage.cpp +++ b/image/OrientedImage.cpp @@ -81,7 +81,7 @@ OrientedImage::GetFrame(uint32_t aWhichFrame, } // Get the underlying dimensions. - gfxIntSize size; + IntSize size; rv = InnerImage()->GetWidth(&size.width); NS_ENSURE_SUCCESS(rv, nullptr); rv = InnerImage()->GetHeight(&size.height); diff --git a/image/imgFrame.cpp b/image/imgFrame.cpp index f45a954a71..16aa92c9aa 100644 --- a/image/imgFrame.cpp +++ b/image/imgFrame.cpp @@ -539,7 +539,7 @@ imgFrame::SurfaceForDrawing(bool aDoPadding, aContext->Multiply(gfxMatrix::Translation(paddingTopLeft)); aImageRect = gfxRect(0, 0, mSize.width, mSize.height); - gfxIntSize availableSize(mDecoded.width, mDecoded.height); + IntSize availableSize(mDecoded.width, mDecoded.height); return SurfaceWithFormat(new gfxSurfaceDrawable(aSurface, availableSize), mFormat); } @@ -574,8 +574,7 @@ bool imgFrame::Draw(gfxContext* aContext, const ImageRegion& aRegion, RefPtr dt = aContext->GetDrawTarget(); dt->FillRect(ToRect(aRegion.Rect()), ColorPattern(mSinglePixelColor), - DrawOptions(1.0f, - CompositionOpForOp(aContext->CurrentOperator()))); + DrawOptions(1.0f, aContext->CurrentOp())); return true; } diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index c385d746d6..ee567c36e6 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -780,7 +780,8 @@ nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext, aDrawTarget.FillRect(joinedBorderAreaPx, color); #endif - nsCSSBorderRenderer br(&aDrawTarget, + nsCSSBorderRenderer br(aPresContext->Type(), + &aDrawTarget, joinedBorderAreaPx, borderStyles, borderWidths, @@ -915,7 +916,8 @@ nsCSSRendering::PaintOutline(nsPresContext* aPresContext, // start drawing gfxContext *ctx = aRenderingContext.ThebesContext(); - nsCSSBorderRenderer br(ctx->GetDrawTarget(), + nsCSSBorderRenderer br(aPresContext->Type(), + ctx->GetDrawTarget(), oRect, outlineStyles, outlineWidths, @@ -963,7 +965,8 @@ nsCSSRendering::PaintFocus(nsPresContext* aPresContext, // something that CSS can style, this function will then have access // to a style context and can use the same logic that PaintBorder // and PaintOutline do.) - nsCSSBorderRenderer br(ctx->GetDrawTarget(), + nsCSSBorderRenderer br(aPresContext->Type(), + ctx->GetDrawTarget(), focusRect, focusStyles, focusWidths, @@ -1418,6 +1421,7 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext, } } } + fragmentClip = fragmentClip.Intersect(aDirtyRect); renderContext-> Clip(NSRectToSnappedRect(fragmentClip, aForFrame->PresContext()->AppUnitsPerDevPixel(), @@ -1518,14 +1522,27 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, nsRect shadowPaintRect = paddingRect; shadowPaintRect.Inflate(blurMargin); + Rect shadowPaintGfxRect = NSRectToRect(shadowPaintRect, twipsPerPixel); + shadowPaintGfxRect.RoundOut(); + + // Round the spread radius to device pixels (by truncation). + // This mostly matches what we do for borders, except that we don't round + // up values between zero and one device pixels to one device pixel. + // This way of rounding is symmetric around zero, which makes sense for + // the spread radius. + int32_t spreadDistance = shadowItem->mSpread / twipsPerPixel; + nscoord spreadDistanceAppUnits = aPresContext->DevPixelsToAppUnits(spreadDistance); + nsRect shadowClipRect = paddingRect; shadowClipRect.MoveBy(shadowItem->mXOffset, shadowItem->mYOffset); - shadowClipRect.Deflate(shadowItem->mSpread, shadowItem->mSpread); + shadowClipRect.Deflate(spreadDistanceAppUnits, spreadDistanceAppUnits); + + Rect shadowClipGfxRect = NSRectToRect(shadowClipRect, twipsPerPixel); + shadowClipGfxRect.Round(); RectCornerRadii clipRectRadii; if (hasBorderRadius) { // Calculate the radii the inner clipping rect will have - Float spreadDistance = shadowItem->mSpread / twipsPerPixel; Float borderSizes[4] = {0, 0, 0, 0}; // See PaintBoxShadowOuter and bug 514670 @@ -1567,29 +1584,22 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, gfxContext* renderContext = aRenderingContext.ThebesContext(); DrawTarget* drawTarget = renderContext->GetDrawTarget(); nsContextBoxBlur blurringArea; - gfxContext* shadowContext = - blurringArea.Init(shadowPaintRect, 0, blurRadius, twipsPerPixel, - renderContext, aDirtyRect, &skipGfxRect); - if (!shadowContext) - continue; - DrawTarget* shadowDT = shadowContext->GetDrawTarget(); - - // shadowContext is owned by either blurringArea or aRenderingContext. - MOZ_ASSERT(shadowContext == renderContext || - shadowContext == blurringArea.GetContext()); - - // Set the shadow color; if not specified, use the foreground color - Color shadowColor = Color::FromABGR(shadowItem->mHasColor ? - shadowItem->mColor : - aForFrame->StyleColor()->mColor); - renderContext->Save(); - renderContext->SetColor(ThebesColor(shadowColor)); // Clip the context to the area of the frame's padding rect, so no part of the // shadow is painted outside. Also cut out anything beyond where the inset shadow // will be. Rect shadowGfxRect = NSRectToRect(paddingRect, twipsPerPixel); shadowGfxRect.Round(); + + // Set the shadow color; if not specified, use the foreground color + Color shadowColor = Color::FromABGR(shadowItem->mHasColor ? + shadowItem->mColor : + aForFrame->StyleColor()->mColor); + + renderContext->Save(); + + // This clips the outside border radius. + // clipRectRadii is the border radius inside the inset shadow. if (hasBorderRadius) { RefPtr roundedRect = MakePathForRoundedRect(*drawTarget, shadowGfxRect, innerRadii); @@ -1598,26 +1608,13 @@ nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext, renderContext->Clip(shadowGfxRect); } - // Fill the surface minus the area within the frame that we should - // not paint in, and blur and apply it. - Rect shadowPaintGfxRect = NSRectToRect(shadowPaintRect, twipsPerPixel); - shadowPaintGfxRect.RoundOut(); - Rect shadowClipGfxRect = NSRectToRect(shadowClipRect, twipsPerPixel); - shadowClipGfxRect.Round(); - RefPtr builder = - shadowDT->CreatePathBuilder(FillRule::FILL_EVEN_ODD); - AppendRectToPath(builder, shadowPaintGfxRect, true); - if (hasBorderRadius) { - AppendRoundedRectToPath(builder, shadowClipGfxRect, clipRectRadii, false); - } else { - AppendRectToPath(builder, shadowClipGfxRect, false); - } - RefPtr path = builder->Finish(); - shadowContext->SetPath(path); - shadowContext->Fill(); - shadowContext->NewPath(); - - blurringArea.DoPaint(); + nsContextBoxBlur insetBoxBlur; + gfxRect destRect = nsLayoutUtils::RectToGfxRect(shadowPaintRect, twipsPerPixel); + insetBoxBlur.InsetBoxBlur(renderContext, ToRect(destRect), + shadowClipGfxRect, shadowColor, + blurRadius, spreadDistanceAppUnits, + twipsPerPixel, hasBorderRadius, + clipRectRadii, ToRect(skipGfxRect)); renderContext->Restore(); } } @@ -2191,6 +2188,12 @@ ComputeRadialGradientLine(nsPresContext* aPresContext, } + +static float Interpolate(float aF1, float aF2, float aFrac) +{ + return aF1 + aFrac * (aF2 - aF1); +} + // Returns aFrac*aC2 + (1 - aFrac)*C1. The interpolation is done // in unpremultiplied space, which is what SVG gradients and cairo // gradients expect. @@ -2352,6 +2355,77 @@ static void ResolveMidpoints(nsTArray& stops) } } +static gfxRGBA +Premultiply(const gfxRGBA& aColor) +{ + gfxFloat a = aColor.a; + return gfxRGBA(aColor.r * a, aColor.g * a, aColor.b * a, a); +} + +static gfxRGBA +Unpremultiply(const gfxRGBA& aColor) +{ + gfxFloat a = aColor.a; + return (a > 0.0) ? gfxRGBA(aColor.r / a, aColor.g / a, aColor.b / a, a) : aColor; +} + +static gfxRGBA +TransparentColor(gfxRGBA aColor) { + aColor.a = 0; + return aColor; +} + +// Adjusts and adds color stops in such a way that drawing the gradient with +// unpremultiplied interpolation looks nearly the same as if it were drawn with +// premultiplied interpolation. +static const float kAlphaIncrementPerGradientStep = 0.1f; +static void +ResolvePremultipliedAlpha(nsTArray& aStops) +{ + for (size_t x = 1; x < aStops.Length(); x++) { + const ColorStop leftStop = aStops[x - 1]; + const ColorStop rightStop = aStops[x]; + + // if the left and right stop have the same alpha value, we don't need + // to do anything + if (leftStop.mColor.a == rightStop.mColor.a) { + continue; + } + + // Is the stop on the left 100% transparent? If so, have it adopt the color + // of the right stop + if (leftStop.mColor.a == 0) { + aStops[x - 1].mColor = TransparentColor(rightStop.mColor); + continue; + } + + // Is the stop on the right completely transparent? + // If so, duplicate it and assign it the color on the left. + if (rightStop.mColor.a == 0) { + ColorStop newStop = rightStop; + newStop.mColor = TransparentColor(leftStop.mColor); + aStops.InsertElementAt(x, newStop); + x++; + continue; + } + + // Now handle cases where one or both of the stops are partially transparent. + if (leftStop.mColor.a != 1.0f || rightStop.mColor.a != 1.0f) { + gfxRGBA premulLeftColor = Premultiply(leftStop.mColor); + gfxRGBA premulRightColor = Premultiply(rightStop.mColor); + // Calculate how many extra steps. We do a step per 10% transparency. + size_t stepCount = NSToIntFloor(fabs(leftStop.mColor.a - rightStop.mColor.a) / kAlphaIncrementPerGradientStep); + for (size_t y = 1; y < stepCount; y++) { + float frac = static_cast(y) / stepCount; + ColorStop newStop(Interpolate(leftStop.mPosition, rightStop.mPosition, frac), false, + Unpremultiply(InterpolateColor(premulLeftColor, premulRightColor, frac))); + aStops.InsertElementAt(x, newStop); + x++; + } + } + } +} + void nsCSSRendering::PaintGradient(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, @@ -2459,44 +2533,6 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, } } - // Special case for 'transparent' - for (uint32_t i = 0; i < stops.Length(); ++i) { - gfxRGBA color = stops[i].mColor; - if (color.r == 0 && color.g == 0 && color.b == 0 && color.a == 0) { - // We have (0,0,0,0) as a color stop - this means 'transparent'. - // In this case for the usually intended effect, we change the color - // of the transparent stop to the color of the adjacent stop with - // 0 opacity. If we are not on either edge, we add a stop on both - // sides of the transparent point with the adjacent color value. - // i.e.: c1 -> c1 (alpha 0) | c2 (alpha 0) -> c2 - // XXX: We should probably track the use of the transparent keyword - // down from the CSS parsing level to here with a flag in mStops, if - // rgba(0,0,0,0) ever is an intended thing (very much a corner case). - if (i > 0) { - // Change stop color to adjacent-previous (color->T) - color = stops[i - 1].mColor; - color.a = 0; - stops[i].mColor = color; - if (i < stops.Length() - 1) { - // We're in the middle somewhere: insert stop adjacent-next (T->color) - gfxRGBA color2 = stops[i + 1].mColor; - color2.a = 0; - if (color != color2) { - // Only insert an extra stop if c1 is different than c2 in c1->T->c2 - // Note: A transparent stop is never considered an interpolation hint - stops.InsertElementAt(i + 1, ColorStop(stops[i].mPosition, false, color2)); - i++; - } - } - } else if (i < stops.Length() - 1) { - // Change stop color to adjacent-next (T->color) - color = stops[i + 1].mColor; - color.a = 0; - stops[i].mColor = color; - } - } - } - // Eliminate negative-position stops if the gradient is radial. double firstStop = stops[0].mPosition; if (aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR && firstStop < 0.0) { @@ -2686,6 +2722,8 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, ResolveMidpoints(stops); + ResolvePremultipliedAlpha(stops); + bool isRepeat = aGradient->mRepeating || forceRepeatToCoverTiles; // Now set normalized color stops in pattern. @@ -2973,10 +3011,10 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, nsBackgroundLayerState state = PrepareBackgroundLayer(aPresContext, aForFrame, aFlags, paintBorderArea, clipState.mBGClipArea, layer); if (!state.mFillArea.IsEmpty()) { - if (state.mCompositingOp != gfxContext::OPERATOR_OVER) { - NS_ASSERTION(ctx->CurrentOperator() == gfxContext::OPERATOR_OVER, - "It is assumed the initial operator is OPERATOR_OVER, when it is restored later"); - ctx->SetOperator(state.mCompositingOp); + if (state.mCompositionOp != CompositionOp::OP_OVER) { + NS_ASSERTION(ctx->CurrentOp() == CompositionOp::OP_OVER, + "It is assumed the initial op is OP_OVER, when it is restored later"); + ctx->SetOp(state.mCompositionOp); } DrawResult resultForLayer = @@ -2990,8 +3028,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext, result = resultForLayer; } - if (state.mCompositingOp != gfxContext::OPERATOR_OVER) { - ctx->SetOperator(gfxContext::OPERATOR_OVER); + if (state.mCompositionOp != CompositionOp::OP_OVER) { + ctx->SetOp(CompositionOp::OP_OVER); } } } @@ -3401,7 +3439,7 @@ nsCSSRendering::PrepareBackgroundLayer(nsPresContext* aPresContext, } state.mFillArea.IntersectRect(state.mFillArea, bgClipRect); - state.mCompositingOp = GetGFXBlendMode(aLayer.mBlendMode); + state.mCompositionOp = GetGFXBlendMode(aLayer.mBlendMode); return state; } @@ -3962,8 +4000,11 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext, mozilla::css::Side ridgeGrooveSide = (horizontal) ? NS_SIDE_TOP : NS_SIDE_LEFT; // FIXME: In theory, this should use the visited-dependent // background color, but I don't care. - ctx->SetColor( - MakeBevelColor(ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor)); + nscolor bevelColor = MakeBevelColor(ridgeGrooveSide, ridgeGroove, + aBGColor->mBackgroundColor, + aBorderColor); + // XXXbz is this SetColor call still needed? + ctx->SetColor(bevelColor); nsRect rect(aBorder); nscoord half; if (horizontal) { // top, bottom @@ -3976,7 +4017,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext, if (NS_SIDE_TOP == aEndBevelSide) { rect.width -= endBevel; } - DrawSolidBorderSegment(aContext, rect, aBorderColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, + DrawSolidBorderSegment(aContext, rect, bevelColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, startBevel, aEndBevelSide, endBevel); } else { // left, right @@ -3989,7 +4030,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext, if (NS_SIDE_LEFT == aEndBevelSide) { rect.height -= endBevel; } - DrawSolidBorderSegment(aContext, rect, aBorderColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, + DrawSolidBorderSegment(aContext, rect, bevelColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, startBevel, aEndBevelSide, endBevel); } @@ -3997,8 +4038,10 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext, ridgeGrooveSide = (NS_SIDE_TOP == ridgeGrooveSide) ? NS_SIDE_BOTTOM : NS_SIDE_RIGHT; // FIXME: In theory, this should use the visited-dependent // background color, but I don't care. - ctx->SetColor( - MakeBevelColor(ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor)); + bevelColor = MakeBevelColor(ridgeGrooveSide, ridgeGroove, + aBGColor->mBackgroundColor, aBorderColor); + // XXXbz is this SetColor call still needed? + ctx->SetColor(bevelColor); if (horizontal) { rect.y = rect.y + half; rect.height = aBorder.height - half; @@ -4009,7 +4052,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext, if (NS_SIDE_BOTTOM == aEndBevelSide) { rect.width -= endBevel; } - DrawSolidBorderSegment(aContext, rect, aBorderColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, + DrawSolidBorderSegment(aContext, rect, bevelColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, startBevel, aEndBevelSide, endBevel); } else { @@ -4022,7 +4065,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext, if (NS_SIDE_RIGHT == aEndBevelSide) { rect.height -= endBevel; } - DrawSolidBorderSegment(aContext, rect, aBorderColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, + DrawSolidBorderSegment(aContext, rect, bevelColor, aAppUnitsPerDevPixel, twipsPerPixel, aStartBevelSide, startBevel, aEndBevelSide, endBevel); } } @@ -4627,12 +4670,11 @@ nsCSSRendering::GetTextDecorationRectInternal(const gfxPoint& aPt, } if (aVertical) { - r.y = baseline + floor(aOffset + 0.5); // this will need updating when we - // support sideways-left orientation + r.y = baseline + floor(offset + 0.5); Swap(r.x, r.y); Swap(r.width, r.height); } else { - r.y = baseline - floor(aOffset + 0.5); + r.y = baseline - floor(offset + 0.5); } return r; @@ -4822,7 +4864,7 @@ nsImageRenderer::ComputeIntrinsicSize() } } else { NS_ASSERTION(mImageElementSurface.mSourceSurface, "Surface should be ready."); - gfxIntSize surfaceSize = mImageElementSurface.mSize; + IntSize surfaceSize = mImageElementSurface.mSize; result.SetSize( nsSize(nsPresContext::CSSPixelsToAppUnits(surfaceSize.width), nsPresContext::CSSPixelsToAppUnits(surfaceSize.height))); @@ -5023,10 +5065,10 @@ nsImageRenderer::Draw(nsPresContext* aPresContext, } gfxContext* ctx = aRenderingContext.ThebesContext(); - gfxContext::GraphicsOperator op = ctx->CurrentOperator(); - if (op != gfxContext::OPERATOR_OVER) { + CompositionOp op = ctx->CurrentOp(); + if (op != CompositionOp::OP_OVER) { ctx->PushGroup(gfxContentType::COLOR_ALPHA); - ctx->SetOperator(gfxContext::OPERATOR_OVER); + ctx->SetOp(CompositionOp::OP_OVER); } nsCOMPtr image(ImageOps::CreateFromDrawable(drawable)); @@ -5035,7 +5077,7 @@ nsImageRenderer::Draw(nsPresContext* aPresContext, filter, aDest, aFill, aAnchor, aDirtyRect, ConvertImageRendererToDrawFlags(mFlags)); - if (op != gfxContext::OPERATOR_OVER) { + if (op != CompositionOp::OP_OVER) { ctx->PopGroupToSource(); ctx->Paint(); } @@ -5058,7 +5100,7 @@ nsImageRenderer::DrawableForElement(const nsRect& aImageRect, int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel(); nsRect destRect = aImageRect - aImageRect.TopLeft(); nsIntSize roundedOut = destRect.ToOutsidePixels(appUnitsPerDevPixel).Size(); - gfxIntSize imageSize(roundedOut.width, roundedOut.height); + IntSize imageSize(roundedOut.width, roundedOut.height); nsRefPtr drawable = nsSVGIntegrationUtils::DrawableFromPaintServer( mPaintServerFrame, mForFrame, mSize, imageSize, @@ -5318,7 +5360,7 @@ static inline gfxPoint ComputeBlurStdDev(nscoord aBlurRadius, gfxFloat(MAX_BLUR_RADIUS)) / 2.0); } -static inline gfxIntSize +static inline IntSize ComputeBlurRadius(nscoord aBlurRadius, int32_t aAppUnitsPerDevPixel, gfxFloat aScaleX = 1.0, @@ -5347,27 +5389,12 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius, return nullptr; } - gfxFloat scaleX = 1; - gfxFloat scaleY = 1; + IntSize blurRadius; + IntSize spreadRadius; + GetBlurAndSpreadRadius(aDestinationCtx, aAppUnitsPerDevPixel, + aBlurRadius, aSpreadRadius, + blurRadius, spreadRadius); - // Do blurs in device space when possible. - // Chrome/Skia always does the blurs in device space - // and will sometimes get incorrect results (e.g. rotated blurs) - gfxMatrix transform = aDestinationCtx->CurrentMatrix(); - // XXX: we could probably handle negative scales but for now it's easier just to fallback - if (transform.HasNonAxisAlignedTransform() || transform._11 <= 0.0 || transform._22 <= 0.0) { - transform = gfxMatrix(); - } else { - scaleX = transform._11; - scaleY = transform._22; - } - - // compute a large or smaller blur radius - gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY); - gfxIntSize spreadRadius = gfxIntSize(std::min(int32_t(aSpreadRadius * scaleX / aAppUnitsPerDevPixel), - int32_t(MAX_SPREAD_RADIUS)), - std::min(int32_t(aSpreadRadius * scaleY / aAppUnitsPerDevPixel), - int32_t(MAX_SPREAD_RADIUS))); mDestinationCtx = aDestinationCtx; // If not blurring, draw directly onto the destination device @@ -5385,6 +5412,7 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius, nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel); dirtyRect.RoundOut(); + gfxMatrix transform = aDestinationCtx->CurrentMatrix(); rect = transform.TransformBounds(rect); mPreTransformed = !transform.IsIdentity(); @@ -5411,8 +5439,9 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius, void nsContextBoxBlur::DoPaint() { - if (mContext == mDestinationCtx) + if (mContext == mDestinationCtx) { return; + } gfxContextMatrixAutoSaveRestore saveMatrix(mDestinationCtx); @@ -5433,7 +5462,7 @@ nsContextBoxBlur::GetContext() nsContextBoxBlur::GetBlurRadiusMargin(nscoord aBlurRadius, int32_t aAppUnitsPerDevPixel) { - gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel); + IntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel); nsMargin result; result.top = result.bottom = blurRadius.height * aAppUnitsPerDevPixel; @@ -5510,3 +5539,99 @@ nsContextBoxBlur::BlurRectangle(gfxContext* aDestinationCtx, dirtyRect, skipRect); } + +/* static */ void +nsContextBoxBlur::GetBlurAndSpreadRadius(gfxContext* aDestinationCtx, + int32_t aAppUnitsPerDevPixel, + nscoord aBlurRadius, + nscoord aSpreadRadius, + IntSize& aOutBlurRadius, + IntSize& aOutSpreadRadius, + bool aConstrainSpreadRadius) +{ + gfxFloat scaleX = 1; + gfxFloat scaleY = 1; + + // Do blurs in device space when possible. + // Chrome/Skia always does the blurs in device space + // and will sometimes get incorrect results (e.g. rotated blurs) + gfxMatrix transform = aDestinationCtx->CurrentMatrix(); + // XXX: we could probably handle negative scales but for now it's easier just to fallback + if (transform.HasNonAxisAlignedTransform() || transform._11 <= 0.0 || transform._22 <= 0.0) { + transform = gfxMatrix(); + } else { + scaleX = transform._11; + scaleY = transform._22; + } + + // compute a large or smaller blur radius + aOutBlurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY); + aOutSpreadRadius = + IntSize(int32_t(aSpreadRadius * scaleX / aAppUnitsPerDevPixel), + int32_t(aSpreadRadius * scaleY / aAppUnitsPerDevPixel)); + + + if (aConstrainSpreadRadius) { + aOutSpreadRadius.width = std::min(aOutSpreadRadius.width, int32_t(MAX_SPREAD_RADIUS)); + aOutSpreadRadius.height = std::min(aOutSpreadRadius.height, int32_t(MAX_SPREAD_RADIUS)); + } +} + +/* static */ bool +nsContextBoxBlur::InsetBoxBlur(gfxContext* aDestinationCtx, + Rect aDestinationRect, + Rect aShadowClipRect, + Color& aShadowColor, + nscoord aBlurRadiusAppUnits, + nscoord aSpreadDistanceAppUnits, + int32_t aAppUnitsPerDevPixel, + bool aHasBorderRadius, + RectCornerRadii& aInnerClipRectRadii, + Rect aSkipRect) +{ + if (aDestinationRect.IsEmpty()) { + mContext = nullptr; + return false; + } + + IntSize blurRadius; + IntSize spreadRadius; + // Convert the blur and spread radius to device pixels + bool constrainSpreadRadius = false; + GetBlurAndSpreadRadius(aDestinationCtx, aAppUnitsPerDevPixel, + aBlurRadiusAppUnits, aSpreadDistanceAppUnits, + blurRadius, spreadRadius, constrainSpreadRadius); + + // The blur and spread radius are scaled already, so scale all + // input data to the blur. This way, we don't have to scale the min + // inset blur to the invert of the dest context, then rescale it back + // when we draw to the destination surface. + gfxSize scale = aDestinationCtx->CurrentMatrix().ScaleFactors(true); + Matrix currentMatrix = ToMatrix(aDestinationCtx->CurrentMatrix()); + + Rect transformedDestRect = currentMatrix.TransformBounds(aDestinationRect); + Rect transformedShadowClipRect = currentMatrix.TransformBounds(aShadowClipRect); + Rect transformedSkipRect = currentMatrix.TransformBounds(aSkipRect); + + transformedDestRect.Round(); + transformedShadowClipRect.Round(); + transformedSkipRect.RoundIn(); + + for (size_t i = 0; i < 4; i++) { + aInnerClipRectRadii[i].width = std::floor(scale.width * aInnerClipRectRadii[i].width); + aInnerClipRectRadii[i].height = std::floor(scale.height * aInnerClipRectRadii[i].height); + } + + { + gfxContextAutoSaveRestore autoRestore(aDestinationCtx); + aDestinationCtx->SetMatrix(gfxMatrix()); + + mAlphaBoxBlur.BlurInsetBox(aDestinationCtx, transformedDestRect, + transformedShadowClipRect, + blurRadius, spreadRadius, + aShadowColor, + aHasBorderRadius, + aInnerClipRectRadii, transformedSkipRect); + } + return true; +} diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index a166c52d2e..910c8bd029 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -25,6 +25,7 @@ class nsRenderingContext; namespace mozilla { namespace gfx { +struct Color; class DrawTarget; } // namespace gfx @@ -298,11 +299,16 @@ private: * See PrepareBackgroundLayer. */ struct nsBackgroundLayerState { + typedef mozilla::gfx::CompositionOp CompositionOp; + /** * @param aFlags some combination of nsCSSRendering::PAINTBG_* flags */ - nsBackgroundLayerState(nsIFrame* aForFrame, const nsStyleImage* aImage, uint32_t aFlags) - : mImageRenderer(aForFrame, aImage, aFlags), mCompositingOp(gfxContext::OPERATOR_OVER) {} + nsBackgroundLayerState(nsIFrame* aForFrame, const nsStyleImage* aImage, + uint32_t aFlags) + : mImageRenderer(aForFrame, aImage, aFlags) + , mCompositionOp(CompositionOp::OP_OVER) + {} /** * The nsImageRenderer that will be used to draw the background. @@ -332,12 +338,13 @@ struct nsBackgroundLayerState { */ nsSize mRepeatSize; /** - * The compositing operation that the image should use + * The composition operation that the image should use. */ - gfxContext::GraphicsOperator mCompositingOp; + CompositionOp mCompositionOp; }; struct nsCSSRendering { + typedef mozilla::gfx::CompositionOp CompositionOp; typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::gfx::Float Float; typedef mozilla::gfx::Rect Rect; @@ -765,28 +772,26 @@ struct nsCSSRendering { bool aVertical, const gfxFloat aDescentLimit = -1.0); - static gfxContext::GraphicsOperator GetGFXBlendMode(uint8_t mBlendMode) { + static CompositionOp GetGFXBlendMode(uint8_t mBlendMode) { switch (mBlendMode) { - case NS_STYLE_BLEND_NORMAL: return gfxContext::OPERATOR_OVER; - case NS_STYLE_BLEND_MULTIPLY: return gfxContext::OPERATOR_MULTIPLY; - case NS_STYLE_BLEND_SCREEN: return gfxContext::OPERATOR_SCREEN; - case NS_STYLE_BLEND_OVERLAY: return gfxContext::OPERATOR_OVERLAY; - case NS_STYLE_BLEND_DARKEN: return gfxContext::OPERATOR_DARKEN; - case NS_STYLE_BLEND_LIGHTEN: return gfxContext::OPERATOR_LIGHTEN; - case NS_STYLE_BLEND_COLOR_DODGE: return gfxContext::OPERATOR_COLOR_DODGE; - case NS_STYLE_BLEND_COLOR_BURN: return gfxContext::OPERATOR_COLOR_BURN; - case NS_STYLE_BLEND_HARD_LIGHT: return gfxContext::OPERATOR_HARD_LIGHT; - case NS_STYLE_BLEND_SOFT_LIGHT: return gfxContext::OPERATOR_SOFT_LIGHT; - case NS_STYLE_BLEND_DIFFERENCE: return gfxContext::OPERATOR_DIFFERENCE; - case NS_STYLE_BLEND_EXCLUSION: return gfxContext::OPERATOR_EXCLUSION; - case NS_STYLE_BLEND_HUE: return gfxContext::OPERATOR_HUE; - case NS_STYLE_BLEND_SATURATION: return gfxContext::OPERATOR_SATURATION; - case NS_STYLE_BLEND_COLOR: return gfxContext::OPERATOR_COLOR; - case NS_STYLE_BLEND_LUMINOSITY: return gfxContext::OPERATOR_LUMINOSITY; - default: MOZ_ASSERT(false); return gfxContext::OPERATOR_OVER; + case NS_STYLE_BLEND_NORMAL: return CompositionOp::OP_OVER; + case NS_STYLE_BLEND_MULTIPLY: return CompositionOp::OP_MULTIPLY; + case NS_STYLE_BLEND_SCREEN: return CompositionOp::OP_SCREEN; + case NS_STYLE_BLEND_OVERLAY: return CompositionOp::OP_OVERLAY; + case NS_STYLE_BLEND_DARKEN: return CompositionOp::OP_DARKEN; + case NS_STYLE_BLEND_LIGHTEN: return CompositionOp::OP_LIGHTEN; + case NS_STYLE_BLEND_COLOR_DODGE: return CompositionOp::OP_COLOR_DODGE; + case NS_STYLE_BLEND_COLOR_BURN: return CompositionOp::OP_COLOR_BURN; + case NS_STYLE_BLEND_HARD_LIGHT: return CompositionOp::OP_HARD_LIGHT; + case NS_STYLE_BLEND_SOFT_LIGHT: return CompositionOp::OP_SOFT_LIGHT; + case NS_STYLE_BLEND_DIFFERENCE: return CompositionOp::OP_DIFFERENCE; + case NS_STYLE_BLEND_EXCLUSION: return CompositionOp::OP_EXCLUSION; + case NS_STYLE_BLEND_HUE: return CompositionOp::OP_HUE; + case NS_STYLE_BLEND_SATURATION: return CompositionOp::OP_SATURATION; + case NS_STYLE_BLEND_COLOR: return CompositionOp::OP_COLOR; + case NS_STYLE_BLEND_LUMINOSITY: return CompositionOp::OP_LUMINOSITY; + default: MOZ_ASSERT(false); return CompositionOp::OP_OVER; } - - return gfxContext::OPERATOR_OVER; } protected: @@ -954,7 +959,48 @@ public: const nsRect& aDirtyRect, const gfxRect& aSkipRect); + /** + * Draws a blurred inset box shadow shape onto the destination surface. + * Like BlurRectangle, this is equivalent to calling Init(), + * drawing a rectangle onto the returned surface + * and then calling DoPaint, but may let us optimize better in the + * backend. + * + * @param aDestinationCtx The destination to blur to. + * @param aDestinationRect The rectangle to blur in app units. + * @param aShadowClipRect The inside clip rect that creates the path. + * @param aShadowColor The color of the blur + * @param aBlurRadiusAppUnits The blur radius in app units + * @param aSpreadRadiusAppUnits The spread radius in app units. + * @param aAppUnitsPerDevPixel The number of app units in a device pixel, + * for conversion. Most of the time you'll + * pass this from the current PresContext if + * available. + * @param aHasBorderRadius If this inset box blur has a border radius + * @param aInnerClipRectRadii The clip rect radii used for the inside rect's path. + * @param aSkipRect An area in device pixels (NOT app units!) to avoid + * blurring over, to prevent unnecessary work. + */ + bool InsetBoxBlur(gfxContext* aDestinationCtx, + mozilla::gfx::Rect aDestinationRect, + mozilla::gfx::Rect aShadowClipRect, + mozilla::gfx::Color& aShadowColor, + nscoord aBlurRadiusAppUnits, + nscoord aSpreadRadiusAppUnits, + int32_t aAppUnitsPerDevPixel, + bool aHasBorderRadius, + RectCornerRadii& aInnerClipRectRadii, + mozilla::gfx::Rect aSkipRect); + protected: + static void GetBlurAndSpreadRadius(gfxContext* aContext, + int32_t aAppUnitsPerDevPixel, + nscoord aBlurRadius, + nscoord aSpreadRadius, + mozilla::gfx::IntSize& aOutBlurRadius, + mozilla::gfx::IntSize& aOutSpreadRadius, + bool aConstrainSpreadRadius = true); + gfxAlphaBoxBlur mAlphaBoxBlur; nsRefPtr mContext; gfxContext* mDestinationCtx; @@ -962,7 +1008,6 @@ protected: /* This is true if the blur already has it's content transformed * by mDestinationCtx's transform */ bool mPreTransformed; - }; #endif /* nsCSSRendering_h___ */ diff --git a/layout/base/nsCSSRenderingBorders.cpp b/layout/base/nsCSSRenderingBorders.cpp index 8fccd76a28..d411d6adbd 100644 --- a/layout/base/nsCSSRenderingBorders.cpp +++ b/layout/base/nsCSSRenderingBorders.cpp @@ -118,7 +118,8 @@ typedef enum { CORNER_DOT } CornerStyle; -nsCSSBorderRenderer::nsCSSBorderRenderer(DrawTarget* aDrawTarget, +nsCSSBorderRenderer::nsCSSBorderRenderer(nsPresContext::nsPresContextType aPresContextType, + DrawTarget* aDrawTarget, Rect& aOuterRect, const uint8_t* aBorderStyles, const Float* aBorderWidths, @@ -126,7 +127,8 @@ nsCSSBorderRenderer::nsCSSBorderRenderer(DrawTarget* aDrawTarget, const nscolor* aBorderColors, nsBorderColors* const* aCompositeColors, nscolor aBackgroundColor) - : mDrawTarget(aDrawTarget), + : mPresContextType(aPresContextType), + mDrawTarget(aDrawTarget), mOuterRect(aOuterRect), mBorderStyles(aBorderStyles), mBorderWidths(aBorderWidths), @@ -1448,7 +1450,8 @@ nsCSSBorderRenderer::DrawNoCompositeColorSolidBorder() Float skirtSize = 0.0f, skirtSlope = 0.0f; // the sides don't match, so compute a skirt - if (firstColor != secondColor) { + if (firstColor != secondColor && + mPresContextType != nsPresContext::eContext_Print) { Point cornerDir = outerCorner - innerCorner; ComputeCornerSkirtSize(firstColor.a, secondColor.a, cornerDir.DotProduct(cornerMults[i]), @@ -1710,7 +1713,7 @@ nsCSSBorderRenderer::DrawBorders() } // If we have composite colors -and- border radius, - // then use separate corners so we get OPERATOR_ADD for the corners. + // then use separate corners so we get OP_ADD for the corners. // Otherwise, we'll get artifacts as we draw stacked 1px-wide curves. if (allBordersSame && mCompositeColors[0] != nullptr && !mNoBorderRadius) forceSeparateCorners = true; @@ -1818,7 +1821,7 @@ nsCSSBorderRenderer::DrawBorders() // but we weren't able to render just a solid block for the corner. DrawBorderSides(sideBits); } else { - // Sides are different. We could draw using OPERATOR_ADD to + // Sides are different. We could draw using OP_ADD to // get correct color blending behaviour at the seam. We'd need // to do it in an offscreen surface to ensure that we're // always compositing on transparent black. If the colors diff --git a/layout/base/nsCSSRenderingBorders.h b/layout/base/nsCSSRenderingBorders.h index 355baa3fd7..581577847c 100644 --- a/layout/base/nsCSSRenderingBorders.h +++ b/layout/base/nsCSSRenderingBorders.h @@ -15,6 +15,7 @@ #include "nsColor.h" #include "nsCOMPtr.h" #include "nsStyleConsts.h" +#include "nsPresContext.h" struct nsBorderColors; @@ -85,7 +86,8 @@ class nsCSSBorderRenderer final public: - nsCSSBorderRenderer(DrawTarget* aDrawTarget, + nsCSSBorderRenderer(nsPresContext::nsPresContextType aPresContextType, + DrawTarget* aDrawTarget, Rect& aOuterRect, const uint8_t* aBorderStyles, const Float* aBorderWidths, @@ -114,6 +116,9 @@ private: RectCornerRadii mBorderCornerDimensions; + // the PresContext type + nsPresContext::nsPresContextType mPresContextType; + // destination DrawTarget DrawTarget* mDrawTarget; diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 2ed4cf9afa..0adbedcfde 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -925,7 +925,8 @@ nsCaret::ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset, { NS_ASSERTION(aFrame, "Should have a frame here"); - bool isVertical = aFrame->GetWritingMode().IsVertical(); + WritingMode wm = aFrame->GetWritingMode(); + bool isVertical = wm.IsVertical(); nscoord bidiIndicatorSize; *aCaretRect = GetGeometryForFrame(aFrame, aFrameOffset, &bidiIndicatorSize); @@ -957,11 +958,20 @@ nsCaret::ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset, } bool isCaretRTL = caretBidiLevel % 2; if (isVertical) { - aHookRect->SetRect(aCaretRect->XMost() - bidiIndicatorSize, - aCaretRect->y + (isCaretRTL ? bidiIndicatorSize * -1 : - aCaretRect->height), - aCaretRect->height, - bidiIndicatorSize); + bool isSidewaysLR = wm.IsVerticalLR() && !wm.IsLineInverted(); + if (isSidewaysLR) { + aHookRect->SetRect(aCaretRect->x + bidiIndicatorSize, + aCaretRect->y + (!isCaretRTL ? bidiIndicatorSize * -1 : + aCaretRect->height), + aCaretRect->height, + bidiIndicatorSize); + } else { + aHookRect->SetRect(aCaretRect->XMost() - bidiIndicatorSize, + aCaretRect->y + (isCaretRTL ? bidiIndicatorSize * -1 : + aCaretRect->height), + aCaretRect->height, + bidiIndicatorSize); + } } else { aHookRect->SetRect(aCaretRect->x + (isCaretRTL ? bidiIndicatorSize * -1 : aCaretRect->width), diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 933acfe810..84be6e6a02 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -668,8 +668,7 @@ static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) { void nsDisplayListBuilder::SetContainsBlendMode(uint8_t aBlendMode) { MOZ_ASSERT(aBlendMode != NS_STYLE_BLEND_NORMAL); - gfxContext::GraphicsOperator op = nsCSSRendering::GetGFXBlendMode(aBlendMode); - mContainedBlendModes += gfx::CompositionOpForOp(op); + mContainedBlendModes += nsCSSRendering::GetGFXBlendMode(aBlendMode); } bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem) @@ -4011,11 +4010,11 @@ nsDisplayMixBlendMode::GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerLayerParameters& aParameters) { - gfxContext::GraphicsOperator op = nsCSSRendering::GetGFXBlendMode(mFrame->StyleDisplay()->mMixBlendMode); - if (aManager->SupportsMixBlendMode(gfx::CompositionOpForOp(op))) { - return LAYER_ACTIVE; - } - return LAYER_INACTIVE; + CompositionOp op = + nsCSSRendering::GetGFXBlendMode(mFrame->StyleDisplay()->mMixBlendMode); + return aManager->SupportsMixBlendMode(op) + ? LAYER_ACTIVE + : LAYER_INACTIVE; } // nsDisplayMixBlendMode uses layers for rendering @@ -4033,7 +4032,7 @@ nsDisplayMixBlendMode::BuildLayer(nsDisplayListBuilder* aBuilder, return nullptr; } - container->DeprecatedSetMixBlendMode(nsCSSRendering::GetGFXBlendMode(mFrame->StyleDisplay()->mMixBlendMode)); + container->SetMixBlendMode(nsCSSRendering::GetGFXBlendMode(mFrame->StyleDisplay()->mMixBlendMode)); return container.forget(); } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 67b4a6f419..1bf98a6dfb 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -6686,36 +6686,35 @@ nsLayoutUtils::GetTextRunFlagsForStyle(nsStyleContext* aStyleContext, /* static */ uint32_t nsLayoutUtils::GetTextRunOrientFlagsForStyle(nsStyleContext* aStyleContext) { - WritingMode wm(aStyleContext); - if (wm.IsVertical()) { + uint8_t writingMode = aStyleContext->StyleVisibility()->mWritingMode; + switch (writingMode) { + case NS_STYLE_WRITING_MODE_HORIZONTAL_TB: + return gfxTextRunFactory::TEXT_ORIENT_HORIZONTAL; + + case NS_STYLE_WRITING_MODE_VERTICAL_LR: + case NS_STYLE_WRITING_MODE_VERTICAL_RL: switch (aStyleContext->StyleVisibility()->mTextOrientation) { case NS_STYLE_TEXT_ORIENTATION_MIXED: return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_MIXED; case NS_STYLE_TEXT_ORIENTATION_UPRIGHT: return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT; case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS: - // This should depend on writing mode vertical-lr vs vertical-rl, - // but until we support SIDEWAYS_LEFT, we'll treat this the same - // as SIDEWAYS_RIGHT and simply fall through. - /* - if (wm.IsVerticalLR()) { - return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT; - } else { - return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT; - } - */ - case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT: return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT; - case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_LEFT: - // Not yet supported, so fall through to the default (error) case. - /* - return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT; - */ default: NS_NOTREACHED("unknown text-orientation"); + return 0; } + + case NS_STYLE_WRITING_MODE_SIDEWAYS_LR: + return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT; + + case NS_STYLE_WRITING_MODE_SIDEWAYS_RL: + return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT; + + default: + NS_NOTREACHED("unknown writing-mode"); + return 0; } - return 0; } /* static */ void @@ -6884,7 +6883,7 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, result.mCORSUsed = (corsmode != imgIRequest::CORS_NONE); } - result.mSize = gfxIntSize(imgWidth, imgHeight); + result.mSize = IntSize(imgWidth, imgHeight); result.mPrincipal = principal.forget(); // no images, including SVG images, can load content from another domain. result.mIsWriteOnly = false; @@ -6914,7 +6913,7 @@ nsLayoutUtils::SurfaceFromElement(HTMLCanvasElement* aElement, isPremultiplied = &result.mIsPremultiplied; } - gfxIntSize size = aElement->GetSize(); + IntSize size = aElement->GetSize(); result.mSourceSurface = aElement->GetSurfaceSnapshot(isPremultiplied); if (!result.mSourceSurface) { diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 31158e5392..b2a2939113 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2062,7 +2062,7 @@ public: DirectDrawInfo mDrawInfo; /* The size of the surface */ - gfxIntSize mSize; + mozilla::gfx::IntSize mSize; /* The principal associated with the element whose surface was returned. If there is a surface, this will never be null. */ nsCOMPtr mPrincipal; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 28fb5ee6b7..b50ba4a472 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -4645,19 +4645,19 @@ PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags, gfxContextAutoSaveRestore save(aThebesContext); - gfxContext::GraphicsOperator oldOperator = aThebesContext->CurrentOperator(); - if (oldOperator == gfxContext::OPERATOR_OVER) { + CompositionOp oldOp = aThebesContext->CurrentOp(); + if (oldOp == CompositionOp::OP_OVER) { // Clip to the destination rectangle before we push the group, // to limit the size of the temporary surface aThebesContext->Clip(); } // we want the window to be composited as a single image using - // whatever operator was set; set OPERATOR_OVER here, which is + // whatever operator was set; set OP_OVER here, which is // either already the case, or overrides the operator in a group. // the original operator will be present when we PopGroup. - // we can avoid using a temporary surface if we're using OPERATOR_OVER - bool needsGroup = oldOperator != gfxContext::OPERATOR_OVER; + // we can avoid using a temporary surface if we're using OP_OVER + bool needsGroup = oldOp != CompositionOp::OP_OVER; if (needsGroup) { aThebesContext->PushGroup(NS_GET_A(aBackgroundColor) == 0xff ? @@ -4665,14 +4665,14 @@ PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags, gfxContentType::COLOR_ALPHA); aThebesContext->Save(); - if (oldOperator != gfxContext::OPERATOR_OVER) { + if (oldOp != CompositionOp::OP_OVER) { // Clip now while we paint to the temporary surface. For // non-source-bounded operators (e.g., SOURCE), we need to do clip // here after we've pushed the group, so that eventually popping // the group and painting it will be able to clear the entire // destination surface. aThebesContext->Clip(); - aThebesContext->SetOperator(gfxContext::OPERATOR_OVER); + aThebesContext->SetOp(CompositionOp::OP_OVER); } } @@ -5312,7 +5312,7 @@ void PresShell::UpdateCanvasBackground() if (!FrameConstructor()->GetRootElementFrame()) { mCanvasBackgroundColor = GetDefaultBackgroundColorToDraw(); } - if (XRE_IsContentProcess()) { + if (XRE_IsContentProcess() && mPresContext->IsRoot()) { if (TabChild* tabChild = TabChild::GetFrom(this)) { tabChild->SetBackgroundColor(mCanvasBackgroundColor); } @@ -5360,7 +5360,7 @@ bool PresShell::AsyncPanZoomEnabled() return widget->AsyncPanZoomEnabled(); } } - return false; + return gfxPlatform::AsyncPanZoomEnabled(); } void PresShell::SetIgnoreViewportScrolling(bool aIgnore) diff --git a/layout/generic/WritingModes.h b/layout/generic/WritingModes.h index 6af3e44c12..410d9ffb2c 100644 --- a/layout/generic/WritingModes.h +++ b/layout/generic/WritingModes.h @@ -204,7 +204,15 @@ public: BidiDir GetBidiDir() const { return BidiDir(mWritingMode & eBidiMask); } /** - * Return true if LTR. (Convenience method) + * Return true if the inline flow direction is against physical direction + * (i.e. right-to-left or bottom-to-top). + * This occurs when writing-mode is sideways-lr OR direction is rtl (but not + * if both of those are true). + */ + bool IsInlineReversed() const { return !!(mWritingMode & eInlineFlowMask); } + + /** + * Return true if bidi direction is LTR. (Convenience method) */ bool IsBidiLTR() const { return eBidiLTR == GetBidiDir(); } @@ -226,9 +234,7 @@ public: /** * True if line-over/line-under are inverted from block-start/block-end. - * This is true when - * - writing-mode is vertical-rl && text-orientation is sideways-left - * - writing-mode is vertical-lr && text-orientation is not sideways-left + * This is true only when writing-mode is vertical-lr. */ bool IsLineInverted() const { return !!(mWritingMode & eLineOrientMask); } @@ -298,7 +304,13 @@ public: { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // vertical-lr }; + // Ignore the SIDEWAYS_MASK bit of the writing-mode value, as this has no + // effect on the side mappings. + aWritingModeValue &= ~NS_STYLE_WRITING_MODE_SIDEWAYS_MASK; + + // What's left of the writing-mode should be in the range 0-3: NS_ASSERTION(aWritingModeValue < 4, "invalid aWritingModeValue value"); + return kLogicalBlockSides[aWritingModeValue][aEdge]; } @@ -309,23 +321,27 @@ public: // bit 1 = the eInlineFlowMask value // bit 2 = the eBlockFlowMask value // bit 3 = the eLineOrientMask value + // Not all of these combinations can actually be specified via CSS: there + // is no horizontal-bt writing-mode, and no text-orientation value that + // produces "inverted" text. (The former 'sideways-left' value, no longer + // in the spec, would have produced this in vertical-rl mode.) static const mozilla::css::Side kLogicalInlineSides[][2] = { - { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // horizontal-tb ltr - { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-rl ltr - { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // horizontal-tb rtl - { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-rl rtl - { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // (horizontal-bt) (inverted) ltr - { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-lr sideways-left rtl - { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // (horizontal-bt) (inverted) rtl - { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-lr sideways-left ltr - { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // horizontal-tb (inverted) rtl - { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-rl sideways-left rtl - { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // horizontal-tb (inverted) ltr - { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-rl sideways-left ltr - { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // (horizontal-bt) ltr - { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-lr ltr - { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // (horizontal-bt) rtl - { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-lr rtl + { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // horizontal-tb ltr + { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-rl ltr + { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // horizontal-tb rtl + { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-rl rtl + { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // (horizontal-bt) (inverted) ltr + { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // sideways-lr rtl + { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // (horizontal-bt) (inverted) rtl + { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // sideways-lr ltr + { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // horizontal-tb (inverted) rtl + { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-rl (inverted) rtl + { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // horizontal-tb (inverted) ltr + { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-rl (inverted) ltr + { NS_SIDE_LEFT, NS_SIDE_RIGHT }, // (horizontal-bt) ltr + { NS_SIDE_TOP, NS_SIDE_BOTTOM }, // vertical-lr ltr + { NS_SIDE_RIGHT, NS_SIDE_LEFT }, // (horizontal-bt) rtl + { NS_SIDE_BOTTOM, NS_SIDE_TOP }, // vertical-lr rtl }; // Inline axis sides depend on all three of writing-mode, text-orientation @@ -420,7 +436,7 @@ public: { auto side = static_cast(aDir); if (IsInline(side)) { - return IsBidiLTR() ? side : GetOppositeSide(side); + return !IsInlineReversed() ? side : GetOppositeSide(side); } return !IsLineInverted() ? side : GetOppositeSide(side); } @@ -454,12 +470,7 @@ public: eLineOrientMask | eOrientationMask; uint8_t textOrientation = aStyleContext->StyleVisibility()->mTextOrientation; -#if 0 // not yet implemented - if (textOrientation == NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_LEFT) { - mWritingMode &= ~eLineOrientMask; - } -#endif - if (textOrientation >= NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT) { + if (textOrientation == NS_STYLE_TEXT_ORIENTATION_SIDEWAYS) { mWritingMode |= eSidewaysMask; } break; @@ -469,17 +480,24 @@ public: { mWritingMode = eOrientationMask; uint8_t textOrientation = aStyleContext->StyleVisibility()->mTextOrientation; -#if 0 // not yet implemented - if (textOrientation == NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_LEFT) { - mWritingMode |= eLineOrientMask; - } -#endif - if (textOrientation >= NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT) { + if (textOrientation == NS_STYLE_TEXT_ORIENTATION_SIDEWAYS) { mWritingMode |= eSidewaysMask; } break; } + case NS_STYLE_WRITING_MODE_SIDEWAYS_LR: + mWritingMode = eBlockFlowMask | + eInlineFlowMask | + eOrientationMask | + eSidewaysMask; + break; + + case NS_STYLE_WRITING_MODE_SIDEWAYS_RL: + mWritingMode = eOrientationMask | + eSidewaysMask; + break; + default: NS_NOTREACHED("unknown writing mode!"); mWritingMode = 0; @@ -487,8 +505,7 @@ public: } if (NS_STYLE_DIRECTION_RTL == styleVisibility->mDirection) { - mWritingMode |= eInlineFlowMask | //XXX needs update when text-orientation added - eBidiMask; + mWritingMode ^= eInlineFlowMask | eBidiMask; } } @@ -570,7 +587,10 @@ private: // Note: We have one excess bit of info; WritingMode can pack into 4 bits. // But since we have space, we're caching interesting things for fast access. - eSidewaysMask = 0x20, // true means text-orientation is sideways-*, + eSidewaysMask = 0x20, // true means text is being rendered vertically + // using rotated glyphs (i.e. writing-mode is + // sideways-*, or writing-mode is vertical-* AND + // text-orientation is sideways), // which means we'll use alphabetic instead of // centered default baseline for vertical text @@ -651,13 +671,13 @@ public: #endif { if (aWritingMode.IsVertical()) { - I() = aWritingMode.IsBidiLTR() ? aPoint.y - : aContainerSize.height - aPoint.y; + I() = aWritingMode.IsInlineReversed() ? aContainerSize.height - aPoint.y + : aPoint.y; B() = aWritingMode.IsVerticalLR() ? aPoint.x : aContainerSize.width - aPoint.x; } else { - I() = aWritingMode.IsBidiLTR() ? aPoint.x - : aContainerSize.width - aPoint.x; + I() = aWritingMode.IsInlineReversed() ? aContainerSize.width - aPoint.x + : aPoint.x; B() = aPoint.y; } } @@ -702,11 +722,11 @@ public: if (aWritingMode.IsVertical()) { return nsPoint(aWritingMode.IsVerticalLR() ? B() : aContainerSize.width - B(), - aWritingMode.IsBidiLTR() - ? I() : aContainerSize.height - I()); + aWritingMode.IsInlineReversed() + ? aContainerSize.height - I() : I()); } else { - return nsPoint(aWritingMode.IsBidiLTR() - ? I() : aContainerSize.width - I(), + return nsPoint(aWritingMode.IsInlineReversed() + ? aContainerSize.width - I() : I(), B()); } } @@ -1062,22 +1082,22 @@ public: mMargin.top = aPhysicalMargin.right; mMargin.bottom = aPhysicalMargin.left; } - if (aWritingMode.IsBidiLTR()) { - mMargin.left = aPhysicalMargin.top; - mMargin.right = aPhysicalMargin.bottom; - } else { + if (aWritingMode.IsInlineReversed()) { mMargin.left = aPhysicalMargin.bottom; mMargin.right = aPhysicalMargin.top; + } else { + mMargin.left = aPhysicalMargin.top; + mMargin.right = aPhysicalMargin.bottom; } } else { mMargin.top = aPhysicalMargin.top; mMargin.bottom = aPhysicalMargin.bottom; - if (aWritingMode.IsBidiLTR()) { - mMargin.left = aPhysicalMargin.left; - mMargin.right = aPhysicalMargin.right; - } else { + if (aWritingMode.IsInlineReversed()) { mMargin.left = aPhysicalMargin.right; mMargin.right = aPhysicalMargin.left; + } else { + mMargin.left = aPhysicalMargin.left; + mMargin.right = aPhysicalMargin.right; } } } @@ -1176,14 +1196,14 @@ public: { CHECK_WRITING_MODE(aWritingMode); return aWritingMode.IsVertical() ? - (aWritingMode.IsBidiLTR() ? IStart() : IEnd()) : BStart(); + (aWritingMode.IsInlineReversed() ? IEnd() : IStart()) : BStart(); } nscoord Bottom(WritingMode aWritingMode) const { CHECK_WRITING_MODE(aWritingMode); return aWritingMode.IsVertical() ? - (aWritingMode.IsBidiLTR() ? IEnd() : IStart()) : BEnd(); + (aWritingMode.IsInlineReversed() ? IStart() : IEnd()) : BEnd(); } nscoord Left(WritingMode aWritingMode) const @@ -1191,7 +1211,7 @@ public: CHECK_WRITING_MODE(aWritingMode); return aWritingMode.IsVertical() ? (aWritingMode.IsVerticalLR() ? BStart() : BEnd()) : - (aWritingMode.IsBidiLTR() ? IStart() : IEnd()); + (aWritingMode.IsInlineReversed() ? IEnd() : IStart()); } nscoord Right(WritingMode aWritingMode) const @@ -1199,7 +1219,7 @@ public: CHECK_WRITING_MODE(aWritingMode); return aWritingMode.IsVertical() ? (aWritingMode.IsVerticalLR() ? BEnd() : BStart()) : - (aWritingMode.IsBidiLTR() ? IEnd() : IStart()); + (aWritingMode.IsInlineReversed() ? IStart() : IEnd()); } nscoord LeftRight(WritingMode aWritingMode) const @@ -1229,15 +1249,15 @@ public: CHECK_WRITING_MODE(aWritingMode); return aWritingMode.IsVertical() ? (aWritingMode.IsVerticalLR() - ? (aWritingMode.IsBidiLTR() - ? nsMargin(IStart(), BEnd(), IEnd(), BStart()) - : nsMargin(IEnd(), BEnd(), IStart(), BStart())) - : (aWritingMode.IsBidiLTR() - ? nsMargin(IStart(), BStart(), IEnd(), BEnd()) - : nsMargin(IEnd(), BStart(), IStart(), BEnd()))) - : (aWritingMode.IsBidiLTR() - ? nsMargin(BStart(), IEnd(), BEnd(), IStart()) - : nsMargin(BStart(), IStart(), BEnd(), IEnd())); + ? (aWritingMode.IsInlineReversed() + ? nsMargin(IEnd(), BEnd(), IStart(), BStart()) + : nsMargin(IStart(), BEnd(), IEnd(), BStart())) + : (aWritingMode.IsInlineReversed() + ? nsMargin(IEnd(), BStart(), IStart(), BEnd()) + : nsMargin(IStart(), BStart(), IEnd(), BEnd()))) + : (aWritingMode.IsInlineReversed() + ? nsMargin(BStart(), IStart(), BEnd(), IEnd()) + : nsMargin(BStart(), IEnd(), BEnd(), IStart())); } /** @@ -1404,13 +1424,13 @@ public: if (aWritingMode.IsVertical()) { mRect.y = aWritingMode.IsVerticalLR() ? aRect.x : aContainerSize.width - aRect.XMost(); - mRect.x = aWritingMode.IsBidiLTR() - ? aRect.y : aContainerSize.height - aRect.YMost(); + mRect.x = aWritingMode.IsInlineReversed() + ? aContainerSize.height - aRect.YMost() : aRect.y; mRect.height = aRect.width; mRect.width = aRect.height; } else { - mRect.x = aWritingMode.IsBidiLTR() - ? aRect.x : aContainerSize.width - aRect.XMost(); + mRect.x = aWritingMode.IsInlineReversed() + ? aContainerSize.width - aRect.XMost() : aRect.x; mRect.y = aRect.y; mRect.width = aRect.width; mRect.height = aRect.height; @@ -1513,8 +1533,8 @@ public: return aWritingMode.IsVerticalLR() ? mRect.Y() : aContainerWidth - mRect.YMost(); } else { - return aWritingMode.IsBidiLTR() ? - mRect.X() : aContainerWidth - mRect.XMost(); + return aWritingMode.IsInlineReversed() ? + aContainerWidth - mRect.XMost() : mRect.X(); } } @@ -1522,8 +1542,8 @@ public: { CHECK_WRITING_MODE(aWritingMode); if (aWritingMode.IsVertical()) { - return aWritingMode.IsBidiLTR() ? mRect.X() - : aContainerHeight - mRect.XMost(); + return aWritingMode.IsInlineReversed() ? aContainerHeight - mRect.XMost() + : mRect.X(); } else { return mRect.Y(); } @@ -1548,8 +1568,8 @@ public: return aWritingMode.IsVerticalLR() ? mRect.YMost() : aContainerWidth - mRect.Y(); } else { - return aWritingMode.IsBidiLTR() ? - mRect.XMost() : aContainerWidth - mRect.X(); + return aWritingMode.IsInlineReversed() ? + aContainerWidth - mRect.X() : mRect.XMost(); } } @@ -1557,8 +1577,8 @@ public: { CHECK_WRITING_MODE(aWritingMode); if (aWritingMode.IsVertical()) { - return aWritingMode.IsBidiLTR() ? mRect.XMost() - : aContainerHeight - mRect.x; + return aWritingMode.IsInlineReversed() ? aContainerHeight - mRect.x + : mRect.XMost(); } else { return mRect.YMost(); } @@ -1672,12 +1692,12 @@ public: if (aWritingMode.IsVertical()) { return nsRect(aWritingMode.IsVerticalLR() ? BStart() : aContainerSize.width - BEnd(), - aWritingMode.IsBidiLTR() - ? IStart() : aContainerSize.height - IEnd(), + aWritingMode.IsInlineReversed() + ? aContainerSize.height - IEnd() : IStart(), BSize(), ISize()); } else { - return nsRect(aWritingMode.IsBidiLTR() - ? IStart() : aContainerSize.width - IEnd(), + return nsRect(aWritingMode.IsInlineReversed() + ? aContainerSize.width - IEnd() : IStart(), BStart(), ISize(), BSize()); } } diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 2e3a7065f3..0473934f82 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1199,7 +1199,7 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext, nscoord x, y; if (isVertical) { - x = pt.x + maxDescent; // XXX will need update for sideways-left + x = pt.x + maxDescent; if (wm.IsBidiLTR()) { y = aRect.y; dir = NSBIDI_LTR; diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 731558e6e2..d438df2ea4 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -5344,6 +5344,7 @@ nsTextFrame::DrawSelectionDecorations(gfxContext* aContext, const gfxFont::Metrics& aFontMetrics, DrawPathCallbacks* aCallbacks, bool aVertical, + gfxFloat aDecorationOffsetDir, uint8_t aDecoration) { gfxPoint pt(aPt); @@ -5450,8 +5451,8 @@ nsTextFrame::DrawSelectionDecorations(gfxContext* aContext, size.height *= relativeSize; PaintDecorationLine(aContext, aDirtyRect, color, nullptr, pt, (aVertical ? (pt.y - aPt.y) : (pt.x - aPt.x)) + aICoordInFrame, - size, aAscent, offset, aDecoration, style, eSelectionDecoration, - aCallbacks, aVertical, descentLimit); + size, aAscent, offset * aDecorationOffsetDir, aDecoration, style, + eSelectionDecoration, aCallbacks, aVertical, descentLimit); } /* static */ @@ -5825,7 +5826,7 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx, mTextRun->GetAdvanceWidth(offset, length, &aProvider); if (NS_GET_A(background) > 0) { gfxRect bgRect; - gfxFloat offs = iOffset - (mTextRun->IsRightToLeft() ? advance : 0); + gfxFloat offs = iOffset - (mTextRun->IsInlineReversed() ? advance : 0); if (vertical) { bgRect = gfxRect(aFramePt.x, aFramePt.y + offs, GetSize().width, advance); @@ -5862,7 +5863,7 @@ nsTextFrame::PaintTextWithSelectionColors(gfxContext* aCtx, GetSelectionTextShadow(this, type, aTextPaintStyle, &shadow); if (shadow) { nscoord startEdge = iOffset; - if (mTextRun->IsRightToLeft()) { + if (mTextRun->IsInlineReversed()) { startEdge -= mTextRun->GetAdvanceWidth(offset, length, &aProvider) + hyphenWidth; } @@ -5952,6 +5953,7 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx, } gfxRect dirtyRect(aDirtyRect.x / app, aDirtyRect.y / app, aDirtyRect.width / app, aDirtyRect.height / app); + gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0; SelectionType type; TextRangeStyle selectedStyle; while (iterator.GetNextSegment(&iOffset, &offset, &length, &hyphenWidth, @@ -5961,17 +5963,18 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx, if (type == aSelectionType) { if (verticalRun) { pt.y = (aFramePt.y + iOffset - - (mTextRun->IsRightToLeft() ? advance : 0)) / app; + (mTextRun->IsInlineReversed() ? advance : 0)) / app; } else { pt.x = (aFramePt.x + iOffset - - (mTextRun->IsRightToLeft() ? advance : 0)) / app; + (mTextRun->IsInlineReversed() ? advance : 0)) / app; } gfxFloat width = Abs(advance) / app; gfxFloat xInFrame = pt.x - (aFramePt.x / app); DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType, aTextPaintStyle, selectedStyle, pt, xInFrame, width, mAscent / app, decorationMetrics, - aCallbacks, verticalRun, kDecoration); + aCallbacks, verticalRun, decorationOffsetDir, + kDecoration); } iterator.UpdateWithAdvance(advance); } @@ -6279,7 +6282,7 @@ nsTextFrame::PaintText(nsRenderingContext* aRenderingContext, nsPoint aPt, provider.InitializeForDisplay(!IsSelected()); gfxContext* ctx = aRenderingContext->ThebesContext(); - const bool rtl = mTextRun->IsRightToLeft(); + const bool reversed = mTextRun->IsInlineReversed(); const bool verticalRun = mTextRun->IsVertical(); WritingMode wm = GetWritingMode(); const nscoord frameWidth = GetSize().width; @@ -6294,10 +6297,11 @@ nsTextFrame::PaintText(nsRenderingContext* aRenderingContext, nsPoint aPt, nsLayoutUtils::GetSnappedBaselineX(this, ctx, aPt.x + frameWidth, -mAscent); } - textBaselinePt.y = rtl ? aPt.y + GetSize().height : aPt.y; + textBaselinePt.y = reversed ? aPt.y + GetSize().height : aPt.y; } else { - textBaselinePt = gfxPoint(rtl ? gfxFloat(aPt.x + frameWidth) : framePt.x, - nsLayoutUtils::GetSnappedBaselineY(this, ctx, aPt.y, mAscent)); + textBaselinePt = + gfxPoint(reversed ? gfxFloat(aPt.x + frameWidth) : framePt.x, + nsLayoutUtils::GetSnappedBaselineY(this, ctx, aPt.y, mAscent)); } uint32_t startOffset = provider.GetStart().GetSkippedOffset(); uint32_t maxLength = ComputeTransformedLength(provider); @@ -6307,9 +6311,9 @@ nsTextFrame::PaintText(nsRenderingContext* aRenderingContext, nsPoint aPt, return; } if (verticalRun) { - textBaselinePt.y += rtl ? -snappedEndEdge : snappedStartEdge; + textBaselinePt.y += reversed ? -snappedEndEdge : snappedStartEdge; } else { - textBaselinePt.x += rtl ? -snappedEndEdge : snappedStartEdge; + textBaselinePt.x += reversed ? -snappedEndEdge : snappedStartEdge; } nsCharClipDisplayItem::ClipEdges clipEdges(aItem, snappedStartEdge, snappedEndEdge); @@ -6465,6 +6469,10 @@ nsTextFrame::DrawTextRunAndDecorations( nscoord inflationMinFontSize = nsLayoutUtils::InflationMinFontSizeFor(this); + // The decoration-line offsets need to be reversed for sideways-lr mode, + // so we will multiply the values from metrics by this factor. + gfxFloat decorationOffsetDir = mTextRun->IsSidewaysLeft() ? -1.0 : 1.0; + // Underlines for (uint32_t i = aDecorations.mUnderlines.Length(); i-- > 0; ) { const LineDecoration& dec = aDecorations.mUnderlines[i]; @@ -6483,7 +6491,8 @@ nsTextFrame::DrawTextRunAndDecorations( PaintDecorationLine(aCtx, dirtyRect, dec.mColor, aDecorationOverrideColor, decPt, 0.0, decSize, ascent, - metrics.underlineOffset, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, + decorationOffsetDir * metrics.underlineOffset, + NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, dec.mStyle, eNormalDecoration, aCallbacks, verticalRun); } // Overlines @@ -6504,7 +6513,8 @@ nsTextFrame::DrawTextRunAndDecorations( PaintDecorationLine(aCtx, dirtyRect, dec.mColor, aDecorationOverrideColor, decPt, 0.0, decSize, ascent, - metrics.maxAscent, NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle, + decorationOffsetDir * metrics.maxAscent, + NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle, eNormalDecoration, aCallbacks, verticalRun); } @@ -6531,7 +6541,8 @@ nsTextFrame::DrawTextRunAndDecorations( PaintDecorationLine(aCtx, dirtyRect, dec.mColor, aDecorationOverrideColor, decPt, 0.0, decSize, ascent, - metrics.strikeoutOffset, NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH, + decorationOffsetDir * metrics.strikeoutOffset, + NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH, dec.mStyle, eNormalDecoration, aCallbacks, verticalRun); } } @@ -6664,9 +6675,9 @@ nsTextFrame::GetCharacterOffsetAtFramePointInternal(nsPoint aPoint, PropertyProvider provider(this, iter, nsTextFrame::eInflated); // Trim leading but not trailing whitespace if possible provider.InitializeForDisplay(false); - gfxFloat width = mTextRun->IsVertical() ? - (mTextRun->IsRightToLeft() ? mRect.height - aPoint.y : aPoint.y) : - (mTextRun->IsRightToLeft() ? mRect.width - aPoint.x : aPoint.x); + gfxFloat width = mTextRun->IsVertical() + ? (mTextRun->IsInlineReversed() ? mRect.height - aPoint.y : aPoint.y) + : (mTextRun->IsInlineReversed() ? mRect.width - aPoint.x : aPoint.x); gfxFloat fitWidth; uint32_t skippedLength = ComputeTransformedLength(provider); @@ -6893,13 +6904,13 @@ nsTextFrame::GetPointFromOffset(int32_t inOffset, nscoord iSize = NSToCoordCeilClamped(advance); if (mTextRun->IsVertical()) { - if (mTextRun->IsRightToLeft()) { + if (mTextRun->IsInlineReversed()) { outPoint->y = mRect.height - iSize; } else { outPoint->y = iSize; } } else { - if (mTextRun->IsRightToLeft()) { + if (mTextRun->IsInlineReversed()) { outPoint->x = mRect.width - iSize; } else { outPoint->x = iSize; diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 0a2ff356b2..13445bd745 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -761,6 +761,7 @@ protected: const gfxFont::Metrics& aFontMetrics, DrawPathCallbacks* aCallbacks, bool aVertical, + gfxFloat aDecorationOffsetDir, uint8_t aDecoration); enum DecorationType { diff --git a/layout/reftests/box-shadow/boxshadow-color-rounding-middle-ref.html b/layout/reftests/box-shadow/boxshadow-color-rounding-middle-ref.html new file mode 100644 index 0000000000..aa2a57e81d --- /dev/null +++ b/layout/reftests/box-shadow/boxshadow-color-rounding-middle-ref.html @@ -0,0 +1,23 @@ + + + +
+
+
+
diff --git a/layout/reftests/box-shadow/boxshadow-color-rounding-middle.html b/layout/reftests/box-shadow/boxshadow-color-rounding-middle.html new file mode 100644 index 0000000000..1693fb9a3d --- /dev/null +++ b/layout/reftests/box-shadow/boxshadow-color-rounding-middle.html @@ -0,0 +1,11 @@ + + + +
diff --git a/layout/reftests/box-shadow/reftest.list b/layout/reftests/box-shadow/reftest.list index 35f6b0c95e..e7f32517ee 100644 --- a/layout/reftests/box-shadow/reftest.list +++ b/layout/reftests/box-shadow/reftest.list @@ -21,6 +21,7 @@ random-if(d2d) == boxshadow-threecorners.html boxshadow-threecorners-ref.html == boxshadow-skiprect.html boxshadow-skiprect-ref.html == boxshadow-opacity.html boxshadow-opacity-ref.html == boxshadow-color-rounding.html boxshadow-color-rounding-ref.html +== boxshadow-color-rounding-middle.html boxshadow-color-rounding-middle-ref.html == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref.html == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref2.html diff --git a/layout/reftests/bugs/1155828-1-ref.html b/layout/reftests/bugs/1155828-1-ref.html new file mode 100644 index 0000000000..66bfea56c4 --- /dev/null +++ b/layout/reftests/bugs/1155828-1-ref.html @@ -0,0 +1,25 @@ + + + + + + + +
+ + diff --git a/layout/reftests/bugs/1155828-1.html b/layout/reftests/bugs/1155828-1.html new file mode 100644 index 0000000000..8eaefd2b2d --- /dev/null +++ b/layout/reftests/bugs/1155828-1.html @@ -0,0 +1,26 @@ + + + +Scrolling shouldn't cause gaps in the shadow + + +
+ + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index c9e623e1fd..5e57d2d18d 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1926,6 +1926,7 @@ skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul == 1151145-1.html 1151145-1-ref.html == 1151306-1.html 1151306-1-ref.html == 1153845-1.html 1153845-1-ref.html +== 1155828-1.html 1155828-1-ref.html == 1156129-1.html 1156129-1-ref.html == 1169331-1.html 1169331-1-ref.html fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 1174332-1.html 1174332-1-ref.html diff --git a/layout/reftests/css-gradients/linear-premul-ref.html b/layout/reftests/css-gradients/linear-premul-ref.html new file mode 100644 index 0000000000..bf0b12c33f --- /dev/null +++ b/layout/reftests/css-gradients/linear-premul-ref.html @@ -0,0 +1 @@ +

diff --git a/layout/reftests/css-gradients/linear-premul.html b/layout/reftests/css-gradients/linear-premul.html new file mode 100644 index 0000000000..20c7c276a2 --- /dev/null +++ b/layout/reftests/css-gradients/linear-premul.html @@ -0,0 +1 @@ +

diff --git a/layout/reftests/css-gradients/radial-premul-ref.html b/layout/reftests/css-gradients/radial-premul-ref.html new file mode 100644 index 0000000000..1424f4373c --- /dev/null +++ b/layout/reftests/css-gradients/radial-premul-ref.html @@ -0,0 +1 @@ +

diff --git a/layout/reftests/css-gradients/radial-premul.html b/layout/reftests/css-gradients/radial-premul.html new file mode 100644 index 0000000000..33b89c72bc --- /dev/null +++ b/layout/reftests/css-gradients/radial-premul.html @@ -0,0 +1 @@ +

diff --git a/layout/reftests/css-gradients/reftest.list b/layout/reftests/css-gradients/reftest.list index 8dabf336e4..d4ea654436 100644 --- a/layout/reftests/css-gradients/reftest.list +++ b/layout/reftests/css-gradients/reftest.list @@ -16,6 +16,7 @@ fuzzy-if(!contentSameGfxBackendAsCanvas,4,92400) fuzzy-if(azureSkiaGL,3,143400) == linear-diagonal-4a.html linear-diagonal-4-ref.html == linear-diagonal-4b.html linear-diagonal-4-ref.html == linear-diagonal-4c.html linear-diagonal-4-ref.html +== linear-premul.html linear-premul-ref.html # these tests uses a similar gradient over different bounds. It's perfectly # reasonable to expect implementations to give slightly different results @@ -91,6 +92,7 @@ fuzzy-if(Android,4,248) == radial-zero-length-1f.html radial-zero-length-1-ref.h fuzzy-if(Android,4,248) == radial-zero-length-1h.html radial-zero-length-1-ref.html == radial-zero-length-1i.html radial-zero-length-1-ref.html fuzzy-if(Android,4,248) == radial-zero-length-1j.html radial-zero-length-1-ref.html +== radial-premul.html radial-premul-ref.html == repeated-final-stop-1.html repeated-final-stop-1-ref.html == repeating-linear-1a.html repeating-linear-1-ref.html == repeating-linear-1b.html repeating-linear-1-ref.html diff --git a/layout/reftests/floats/float-in-rtl-slr-1-ref.html b/layout/reftests/floats/float-in-rtl-slr-1-ref.html new file mode 100644 index 0000000000..f5af2bc196 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-1-ref.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+
This text should appear BELOW the red and green blocks.
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-1a.html b/layout/reftests/floats/float-in-rtl-slr-1a.html new file mode 100644 index 0000000000..04e05bf2c4 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-1a.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-1b.html b/layout/reftests/floats/float-in-rtl-slr-1b.html new file mode 100644 index 0000000000..0d67449198 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-1b.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-1c.html b/layout/reftests/floats/float-in-rtl-slr-1c.html new file mode 100644 index 0000000000..41e3be793d --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-1c.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-1d.html b/layout/reftests/floats/float-in-rtl-slr-1d.html new file mode 100644 index 0000000000..8813c2a63e --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-1d.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-2-ref.html b/layout/reftests/floats/float-in-rtl-slr-2-ref.html new file mode 100644 index 0000000000..b3cd61f6c7 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-2-ref.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+
This text should appear ABOVE the green and red blocks.
+
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-2a.html b/layout/reftests/floats/float-in-rtl-slr-2a.html new file mode 100644 index 0000000000..31c4fe178f --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-2a.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-2b.html b/layout/reftests/floats/float-in-rtl-slr-2b.html new file mode 100644 index 0000000000..dd25587665 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-2b.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-2c.html b/layout/reftests/floats/float-in-rtl-slr-2c.html new file mode 100644 index 0000000000..4ee217ce1d --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-2c.html @@ -0,0 +1,21 @@ + + + + + + +
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-2d.html b/layout/reftests/floats/float-in-rtl-slr-2d.html new file mode 100644 index 0000000000..b3b9623eec --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-2d.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-3-ref.html b/layout/reftests/floats/float-in-rtl-slr-3-ref.html new file mode 100644 index 0000000000..4c99aa543c --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-3-ref.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+
This text should appear ABOVE the green and red blocks.
+
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-3a.html b/layout/reftests/floats/float-in-rtl-slr-3a.html new file mode 100644 index 0000000000..641a6aa79a --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-3a.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-3b.html b/layout/reftests/floats/float-in-rtl-slr-3b.html new file mode 100644 index 0000000000..613ffac32e --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-3b.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-3c.html b/layout/reftests/floats/float-in-rtl-slr-3c.html new file mode 100644 index 0000000000..5c4669bb41 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-3c.html @@ -0,0 +1,23 @@ + + + + + + +
+
+
+
+
+
+
+
+This text should appear ABOVE the green and red blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-3d.html b/layout/reftests/floats/float-in-rtl-slr-3d.html new file mode 100644 index 0000000000..ef7b1886fd --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-3d.html @@ -0,0 +1,25 @@ + + + + + + +
+
+
+
+
+
+
+
+
+
+ This text should appear ABOVE the green and red blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-4-ref.html b/layout/reftests/floats/float-in-rtl-slr-4-ref.html new file mode 100644 index 0000000000..1696cdd4d8 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-4-ref.html @@ -0,0 +1,24 @@ + + + + + + +
+
+
+
+
+
+
+
+
This text should appear BELOW the red and green blocks.
+
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-4a.html b/layout/reftests/floats/float-in-rtl-slr-4a.html new file mode 100644 index 0000000000..f94ed50980 --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-4a.html @@ -0,0 +1,24 @@ + + + + + + +
+
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-4b.html b/layout/reftests/floats/float-in-rtl-slr-4b.html new file mode 100644 index 0000000000..7520ea6ddb --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-4b.html @@ -0,0 +1,24 @@ + + + + + + +
+
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-4c.html b/layout/reftests/floats/float-in-rtl-slr-4c.html new file mode 100644 index 0000000000..000938f91c --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-4c.html @@ -0,0 +1,24 @@ + + + + + + +
+
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+
+ + diff --git a/layout/reftests/floats/float-in-rtl-slr-4d.html b/layout/reftests/floats/float-in-rtl-slr-4d.html new file mode 100644 index 0000000000..6fb5e8509b --- /dev/null +++ b/layout/reftests/floats/float-in-rtl-slr-4d.html @@ -0,0 +1,26 @@ + + + + + + +
+
+
+
+
+
+
+
+
+
+This text should appear BELOW the red and green blocks. +
+
+ + diff --git a/layout/reftests/floats/reftest.list b/layout/reftests/floats/reftest.list index b6269f2e2e..89a6f10526 100644 --- a/layout/reftests/floats/reftest.list +++ b/layout/reftests/floats/reftest.list @@ -89,3 +89,20 @@ fuzzy-if(OSX==1010,26,7) fuzzy-if(Android,16,2) == orthogonal-floats-1a.html ort fuzzy-if(OSX==1010,26,7) == orthogonal-floats-1b.html orthogonal-floats-1-ref.html fuzzy-if(OSX==1010,103,802) fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1c.html orthogonal-floats-1-ref.html fuzzy-if(OSX==1010,103,802) fuzzy-if(winWidget,116,700) HTTP(..) == orthogonal-floats-1d.html orthogonal-floats-1-ref.html + +== float-in-rtl-slr-1a.html float-in-rtl-slr-1-ref.html +== float-in-rtl-slr-1b.html float-in-rtl-slr-1-ref.html +== float-in-rtl-slr-1c.html float-in-rtl-slr-1-ref.html +== float-in-rtl-slr-1d.html float-in-rtl-slr-1-ref.html +== float-in-rtl-slr-2a.html float-in-rtl-slr-2-ref.html +== float-in-rtl-slr-2b.html float-in-rtl-slr-2-ref.html +== float-in-rtl-slr-2c.html float-in-rtl-slr-2-ref.html +== float-in-rtl-slr-2d.html float-in-rtl-slr-2-ref.html +== float-in-rtl-slr-3a.html float-in-rtl-slr-3-ref.html +== float-in-rtl-slr-3b.html float-in-rtl-slr-3-ref.html +== float-in-rtl-slr-3c.html float-in-rtl-slr-3-ref.html +== float-in-rtl-slr-3d.html float-in-rtl-slr-3-ref.html +== float-in-rtl-slr-4a.html float-in-rtl-slr-4-ref.html +== float-in-rtl-slr-4b.html float-in-rtl-slr-4-ref.html +== float-in-rtl-slr-4c.html float-in-rtl-slr-4-ref.html +== float-in-rtl-slr-4d.html float-in-rtl-slr-4-ref.html diff --git a/layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge-ref.html b/layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge-ref.html new file mode 100644 index 0000000000..66db649e9b --- /dev/null +++ b/layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge-ref.html @@ -0,0 +1,10 @@ + + + + + + +
diff --git a/layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge.html b/layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge.html new file mode 100644 index 0000000000..b011bd22f7 --- /dev/null +++ b/layout/reftests/table-bordercollapse/border-style-inset-becomes-ridge.html @@ -0,0 +1,12 @@ + + + + + + +
diff --git a/layout/reftests/table-bordercollapse/border-style-outset-becomes-groove-ref.html b/layout/reftests/table-bordercollapse/border-style-outset-becomes-groove-ref.html new file mode 100644 index 0000000000..ddb0f71c89 --- /dev/null +++ b/layout/reftests/table-bordercollapse/border-style-outset-becomes-groove-ref.html @@ -0,0 +1,10 @@ + + + + + + +
diff --git a/layout/reftests/table-bordercollapse/border-style-outset-becomes-groove.html b/layout/reftests/table-bordercollapse/border-style-outset-becomes-groove.html new file mode 100644 index 0000000000..a7245459ec --- /dev/null +++ b/layout/reftests/table-bordercollapse/border-style-outset-becomes-groove.html @@ -0,0 +1,12 @@ + + + + + + +
diff --git a/layout/reftests/table-bordercollapse/reftest.list b/layout/reftests/table-bordercollapse/reftest.list index 0a4fba0a48..e1910d9307 100644 --- a/layout/reftests/table-bordercollapse/reftest.list +++ b/layout/reftests/table-bordercollapse/reftest.list @@ -95,4 +95,12 @@ == bordercolor-4.html bordercolor-4-ref.html == empty-toprow.html empty-toprow-ref.html == double_borders.html double_borders_ref.html -fails == border-collapse-rtl.html border-collapse-rtl-ref.html # see bug 1157569 +== border-collapse-rtl.html border-collapse-rtl-ref.html +# Fuzzy because for some reason the corner beveling is antialiased differently. +# So get 40 pixels of fuzz, 20 at each beveled corner (because the border width +# is 20px). +fuzzy(255,40) == border-style-outset-becomes-groove.html border-style-outset-becomes-groove-ref.html +# Fuzzy because for some reason the corner beveling is antialiased differently. +# So get 40 pixels of fuzz, 20 at each beveled corner (because the border width +# is 20px). +fuzzy(255,40) == border-style-inset-becomes-ridge.html border-style-inset-becomes-ridge-ref.html diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-1-ref.html b/layout/reftests/writing-mode/1193519-sideways-lr-1-ref.html new file mode 100644 index 0000000000..e3c96714c7 --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-1-ref.html @@ -0,0 +1,24 @@ + + + + + + + + + +

All four columns should look the same: +

+
+
+
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-1.html b/layout/reftests/writing-mode/1193519-sideways-lr-1.html new file mode 100644 index 0000000000..66df9d85f7 --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-1.html @@ -0,0 +1,28 @@ + + + + + + + + + +

All four columns should look the same: +

+
+
+
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-2-ref.html b/layout/reftests/writing-mode/1193519-sideways-lr-2-ref.html new file mode 100644 index 0000000000..681cb2890a --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-2-ref.html @@ -0,0 +1,24 @@ + + + + + + + + + +

All four columns should look the same: +

+
+
+
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-2.html b/layout/reftests/writing-mode/1193519-sideways-lr-2.html new file mode 100644 index 0000000000..5a6e7ea0ea --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-2.html @@ -0,0 +1,28 @@ + + + + + + + + + +

All four columns should look the same: +

+
+
+
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-3-ref.html b/layout/reftests/writing-mode/1193519-sideways-lr-3-ref.html new file mode 100644 index 0000000000..e9ac42e259 --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-3-ref.html @@ -0,0 +1,21 @@ + + + + + + + + + +
one two three four + five six seven
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-3.html b/layout/reftests/writing-mode/1193519-sideways-lr-3.html new file mode 100644 index 0000000000..09287844eb --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-3.html @@ -0,0 +1,21 @@ + + + + + + + + + +
one two three four + five six seven
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-4-ref.html b/layout/reftests/writing-mode/1193519-sideways-lr-4-ref.html new file mode 100644 index 0000000000..368d38834f --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-4-ref.html @@ -0,0 +1,27 @@ + + + + + + + + + +
"One two + three four five + six seven."
+ +
"One two + three four five + six seven."
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-4.html b/layout/reftests/writing-mode/1193519-sideways-lr-4.html new file mode 100644 index 0000000000..f01956e3f6 --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-4.html @@ -0,0 +1,27 @@ + + + + + + + + + +
"One two + three four five + six seven."
+ +
"One two + three four five + six seven."
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-decoration-1-ref.html b/layout/reftests/writing-mode/1193519-sideways-lr-decoration-1-ref.html new file mode 100644 index 0000000000..24cac4884b --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-decoration-1-ref.html @@ -0,0 +1,10 @@ + +
+ under + over + through +
diff --git a/layout/reftests/writing-mode/1193519-sideways-lr-decoration-1.html b/layout/reftests/writing-mode/1193519-sideways-lr-decoration-1.html new file mode 100644 index 0000000000..a9cc3dd73b --- /dev/null +++ b/layout/reftests/writing-mode/1193519-sideways-lr-decoration-1.html @@ -0,0 +1,10 @@ + +
+ under + over + through +
diff --git a/layout/reftests/writing-mode/1205787-legacy-svg-values-1-ref.html b/layout/reftests/writing-mode/1205787-legacy-svg-values-1-ref.html new file mode 100644 index 0000000000..251f574151 --- /dev/null +++ b/layout/reftests/writing-mode/1205787-legacy-svg-values-1-ref.html @@ -0,0 +1,25 @@ + + + +
+Hello +horizontal +world +
+ +
One two three
+ + + diff --git a/layout/reftests/writing-mode/1205787-legacy-svg-values-1.html b/layout/reftests/writing-mode/1205787-legacy-svg-values-1.html new file mode 100644 index 0000000000..2e73e68c41 --- /dev/null +++ b/layout/reftests/writing-mode/1205787-legacy-svg-values-1.html @@ -0,0 +1,25 @@ + + + +
+Hello +horizontal +world +
+ +
One two three
+ + + diff --git a/layout/reftests/writing-mode/reftest.list b/layout/reftests/writing-mode/reftest.list index cea38f9a91..7e362faec3 100644 --- a/layout/reftests/writing-mode/reftest.list +++ b/layout/reftests/writing-mode/reftest.list @@ -152,7 +152,16 @@ test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLin == 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html == 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics-ref.html == 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize-ref.html + +# tests involving sideways-lr mode +== 1193519-sideways-lr-1.html 1193519-sideways-lr-1-ref.html +== 1193519-sideways-lr-2.html 1193519-sideways-lr-2-ref.html +== 1193519-sideways-lr-3.html 1193519-sideways-lr-3-ref.html +== 1193519-sideways-lr-4.html 1193519-sideways-lr-4-ref.html +fuzzy-if(gtkWidget||B2G,255,6) fuzzy-if(cocoaWidget,65,69) == 1193519-sideways-lr-decoration-1.html 1193519-sideways-lr-decoration-1-ref.html + == 1196887-1-computed-display-inline-block.html 1196887-1-computed-display-inline-block-ref.html +== 1205787-legacy-svg-values-1.html 1205787-legacy-svg-values-1-ref.html # Suite of tests from Gérard Talbot in bug 1079151 include abspos/reftest.list diff --git a/layout/reftests/writing-mode/tables/reftest.list b/layout/reftests/writing-mode/tables/reftest.list index 868f9e7d47..e1a1b2e3cc 100644 --- a/layout/reftests/writing-mode/tables/reftest.list +++ b/layout/reftests/writing-mode/tables/reftest.list @@ -84,3 +84,10 @@ fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1b.html border-collapse-b fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1c.html border-collapse-bevels-1-ref.html fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1d.html border-collapse-bevels-1-ref.html fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1e.html border-collapse-bevels-1-ref.html + +== vertical-rl-row-progression-1a.html vertical-rl-row-progression-1-ref.html +== vertical-rl-row-progression-1b.html vertical-rl-row-progression-1-ref.html +== sideways-lr-row-progression-1a.html sideways-lr-row-progression-1-ref.html +== sideways-lr-row-progression-1b.html sideways-lr-row-progression-1-ref.html +== sideways-rl-row-progression-1a.html sideways-rl-row-progression-1-ref.html +== sideways-rl-row-progression-1b.html sideways-rl-row-progression-1-ref.html diff --git a/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1-ref.html b/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1-ref.html new file mode 100644 index 0000000000..930ce16dd9 --- /dev/null +++ b/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1-ref.html @@ -0,0 +1,51 @@ + +CSS Reference: sideways-lr Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + +
+ + + + +
+ +
+ + + +
+ + +
diff --git a/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1a.html b/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1a.html new file mode 100644 index 0000000000..68d15a91c9 --- /dev/null +++ b/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1a.html @@ -0,0 +1,68 @@ + +CSS Test: sideways-lr Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1b.html b/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1b.html new file mode 100644 index 0000000000..70172efb94 --- /dev/null +++ b/layout/reftests/writing-mode/tables/sideways-lr-row-progression-1b.html @@ -0,0 +1,69 @@ + +CSS Test: sideways-lr Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1-ref.html b/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1-ref.html new file mode 100644 index 0000000000..64f29765e7 --- /dev/null +++ b/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1-ref.html @@ -0,0 +1,54 @@ + +CSS Reference: sideways-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + +
+ + + +
+ + + + +
+ + +
+ +
diff --git a/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1a.html b/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1a.html new file mode 100644 index 0000000000..c2096757f7 --- /dev/null +++ b/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1a.html @@ -0,0 +1,68 @@ + +CSS Test: sideways-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1b.html b/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1b.html new file mode 100644 index 0000000000..5ef6875511 --- /dev/null +++ b/layout/reftests/writing-mode/tables/sideways-rl-row-progression-1b.html @@ -0,0 +1,68 @@ + +CSS Test: sideways-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html new file mode 100644 index 0000000000..60afb00d9b --- /dev/null +++ b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1-ref.html @@ -0,0 +1,50 @@ + +CSS Reference: vertical-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + +
+ + + +
+ + + + +
+ + +
+ +
diff --git a/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html new file mode 100644 index 0000000000..6b0929495f --- /dev/null +++ b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1a.html @@ -0,0 +1,57 @@ + +CSS Test: vertical-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html new file mode 100644 index 0000000000..69f4f52e6c --- /dev/null +++ b/layout/reftests/writing-mode/tables/vertical-rl-row-progression-1b.html @@ -0,0 +1,57 @@ + +CSS Test: vertical-rl Table Row/Rowgroup/Cell Ordering + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ + +
+ +
+
+ +
diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index e08a279650..cc4921eca2 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -345,6 +345,8 @@ CSS_KEY(local, local) CSS_KEY(logical, logical) CSS_KEY(looped, looped) CSS_KEY(lowercase, lowercase) +CSS_KEY(lr, lr) +CSS_KEY(lr-tb, lr_tb) CSS_KEY(ltr, ltr) CSS_KEY(luminance, luminance) CSS_KEY(luminosity, luminosity) @@ -437,6 +439,8 @@ CSS_KEY(repeat-y, repeat_y) CSS_KEY(reverse, reverse) CSS_KEY(ridge, ridge) CSS_KEY(right, right) +CSS_KEY(rl, rl) +CSS_KEY(rl-tb, rl_tb) CSS_KEY(rotate, rotate) CSS_KEY(rotate3d, rotate3d) CSS_KEY(rotatex, rotatex) @@ -483,9 +487,10 @@ CSS_KEY(separate, separate) CSS_KEY(sepia, sepia) CSS_KEY(serif, serif) CSS_KEY(show, show) -/* CSS_KEY(sideways, sideways) */ -/* CSS_KEY(sideways-left, sideways_left) */ -CSS_KEY(sideways-right, sideways_right) +CSS_KEY(sideways, sideways) +CSS_KEY(sideways-lr, sideways_lr) +CSS_KEY(sideways-right, sideways_right) /* alias for 'sideways' */ +CSS_KEY(sideways-rl, sideways_rl) CSS_KEY(simp-chinese-formal, simp_chinese_formal) CSS_KEY(simp-chinese-informal, simp_chinese_informal) CSS_KEY(simplified, simplified) @@ -540,6 +545,8 @@ CSS_KEY(table-row, table_row) CSS_KEY(table-row-group, table_row_group) CSS_KEY(tabular-nums, tabular_nums) CSS_KEY(tailed, tailed) +CSS_KEY(tb, tb) +CSS_KEY(tb-rl, tb_rl) CSS_KEY(text, text) CSS_KEY(text-bottom, text_bottom) CSS_KEY(text-top, text_top) diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 19429221f5..6241f65986 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1826,9 +1826,8 @@ const KTableValue nsCSSProps::kTextDecorationStyleKTable[] = { const KTableValue nsCSSProps::kTextOrientationKTable[] = { eCSSKeyword_mixed, NS_STYLE_TEXT_ORIENTATION_MIXED, eCSSKeyword_upright, NS_STYLE_TEXT_ORIENTATION_UPRIGHT, - eCSSKeyword_sideways_right, NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT, - /* eCSSKeyword_sideways_left, NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_LEFT, */ - /* eCSSKeyword_sideways, NS_STYLE_TEXT_ORIENTATION_SIDEWAYS, */ + eCSSKeyword_sideways, NS_STYLE_TEXT_ORIENTATION_SIDEWAYS, + eCSSKeyword_sideways_right, NS_STYLE_TEXT_ORIENTATION_SIDEWAYS, eCSSKeyword_UNKNOWN, -1 }; @@ -1996,6 +1995,14 @@ const KTableValue nsCSSProps::kWritingModeKTable[] = { eCSSKeyword_horizontal_tb, NS_STYLE_WRITING_MODE_HORIZONTAL_TB, eCSSKeyword_vertical_lr, NS_STYLE_WRITING_MODE_VERTICAL_LR, eCSSKeyword_vertical_rl, NS_STYLE_WRITING_MODE_VERTICAL_RL, + eCSSKeyword_sideways_lr, NS_STYLE_WRITING_MODE_SIDEWAYS_LR, + eCSSKeyword_sideways_rl, NS_STYLE_WRITING_MODE_SIDEWAYS_RL, + eCSSKeyword_lr, NS_STYLE_WRITING_MODE_HORIZONTAL_TB, + eCSSKeyword_lr_tb, NS_STYLE_WRITING_MODE_HORIZONTAL_TB, + eCSSKeyword_rl, NS_STYLE_WRITING_MODE_HORIZONTAL_TB, + eCSSKeyword_rl_tb, NS_STYLE_WRITING_MODE_HORIZONTAL_TB, + eCSSKeyword_tb, NS_STYLE_WRITING_MODE_VERTICAL_RL, + eCSSKeyword_tb_rl, NS_STYLE_WRITING_MODE_VERTICAL_RL, eCSSKeyword_UNKNOWN, -1 }; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index f264493e73..b4e3a805b9 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7649,6 +7649,8 @@ nsRuleNode::ComputePositionData(void* aStartStruct, break; case NS_STYLE_WRITING_MODE_VERTICAL_RL: case NS_STYLE_WRITING_MODE_VERTICAL_LR: + case NS_STYLE_WRITING_MODE_SIDEWAYS_RL: + case NS_STYLE_WRITING_MODE_SIDEWAYS_LR: vertical = true; break; } diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h index 80be81f420..bb1ab6a7e5 100644 --- a/layout/style/nsStyleConsts.h +++ b/layout/style/nsStyleConsts.h @@ -402,12 +402,25 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { #define NS_STYLE_DIRECTION_RTL 1 // See nsStyleVisibility -// WritingModes.h depends on the particular values used here +// NOTE: WritingModes.h depends on the particular values used here. #define NS_STYLE_WRITING_MODE_HORIZONTAL_TB 0 #define NS_STYLE_WRITING_MODE_VERTICAL_RL 1 // #define NS_STYLE_WRITING_MODE_HORIZONTAL_BT 2 // hypothetical #define NS_STYLE_WRITING_MODE_VERTICAL_LR 3 +// Single-bit flag, used in combination with VERTICAL_LR and _RL to specify +// the corresponding SIDEWAYS_* modes. +// (To avoid ambiguity, this bit must be high enough such that no other +// values here accidentally use it in their binary representation.) +#define NS_STYLE_WRITING_MODE_SIDEWAYS_MASK 4 + +#define NS_STYLE_WRITING_MODE_SIDEWAYS_RL \ + (NS_STYLE_WRITING_MODE_VERTICAL_RL | \ + NS_STYLE_WRITING_MODE_SIDEWAYS_MASK) +#define NS_STYLE_WRITING_MODE_SIDEWAYS_LR \ + (NS_STYLE_WRITING_MODE_VERTICAL_LR | \ + NS_STYLE_WRITING_MODE_SIDEWAYS_MASK) + // See nsStyleDisplay #define NS_STYLE_DISPLAY_NONE 0 #define NS_STYLE_DISPLAY_BLOCK 1 @@ -929,9 +942,7 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) { // See nsStyleText #define NS_STYLE_TEXT_ORIENTATION_MIXED 0 #define NS_STYLE_TEXT_ORIENTATION_UPRIGHT 1 -#define NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT 2 -#define NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_LEFT 3 /* placeholder, not yet parsed */ -#define NS_STYLE_TEXT_ORIENTATION_SIDEWAYS 4 /* placeholder, not yet parsed */ +#define NS_STYLE_TEXT_ORIENTATION_SIDEWAYS 2 // See nsStyleText #define NS_STYLE_TEXT_COMBINE_UPRIGHT_NONE 0 diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index b7064f3f91..d7817f0679 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4577,12 +4577,24 @@ function logical_axis_prop_get_computed(cs, property) var orientation = writingMode.substring(0, writingMode.indexOf("-")); var mappings = { - "block-size": { horizontal: "height", vertical: "width" }, - "inline-size": { horizontal: "width", vertical: "height" }, - "max-block-size": { horizontal: "max-height", vertical: "max-width" }, - "max-inline-size": { horizontal: "max-width", vertical: "max-height" }, - "min-block-size": { horizontal: "min-height", vertical: "min-width" }, - "min-inline-size": { horizontal: "min-width", vertical: "min-height" }, + "block-size": { horizontal: "height", + vertical: "width", + sideways: "width" }, + "inline-size": { horizontal: "width", + vertical: "height", + sideways: "height" }, + "max-block-size": { horizontal: "max-height", + vertical: "max-width", + sideways: "max-width" }, + "max-inline-size": { horizontal: "max-width", + vertical: "max-height", + sideways: "max-height" }, + "min-block-size": { horizontal: "min-height", + vertical: "min-width", + sideways: "min-width" }, + "min-inline-size": { horizontal: "min-width", + vertical: "min-height", + sideways: "min-height" }, }; if (!mappings[property]) { @@ -4601,51 +4613,42 @@ function logical_box_prop_get_computed(cs, property) { // http://dev.w3.org/csswg/css-writing-modes-3/#logical-to-physical - // Use defaults for these two properties in case the vertical text - // pref (which they live behind) is turned off. + // Use default for writing-mode in case the vertical text + // pref (which it lives behind) is turned off. var writingMode = cs.getPropertyValue("writing-mode") || "horizontal-tb"; - var textOrientation = cs.getPropertyValue("text-orientation") || "mixed"; var direction = cs.getPropertyValue("direction"); - // We only need to distinguish between text-orientation values of - // sideways-left and {mixed,upright,sideways-right} (which we will - // call "others"). - - if (textOrientation == "sideways") { - // text-orientation does not contribute to the logical to physical - // mapping when writing-mode is horizontal-tb, so it doesn't matter - // that we convert it to sideways-left in that case. - textOrientation = writingMode == "vertical-rl" ? "others" : "sideways-left"; - } else if (textOrientation != "sideways-left") { - textOrientation = "others"; - } - // keys in blockMappings are writing-mode values var blockMappings = { "horizontal-tb": { "start": "top", "end": "bottom" }, "vertical-rl": { "start": "right", "end": "left" }, "vertical-lr": { "start": "left", "end": "right" }, + "sideways-rl": { "start": "right", "end": "left" }, + "sideways-lr": { "start": "left", "end": "right" }, }; // keys in inlineMappings are regular expressions that match against - // a {writing-mode,text-orientation,direction} triple as a space- - // separated string + // a {writing-mode,direction} pair as a space-separated string var inlineMappings = { - "horizontal-tb \\S+ ltr": { "start": "left", "end": "right" }, - "horizontal-tb \\S+ rtl": { "start": "right", "end": "left" }, - "vertical-.. sideways-left ltr": { "start": "bottom", "end": "top" }, - "vertical-.. sideways-left rtl": { "start": "top", "end": "bottom" }, - "vertical-.. others ltr": { "start": "top", "end": "bottom" }, - "vertical-.. others rtl": { "start": "bottom", "end": "top" }, + "horizontal-tb ltr": { "start": "left", "end": "right" }, + "horizontal-tb rtl": { "start": "right", "end": "left" }, + "vertical-.. ltr": { "start": "bottom", "end": "top" }, + "vertical-.. rtl": { "start": "top", "end": "bottom" }, + "vertical-.. ltr": { "start": "top", "end": "bottom" }, + "vertical-.. rtl": { "start": "bottom", "end": "top" }, + "sideways-lr ltr": { "start": "bottom", "end": "top" }, + "sideways-lr rtl": { "start": "top", "end": "bottom" }, + "sideways-rl ltr": { "start": "top", "end": "bottom" }, + "sideways-rl rtl": { "start": "bottom", "end": "top" }, }; var blockMapping = blockMappings[writingMode]; var inlineMapping; // test each regular expression in inlineMappings against the - // {writing-mode,text-orientation,direction} triple - var key = `${writingMode} ${textOrientation} ${direction}`; + // {writing-mode,direction} pair + var key = `${writingMode} ${direction}`; for (var k in inlineMappings) { if (new RegExp(k).test(key)) { inlineMapping = inlineMappings[k]; @@ -4727,8 +4730,8 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { domProp: "writingMode", inherited: true, type: CSS_TYPE_LONGHAND, - initial_values: [ "horizontal-tb" ], - other_values: [ "vertical-lr", "vertical-rl" ], + initial_values: [ "horizontal-tb", "lr", "lr-tb", "rl", "rl-tb" ], + other_values: [ "vertical-lr", "vertical-rl", "sideways-rl", "sideways-lr", "tb", "tb-rl" ], invalid_values: [ "10px", "30%", "justify", "auto", "1em" ] }, "text-orientation": { @@ -4736,8 +4739,8 @@ if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) { inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "mixed" ], - other_values: [ "upright", "sideways-right" ], - invalid_values: [ "none", "3em", "sideways", "sideways-left" ] /* sideways, sideways-left not yet supported */ + other_values: [ "upright", "sideways", "sideways-right" ], /* sideways-right alias for backward compatibility */ + invalid_values: [ "none", "3em", "sideways-left" ] /* sideways-left removed from CSS Writing Modes */ }, "border-block-end": { domProp: "borderBlockEnd", diff --git a/layout/style/test/test_logical_properties.html b/layout/style/test/test_logical_properties.html index 842b638021..47f8132284 100644 --- a/layout/style/test/test_logical_properties.html +++ b/layout/style/test/test_logical_properties.html @@ -38,60 +38,42 @@ var gValues = { "border-style": ["solid", "dashed", "dotted", "double", "groove"], }; -// six unique overall writing modes +// Six unique overall writing modes for property-mapping purposes. +// Note that text-orientation does not affect these mappings, now that +// the proposed sideways-left value no longer exists (superseded in CSS +// Writing Modes by writing-mode: sideways-lr). var gWritingModes = [ { style: [ - "writing-mode: horizontal-tb; text-orientation: mixed; direction: ltr; ", - "writing-mode: horizontal-tb; text-orientation: upright; direction: ltr; ", - "writing-mode: horizontal-tb; text-orientation: sideways-right; direction: ltr; ", - // XXX See the todo()s below. - // "writing-mode: horizontal-tb; text-orientation: sideways-left; direction: ltr; ", - // "writing-mode: horizontal-tb; text-orientation: sideways; direction: ltr; ", + "writing-mode: horizontal-tb; direction: ltr; ", ], blockStart: "top", blockEnd: "bottom", inlineStart: "left", inlineEnd: "right", block: "vertical", inline: "horizontal" }, { style: [ - "writing-mode: horizontal-tb; text-orientation: mixed; direction: rtl; ", - "writing-mode: horizontal-tb; text-orientation: upright; direction: rtl; ", - "writing-mode: horizontal-tb; text-orientation: sideways-right; direction: rtl; ", - // "writing-mode: horizontal-tb; text-orientation: sideways-left; direction: rtl; ", - // "writing-mode: horizontal-tb; text-orientation: sideways; direction: rtl; ", + "writing-mode: horizontal-tb; direction: rtl; ", ], blockStart: "top", blockEnd: "bottom", inlineStart: "right", inlineEnd: "left", block: "vertical", inline: "horizontal" }, { style: [ - "writing-mode: vertical-rl; text-orientation: mixed; direction: rtl; ", - "writing-mode: vertical-rl; text-orientation: upright; direction: rtl; ", - "writing-mode: vertical-rl; text-orientation: sideways-right; direction: rtl; ", - // "writing-mode: vertical-rl; text-orientation: sideways-left; direction: ltr; ", - // "writing-mode: vertical-rl; text-orientation: sideways; direction: rtl; ", + "writing-mode: vertical-rl; direction: rtl; ", + "writing-mode: sideways-rl; direction: rtl; ", ], blockStart: "right", blockEnd: "left", inlineStart: "bottom", inlineEnd: "top", block: "horizontal", inline: "vertical" }, { style: [ - "writing-mode: vertical-rl; text-orientation: mixed; direction: ltr; ", - "writing-mode: vertical-rl; text-orientation: upright; direction: ltr; ", - "writing-mode: vertical-rl; text-orientation: sideways-right; direction: ltr; ", - // "writing-mode: vertical-rl; text-orientation: sideways-left; direction: rtl; ", - // "writing-mode: vertical-rl; text-orientation: sideways; direction: ltr; ", + "writing-mode: vertical-rl; direction: ltr; ", + "writing-mode: sideways-rl; direction: ltr; ", ], blockStart: "right", blockEnd: "left", inlineStart: "top", inlineEnd: "bottom", block: "horizontal", inline: "vertical" }, { style: [ - "writing-mode: vertical-lr; text-orientation: mixed; direction: rtl; ", - "writing-mode: vertical-lr; text-orientation: upright; direction: rtl; ", - "writing-mode: vertical-lr; text-orientation: sideways-right; direction: rtl; ", - // "writing-mode: vertical-lr; text-orientation: sideways-left; direction: ltr; ", - // "writing-mode: vertical-lr; text-orientation: sideways; direction: ltr; ", + "writing-mode: vertical-lr; direction: rtl; ", + "writing-mode: sideways-lr; direction: ltr; ", ], blockStart: "left", blockEnd: "right", inlineStart: "bottom", inlineEnd: "top", block: "horizontal", inline: "vertical" }, { style: [ - "writing-mode: vertical-lr; text-orientation: mixed; direction: ltr; ", - "writing-mode: vertical-lr; text-orientation: upright; direction: ltr; ", - "writing-mode: vertical-lr; text-orientation: sideways-right; direction: ltr; ", - // "writing-mode: vertical-lr; text-orientation: sideways-left; direction: rtl; ", - // "writing-mode: vertical-lr; text-orientation: sideways; direction: rtl; ", + "writing-mode: vertical-lr; direction: ltr; ", + "writing-mode: sideways-lr; direction: rtl; ", ], blockStart: "left", blockEnd: "right", inlineStart: "top", inlineEnd: "bottom", block: "horizontal", inline: "vertical" }, @@ -156,27 +138,6 @@ function init() { make_declaration(gCSSProperties[`${aPrefix}height`].prerequisites) }); }); - - // Assume that sideways-left and sideways keywords are still not parsed yet - // for text-orientation. When we start supporting these keywords, the - // entries in the .style properties of the gWritingModes objects above - // should be uncommented. - var s = document.createElement("style"); - document.body.appendChild(s); - - s.textContent = "div { }"; - s.sheet.cssRules[0].style.textOrientation = "sideways-left"; - todo(s.sheet.cssRules[0].style.textOrientation, "sideways-left", - "uncomment sideways-left cases from gWritingModes and " + - "remove this todo()!"); - - s.textContent = "div { }"; - s.sheet.cssRules[0].style.textOrientation = "sideways"; - todo(s.sheet.cssRules[0].style.textOrientation, "sideways", - "uncomment sideways cases from gWritingModes and " + - "remove this todo()!"); - - s.remove(); } function test_computed_values(aTestName, aRules, aExpectedValues) { diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index d276816b1f..ee6ab737be 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -531,7 +531,7 @@ nsFilterInstance::OutputFilterSpaceBounds() const nsIntRect bounds = mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion(); bool overflow; - gfxIntSize surfaceSize = + IntSize surfaceSize = nsSVGUtils::ConvertToSurfaceSize(bounds.Size(), &overflow); bounds.SizeTo(surfaceSize); return bounds; diff --git a/layout/svg/nsSVGImageFrame.cpp b/layout/svg/nsSVGImageFrame.cpp index 22ab25516f..4fd421f44f 100644 --- a/layout/svg/nsSVGImageFrame.cpp +++ b/layout/svg/nsSVGImageFrame.cpp @@ -405,7 +405,7 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext, if (opacity != 1.0f || StyleDisplay()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) { aContext.PopGroupToSource(); - aContext.SetOperator(gfxContext::OPERATOR_OVER); + aContext.SetOp(CompositionOp::OP_OVER); aContext.Paint(opacity); } // gfxContextAutoSaveRestore goes out of scope & cleans up our gfxContext diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index c58832620f..73964ce9d2 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -610,7 +610,7 @@ class PaintFrameCallback : public gfxDrawingCallback { public: PaintFrameCallback(nsIFrame* aFrame, const nsSize aPaintServerSize, - const gfxIntSize aRenderSize, + const IntSize aRenderSize, uint32_t aFlags) : mFrame(aFrame) , mPaintServerSize(aPaintServerSize) @@ -624,7 +624,7 @@ public: private: nsIFrame* mFrame; nsSize mPaintServerSize; - gfxIntSize mRenderSize; + IntSize mRenderSize; uint32_t mFlags; }; @@ -695,7 +695,7 @@ PaintFrameCallback::operator()(gfxContext* aContext, nsSVGIntegrationUtils::DrawableFromPaintServer(nsIFrame* aFrame, nsIFrame* aTarget, const nsSize& aPaintServerSize, - const gfxIntSize& aRenderSize, + const IntSize& aRenderSize, const DrawTarget* aDrawTarget, const gfxMatrix& aContextMatrix, uint32_t aFlags) diff --git a/layout/svg/nsSVGIntegrationUtils.h b/layout/svg/nsSVGIntegrationUtils.h index 2554e6e69d..e14a9fa01a 100644 --- a/layout/svg/nsSVGIntegrationUtils.h +++ b/layout/svg/nsSVGIntegrationUtils.h @@ -166,13 +166,13 @@ public: }; static already_AddRefed - DrawableFromPaintServer(nsIFrame* aFrame, - nsIFrame* aTarget, - const nsSize& aPaintServerSize, - const gfxIntSize& aRenderSize, + DrawableFromPaintServer(nsIFrame* aFrame, + nsIFrame* aTarget, + const nsSize& aPaintServerSize, + const mozilla::gfx::IntSize& aRenderSize, const DrawTarget* aDrawTarget, - const gfxMatrix& aContextMatrix, - uint32_t aFlags); + const gfxMatrix& aContextMatrix, + uint32_t aFlags); }; #endif /*NSSVGINTEGRATIONUTILS_H_*/ diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index c3d3a5ccc3..79f6dcbef1 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -802,11 +802,11 @@ nsSVGUtils::TransformFrameRectToOuterSVG(const nsRect& aRect, aMatrix.TransformBounds(r), aPresContext->AppUnitsPerDevPixel()); } -gfxIntSize +IntSize nsSVGUtils::ConvertToSurfaceSize(const gfxSize& aSize, bool *aResultOverflows) { - gfxIntSize surfaceSize(ClampToInt(ceil(aSize.width)), ClampToInt(ceil(aSize.height))); + IntSize surfaceSize(ClampToInt(ceil(aSize.width)), ClampToInt(ceil(aSize.height))); *aResultOverflows = surfaceSize.width != ceil(aSize.width) || surfaceSize.height != ceil(aSize.height); diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 8c982a768a..befeeb4a48 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -351,8 +351,8 @@ public: * @param aResultOverflows true if the desired surface size is too big * @return the surface size to use */ - static gfxIntSize ConvertToSurfaceSize(const gfxSize& aSize, - bool *aResultOverflows); + static mozilla::gfx::IntSize ConvertToSurfaceSize(const gfxSize& aSize, + bool *aResultOverflows); /* * Hit test a given rectangle/matrix. diff --git a/media/webrtc/signaling/test/FakeMediaStreamsImpl.h b/media/webrtc/signaling/test/FakeMediaStreamsImpl.h index a66968768f..ed28875042 100644 --- a/media/webrtc/signaling/test/FakeMediaStreamsImpl.h +++ b/media/webrtc/signaling/test/FakeMediaStreamsImpl.h @@ -158,19 +158,20 @@ Fake_VideoStreamSource::Notify(nsITimer* aTimer) mozilla::layers::PlanarYCbCrData data; data.mYChannel = frame; - data.mYSize = gfxIntSize(WIDTH, HEIGHT); + data.mYSize = mozilla::gfx::IntSize(WIDTH, HEIGHT); data.mYStride = WIDTH * lumaBpp / 8.0; data.mCbCrStride = WIDTH * chromaBpp / 8.0; data.mCbChannel = frame + HEIGHT * data.mYStride; data.mCrChannel = data.mCbChannel + HEIGHT * data.mCbCrStride / 2; - data.mCbCrSize = gfxIntSize(WIDTH / 2, HEIGHT / 2); + data.mCbCrSize = mozilla::gfx::IntSize(WIDTH / 2, HEIGHT / 2); data.mPicX = 0; data.mPicY = 0; - data.mPicSize = gfxIntSize(WIDTH, HEIGHT); + data.mPicSize = mozilla::gfx::IntSize(WIDTH, HEIGHT); data.mStereoMode = mozilla::layers::StereoMode::MONO; mozilla::VideoSegment segment; - segment.AppendFrame(image.forget(), USECS_PER_S / FPS, gfxIntSize(WIDTH, HEIGHT)); + segment.AppendFrame(image.forget(), USECS_PER_S / FPS, + mozilla::gfx::IntSize(WIDTH, HEIGHT)); // TODO(ekr@rtfm.com): are we leaking? #endif diff --git a/widget/cocoa/nsCocoaUtils.mm b/widget/cocoa/nsCocoaUtils.mm index ebc61f3c41..8f7dca5de3 100644 --- a/widget/cocoa/nsCocoaUtils.mm +++ b/widget/cocoa/nsCocoaUtils.mm @@ -485,8 +485,7 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, ui // Render a vector image at the correct resolution on a retina display if (aImage->GetType() == imgIContainer::TYPE_VECTOR && scaleFactor != 1.0f) { - gfxIntSize scaledSize(ceil(width * scaleFactor), - ceil(height * scaleFactor)); + IntSize scaledSize(ceil(width * scaleFactor), ceil(height * scaleFactor)); RefPtr drawTarget = gfxPlatform::GetPlatform()-> CreateOffscreenContentDrawTarget(scaledSize, SurfaceFormat::B8G8R8A8); diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 9c4915eaf4..97d65d9087 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -2170,7 +2170,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) UpdateAlpha(pattern, boundsRect); - ctx->SetOperator(gfxContext::OPERATOR_SOURCE); + ctx->SetOp(CompositionOp::OP_SOURCE); ctx->SetPattern(pattern); ctx->Paint(); } @@ -6053,7 +6053,7 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, Visual* xVisual = gdk_x11_visual_get_xvisual(visual); result = new gfxXlibSurface(xDisplay, xDrawable, xVisual, - gfxIntSize(aSize.width, aSize.height)); + IntSize(aSize.width, aSize.height)); } else { // no visual? we must be using an xrender format. Find a format // for this depth. @@ -6071,7 +6071,7 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, } result = new gfxXlibSurface(xScreen, xDrawable, pf, - gfxIntSize(aSize.width, aSize.height)); + IntSize(aSize.width, aSize.height)); } return result.forget(); diff --git a/widget/nsShmImage.cpp b/widget/nsShmImage.cpp index bc152dabc8..f5266d6e84 100644 --- a/widget/nsShmImage.cpp +++ b/widget/nsShmImage.cpp @@ -46,7 +46,7 @@ TrapShmError(Display* aDisplay, XErrorEvent* aEvent) #endif already_AddRefed -nsShmImage::Create(const gfxIntSize& aSize, +nsShmImage::Create(const IntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth) { nsRefPtr shm = new nsShmImage(); @@ -180,7 +180,7 @@ nsShmImage::Put(QWindow* aWindow, QRect& aRect) #endif already_AddRefed -nsShmImage::EnsureShmImage(const gfxIntSize& aSize, +nsShmImage::EnsureShmImage(const IntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, nsRefPtr& aImage) { diff --git a/widget/nsShmImage.h b/widget/nsShmImage.h index a125e5ef71..6f14c6c3fc 100644 --- a/widget/nsShmImage.h +++ b/widget/nsShmImage.h @@ -38,10 +38,10 @@ class nsShmImage { public: static bool UseShm(); static already_AddRefed - Create(const gfxIntSize& aSize, + Create(const mozilla::gfx::IntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth); static already_AddRefed - EnsureShmImage(const gfxIntSize& aSize, + EnsureShmImage(const mozilla::gfx::IntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, nsRefPtr& aImage); @@ -65,7 +65,7 @@ public: void Put(QWindow* aWindow, QRect& aRect); #endif - gfxIntSize Size() const { return mSize; } + mozilla::gfx::IntSize Size() const { return mSize; } private: nsShmImage() @@ -79,7 +79,7 @@ private: XImage* mImage; Display* mDisplay; XShmSegmentInfo mInfo; - gfxIntSize mSize; + mozilla::gfx::IntSize mSize; mozilla::gfx::SurfaceFormat mFormat; bool mXAttached; }; diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index c01cf7eb14..47db773256 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -817,8 +817,8 @@ nsWindow::StartRemoteDrawing() Screen* screen = DefaultScreenOfDisplay(dpy); Visual* defaultVisual = DefaultVisualOfScreen(screen); gfxASurface* surf = new gfxXlibSurface(dpy, mWidget->winId(), defaultVisual, - gfxIntSize(mWidget->width(), - mWidget->height())); + IntSize(mWidget->width(), + mWidget->height())); IntSize size(surf->GetSize().width, surf->GetSize().height); if (size.width <= 0 || size.height <= 0) { diff --git a/widget/uikit/nsWindow.h b/widget/uikit/nsWindow.h index 00e1c7a537..47cfdbb85b 100644 --- a/widget/uikit/nsWindow.h +++ b/widget/uikit/nsWindow.h @@ -126,7 +126,7 @@ protected: nsWindow* mParent; InputContext mInputContext; - void OnSizeChanged(const gfxIntSize& aSize); + void OnSizeChanged(const mozilla::gfx::IntSize& aSize); static void DumpWindows(); static void DumpWindows(const nsTArray& wins, int indent = 0); diff --git a/widget/windows/TaskbarPreview.cpp b/widget/windows/TaskbarPreview.cpp index 6b5bbe0096..1dd308d0b8 100644 --- a/widget/windows/TaskbarPreview.cpp +++ b/widget/windows/TaskbarPreview.cpp @@ -357,7 +357,7 @@ TaskbarPreview::UpdateTooltip() { void TaskbarPreview::DrawBitmap(uint32_t width, uint32_t height, bool isPreview) { nsresult rv; - nsRefPtr surface = new gfxWindowsSurface(gfxIntSize(width, height), gfxImageFormat::ARGB32); + nsRefPtr surface = new gfxWindowsSurface(gfx::IntSize(width, height), gfxImageFormat::ARGB32); nsCOMPtr shell = do_QueryReferent(mDocShell); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index ec638f2c24..4f3c10ed67 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -2590,7 +2590,7 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor, HCURSOR cursor; // No scaling - gfxIntSize size(0, 0); + IntSize size(0, 0); rv = nsWindowGfx::CreateIcon(aCursor, true, aHotspotX, aHotspotY, size, &cursor); NS_ENSURE_SUCCESS(rv, rv); @@ -6855,7 +6855,7 @@ void nsWindow::ResizeTranslucentWindow(int32_t aNewWidth, int32_t aNewHeight, bo return; nsRefPtr newSurface = - new gfxWindowsSurface(gfxIntSize(aNewWidth, aNewHeight), gfxImageFormat::ARGB32); + new gfxWindowsSurface(IntSize(aNewWidth, aNewHeight), gfxImageFormat::ARGB32); mTransparentSurface = newSurface; mMemoryDC = newSurface->GetDC(); } diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp index 5c48f5e6b1..7b7f3e5fcb 100644 --- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -70,7 +70,7 @@ using namespace mozilla::plugins; **************************************************************/ static nsAutoPtr sSharedSurfaceData; -static gfxIntSize sSharedSurfaceSize; +static IntSize sSharedSurfaceSize; struct IconMetrics { int32_t xMetric; @@ -137,9 +137,9 @@ nsIntRegion nsWindow::GetRegionToPaint(bool aForceFullRepaint, #define WORDSSIZE(x) ((x).width * (x).height) static bool -EnsureSharedSurfaceSize(gfxIntSize size) +EnsureSharedSurfaceSize(IntSize size) { - gfxIntSize screenSize; + IntSize screenSize; screenSize.height = GetSystemMetrics(SM_CYSCREEN); screenSize.width = GetSystemMetrics(SM_CXSCREEN); @@ -341,8 +341,8 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32) || IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24))) { - gfxIntSize surfaceSize(ps.rcPaint.right - ps.rcPaint.left, - ps.rcPaint.bottom - ps.rcPaint.top); + IntSize surfaceSize(ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top); if (!EnsureSharedSurfaceSize(surfaceSize)) { NS_ERROR("Couldn't allocate a shared image surface!"); @@ -425,7 +425,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24) || IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32)) { - gfxIntSize surfaceSize = targetSurfaceImage->GetSize(); + IntSize surfaceSize = targetSurfaceImage->GetSize(); // Just blit this directly BITMAPINFOHEADER bi; @@ -560,7 +560,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) return result; } -gfxIntSize nsWindowGfx::GetIconMetrics(IconSizeType aSizeType) { +IntSize nsWindowGfx::GetIconMetrics(IconSizeType aSizeType) { int32_t width = ::GetSystemMetrics(sIconMetrics[aSizeType].xMetric); int32_t height = ::GetSystemMetrics(sIconMetrics[aSizeType].yMetric); @@ -568,14 +568,14 @@ gfxIntSize nsWindowGfx::GetIconMetrics(IconSizeType aSizeType) { width = height = sIconMetrics[aSizeType].defaultSize; } - return gfxIntSize(width, height); + return IntSize(width, height); } nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer, bool aIsCursor, uint32_t aHotspotX, uint32_t aHotspotY, - gfxIntSize aScaledSize, + IntSize aScaledSize, HICON *aIcon) { MOZ_ASSERT((aScaledSize.width > 0 && aScaledSize.height > 0) || diff --git a/widget/windows/nsWindowGfx.h b/widget/windows/nsWindowGfx.h index a73c165c5f..3f4d763621 100644 --- a/widget/windows/nsWindowGfx.h +++ b/widget/windows/nsWindowGfx.h @@ -19,8 +19,10 @@ public: kSmallIcon, kRegularIcon }; - static gfxIntSize GetIconMetrics(IconSizeType aSizeType); - static nsresult CreateIcon(imgIContainer *aContainer, bool aIsCursor, uint32_t aHotspotX, uint32_t aHotspotY, gfxIntSize aScaledSize, HICON *aIcon); + static mozilla::gfx::IntSize GetIconMetrics(IconSizeType aSizeType); + static nsresult CreateIcon(imgIContainer *aContainer, bool aIsCursor, + uint32_t aHotspotX, uint32_t aHotspotY, + mozilla::gfx::IntSize aScaledSize, HICON *aIcon); private: /**