mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
aec5e5666e
- bug 1083930 - cpu spin during large h2/spdy upload r=hurley (0949388a6a)
- Bug 1241906 - Spdy deadlock on suspended channel r=hurley (f40e9677d5)
- Bug 1247205 - dont loop on http2 softerror r=dragana (2ab3cb69ef)
- Bug 1246778 - dont loop in nshttpconnection during shutdown r=dragana (0677b9d34b)
- Bug 1201037 - only send "HTTP pings" on seemingly idle connections, r=mcmanus (134198bc79)
- Bug 1174899 - discarded spdy data with fin attributed to wrong stream r=bagder (f3b801c734)
- Bug 1236170 - Make Http2Session::UncompressAndDiscard push-aware. r=mcmanus (e71634e853)
- Bug 1240025 - incorrect close state on pushed stream r=hurley (eb2832177a)
- Bug 1227931 - init Http2Stream::mReceivedData in the constructor. r=nwgh (44f1d8e897)
- Bug 241788 - net_FilterURIString should filter \r\n\t from the entire URL r=honzab (734d9b8cae)
- Bug 1259459 - h2 0 length options puts end-stream on headers r=hurley (31ac211a9b)
- Bug 1174899 - fixup log format strings for spdy/h2 r=bagder (967c9ff71e)
- Bug 1211694 - dataLength has been added twice. r=mcmanus (6773981db3)
- cleanup (26517f5de0)
- Bug 1247998 - Let nsHttpChannel::AsyncOpen* throw after nsHttpHandler has been shutdown, r=mcmanus (90bb2364be)
- Bug 1231512 - Allow nsIHttpChannel.redirectTo() work also on an open channel, r=jduell (198fb72816)
- Bug 1242472 - Properly propagate mTopWindowURI through redirects. r=francois/ckerschb (1d27a15770)
- Bug 1133873 - some spdy logs r=hurley (cd95cfed5a)
- bug 1215724 - enable brotli on spdy r=hurley (83cca72fa5)
- Bug 137852 - Add a new working HTTP authentication identity to the begining of the session cache list. r=honzab (f670349771)
- Bug 1245414, part 1 - Delete the mfbt/decimal/LICENSE* files since upstream now just uses inline comments. r=Waldo (15bb211e14)
- Bug 1245414, part 2 - Update mfbt/decimal/update.sh to reflect Blink's switch from svn to git, and the different files we now pull. r=Waldo (4dd0b5916a)
- Bug 1245414, part 3 - Overwrite mfbt/decimal/Decimal.* with vanilla upstream copies. r=Waldo (98f7ba4711)
- Bug 1245414, part 4 - Update mfbt/decimal/zero-serialization.patch. r =Waldo (055e1354a7)
- Bug 1245414, part 5 - Update mfbt/decimal/comparison-with-nan.patch. r=Waldo (583e0f3e76)
- Bug 1245414, part 6 - Update mfbt/decimal/mfbt-abi-markers.patch. r=Waldo (148b1ac08b)
- Bug 1245414, part 7 - Update mfbt/decimal/to-moz-dependencies.patch. r=Waldo (2e2a6a33d7)
- Bug 1245414, part 8 - Remove mfbt/decimal/floor-ceiling.patch now that the issue is fixed upstream. r=Waldo (84fc02c068)
- Bug 1245414, part 9 - Disable mfbt/decimal/fix-wshadow-warnings.patch. r=cpeterson (4476d04c5d)
- Bug 1245414, part 10 - Apply the Mozilla patches via mfbt/decimal/update.sh. r=Waldo (1f95ef5524)
- Bug 1247082 - Suppress rendering of nsBackdropFrame for VR content r=dholbert (0ffeae4267)
- Bug 1206545 - Initialize AccessibleCaretEventHub in nsCanvasFrame. r=roc (687d4997fb)
- Bug 591737 - Add SummaryFrame. r=bz (1b750bfeb8)
- Bug 1165893 - Fix rounding issue in nsDisplaySelectionOverlay::Paint. r=mattwoodro (9994cc983a)
- Bug 1245450 - Only setup AutoSaveRestorePerspectiveIndex for the descendants of the element with perspective. r=roc (fe8a350417)
- Bug 1243282 - Wrap items having clips with a separator. r=mattwoodrow (915737e3d0)
- Bug 1223232 - Use GetUsedBorder() instead of the computed border value when calculating CB size. r=roc (f4c05b30c7)
- Bug 1223232 - Crashtest. (394e112818)
- Bug 1230665 - Make anonymous flex/grid items non-tabbable and non-focusable. r=roc (0d3f70e672)
- Bug 1142295 - Closing descriptor when GECKO_DISPLAY_REFLOW_RULES_FILE is setted. r=erahm (664ae6ba0a)
- minor change (b914bd2602)
- Bug 1237754 part 1 - [css-grid][css-align] Make 'align/justify-content:normal' behave as 'stretch' for Grid containers. r=dholbert (09a9a09629)
- Bug 1237754 part 2 - [css-grid][css-align] Test updates to account for new default behavior for 'align/justify-content'. (5e62e837ff)
- minor of Bug 1141931 part 2 (a12f5b430e)
- Bu 974309: Fixes the IsEditable() logic for table cells. r=ehsan (2a3caa932f)
- Bug 1238137 - Telemetry pings for main thread keyboard-driven scroll input methods. r=ehsan (e9c07427f9)
- Bug 1238137 - Telemetry pings for main thread scrolling to bring the caret into view after moving it in response to keyboard input. r=ehsan (834bc12b7a)
- Bug 1246405 - Declare mTextRun earlier to avoid alignment spill on 64-bit architectures. r=roc (7ba93b72c9)
- Fixing bug 440486. Work around a Windows XP fax dialog bug. r=rstrong. (a59409acd6)
- Bug 1240911 - Prevent SerializedStructuredCloneBuffer from escaping into the heap. r=amarchesini (2c0b7c474b)
- Bug 1240985 - Hold off processing some messages during timeout (r=dvander) (10f6f6d7a2)
- Bug 1146471 - Release thread asserts for IPC (r=dvander) (f94d0ee09a)
- Bug 1240985 - Fix bug where mAwaitingSyncReply can be overwritten in Send after Cancel (r=dvander) (7b95acdca6)
- Bug 1193861: Log to the process log when launching a sandboxed process on Windows. r=billm (0ad1afd0d0)
- Bug 1233061 - add override declarations for MessagePumpForNonMainUIThreads; r=billm (94b9a5bfe9)
- Bug 1172467: Fix an IPC channel file descriptor leak from Nuwa to the child process. r=khuey (908601ed0e)
- Bug 1240985 - Check WasTransactionCanceled after timeout (and avoid timing out) (r=dvander) (33aade0a92)
- Bug 1237458 - Use MOZ_RELEASE_ASSERT for IPC assertions (r=jld) (cb0f058205)
- Bug 1247429 - Warn instead of error if shmem deallocated before IPDL sends it. r=nical (3c94d99b21)
- Bug 1175999 - Deallocate mach SharedMemory properly. r=blassey. (542649b570)
- Bug 1188186 - Fix leak of FDs in |CreateTransport|. r=bds (a40b9a0c58)
- Bg 1240607 - Force CreateWindow hooks to be detours. r=jmathies (895d1c21c4)
- Bug 1209464: Fix missing neutered window region in MessageChannel::WaitForInterruptNotify. Regression from bug 1189709; r=jimm (204256880b)
- Bug 1229825 - Make GIF deinterlacer respect the frame rect bounds. r=tn (904f6bd9b7)
- Bug 1242093 - Fix assertion in Downscaler::ClearRow. r=njn (63ffe82e99)
- Bug 1235859 - Add FrameSize to non-skia downscaler. r=edwin (e7474630e0)
- Bug 1237709: During RasterImage error-handling cleanup, set UniquePtr mAnim to null instead of using reset(), to avoid leaking. r=dholbert (b064f9c20d)
- Bug 1235605 - Use CheckedInt in Deinterlacer and make its buffer allocation fallible. r=tn (f6f3858c65)
- cleanup (f02aa9441e)
- Bug 1242778: Add MOZ_COUNT_CTOR & MOZ_COUNT_DTOR calls to track leaks of imagelib's FrameAnimator class. r=tn (b1aa366694)
- Bug 1241728. Add crashtest. (17d80a3387)
- Bug 1241729. Add crashtest. (bd6d7337d7)
- Bug 1241728. Limit the size of images that we will downscale from to 1048576 pixels. r=edwin (ad38a82aad)
- Bug 1218782 - use fallible allocations in Downscaler.cpp; r=seth (b22caa1121)
- Bug 1224979. Check if we compute usable filters for the downscaler, and if not put the downscaler in error state so it's not used. r=edwin (8fb59463ef)
- Bug 1235297 - Annotate intentional switch fallthroughs to suppress -Wimplicit-fallthrough warnings in image/decoders/. r=tn (094c37c0fe)
- Bug 1238558 (part 1) - Add Decoder::BeforeFinishInternal(). r=tnikkel. (c7922054d6)
- Bug 1238558 (part 2) - Add a test. r=tnikkel. (7e09caf47f)
- Bug 1238551 (part 2) - Add a test. r=tn. (f548a2cb97)
- Bug 1238551 (part 1) - Reject BITMAPV3INFOHEADER BMP images. r=tn. (c4c8f95cb3)
- Bug 1240629. Don't buffer image file data that we are never going to look at in the gap between the header and the pixel data for BMP files. r=njn (f580910cd3)
- Bug 1237171 - Improve a case where ICO and BMP files disagree on an image size. r=tn. (615db65802)
- Bug 1220021 (part 1) - Don't treat 0RGB ICO files as transparent. r=seth. (b97298285f)
- Bug 1220021 (part 2) - Add four reftests. r=seth. (b1e7b58a98)
- Bug 1163856 (Part 2) - Fix tests that depended on image load event timing. r=tn (4304c676a0)
- Bug 1207958 - Fix heuristic for choosing which ICO sub-image to render - r=tn (3d4db5a033)
- Bug 987625 - Conditionally define MOZ_PNG_MAX_DIMENSION. r=jrmuizel (859bae490c)
- Bug 75077 - Interpolate interlaced PNG images instead of libpng blocky display. r=seth (bc17b43fa6)
- fix side-effect of 1219405 (6536821e18)
- Bug 1245845, part 1 - Stop Moz2D Path::CopyToBuilder/TransformedCopyToBuilder implicitly converting the Path's FillRule. r=Bas (ecc552f359)
- Bug 1245845, part 2 - Remove code that is now useless from gfxContext::EnsurePath. r=Bas (2430be2837)
- Bug 1237448 - Moz2Dify two functions in gfxSurfaceDrawable. r=roc. (bb768302c5)
- Bug 1231888 (follow-up) - Simplify CurrentSurface(). r=jrmuizel. (303cea98f3)
- Bug 1247380: Only copy the background if we can succesfully get a snapshot. r=jrmuizel (13b64445e9)
- Bug 1228507 - Initialize mBlendOpacity. r=Bas (b301a2c9f4)
- Bug 1238846 (part 2) - Remove gfxContext::mOriginalDT, which is unused. r=mattwoodrow. (a5b0f948b7)
- Bug 1240819 - cleanup dead branches in gfxXlibNativeRender.cpp. r=jrmuizel (57bbec6693)
- Bug 1234950 - When advancing APZ animations, use the next vsync timestamp instead of the current one, since that is what will be composited. r=mstange (421829d459)
- Bug 1021845 - Don't skip checkerboarding layers during compositing, even if the layer's visible region is empty. r=botond (6cf1497019)
- Bug 1230149 - check bigImgIter to see if it's not null. r=jmuizelaar (aeef579f9f)
- Bug 1248325 - Update BufferTextureHost::GetAsSurface() r=nical (39a8b3ca71)
- reapply per misspatch Bug 1200595 - Consolidate the TextureClient's destruction logic (68966e4dc3)
- Bug 1249245 - Add missing header gfxPrefs.h to GrallocTextureClient.cpp. r=cyu (676669eb01)
- Bug 1245057: Refer to |gfx::IntPoint| in |GrallocTextureHostOGL::SetCropRect|, r=sotaro (99e572f3f6)
- Bug 1240867 - Fix non-unified build bustage in OGLShaderProgram.cpp. r=nical (0071f08285)
- Bug 1238015 - Make sure PTexture actors are destroyed after all messages referring to them are sent. r=sotaro (250f99b4a4)
- Bug 1220895 - Add layerviewer for layer tree & display list visualization NPOTB. r=botond (fa211145a1)
- Bug 1213464 - ImageBridgeChild and CompositorChild should delete their Transport. r=billm (a37a0dbdfd)
- Bug 1234343 (part 1) - Make GfxMemoryImageReporter::sAmount signed. r=Bas. (18f0cb61ec)
- Bug 1234343 (part 2) - Add a missing GfxMemoryImageReporter::DidAlloc() call. r=Bas. (69df7f3674)
- Bug 1245249 - Check actor state before calling Send__delete__(); r=luke (65716a5915)
- Bug 1221418 - A better cleanup method for AsmJSCache::ChildRunnable, r=janv (5c8c023b9d)
- Bug 1235657 - Session storage needs to handle origin attributes correctly - part 1 - createOriginAttributesWithUserContextId, r=huseby (f2df8109ef)
- Bug 1245954 - Console StartTimer/StopTimer and IncrementCounter should run in the owning thread, r=bz (64f73d7759)
- Bug 1245957 - Adding assertions in Console about in which thread is running what, r=bz (291ee70e2d)
- Bug 1248022 - ConsoleEvent.styles can be a sequence of nullable strings, r=bz (b94ec79ac0)
- Bug 1245242 - Normalize to unit vector for DOMMatrix.rotateAxisAngleSelf. r=roc (3a9e684b4d)
- Bug 1236329. Back out the patch for bug 492933 (revision d8012b35413b) because it's not web-compatible in practice. r=smaug (f6540d84c3)
- mTarget can be null in CanvasRenderingContext2D::ClearRect(), return early if so. (13e8a4e26a)
693 lines
23 KiB
C++
693 lines
23 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/* rendering object that goes directly inside the document's scrollbars */
|
|
|
|
#include "nsCanvasFrame.h"
|
|
|
|
#include "AccessibleCaretEventHub.h"
|
|
#include "gfxUtils.h"
|
|
#include "nsContainerFrame.h"
|
|
#include "nsCSSRendering.h"
|
|
#include "nsPresContext.h"
|
|
#include "nsStyleContext.h"
|
|
#include "nsRenderingContext.h"
|
|
#include "nsGkAtoms.h"
|
|
#include "nsPresShell.h"
|
|
#include "nsIPresShell.h"
|
|
#include "nsDisplayList.h"
|
|
#include "nsCSSFrameConstructor.h"
|
|
#include "nsFrameManager.h"
|
|
#include "gfxPlatform.h"
|
|
#include "nsPrintfCString.h"
|
|
#include "mozilla/dom/AnonymousContent.h"
|
|
// for focus
|
|
#include "nsIScrollableFrame.h"
|
|
#ifdef DEBUG_CANVAS_FOCUS
|
|
#include "nsIDocShell.h"
|
|
#endif
|
|
|
|
//#define DEBUG_CANVAS_FOCUS
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
using namespace mozilla::layout;
|
|
using namespace mozilla::gfx;
|
|
|
|
nsCanvasFrame*
|
|
NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|
{
|
|
return new (aPresShell) nsCanvasFrame(aContext);
|
|
}
|
|
|
|
NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
|
|
|
|
NS_QUERYFRAME_HEAD(nsCanvasFrame)
|
|
NS_QUERYFRAME_ENTRY(nsCanvasFrame)
|
|
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
|
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
|
|
|
void
|
|
nsCanvasFrame::ShowCustomContentContainer()
|
|
{
|
|
if (mCustomContentContainer) {
|
|
mCustomContentContainer->UnsetAttr(kNameSpaceID_None, nsGkAtoms::hidden, true);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::HideCustomContentContainer()
|
|
{
|
|
if (mCustomContentContainer) {
|
|
mCustomContentContainer->SetAttr(kNameSpaceID_None, nsGkAtoms::hidden,
|
|
NS_LITERAL_STRING("true"),
|
|
true);
|
|
}
|
|
}
|
|
|
|
nsresult
|
|
nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
|
{
|
|
if (!mContent) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDocument> doc = mContent->OwnerDoc();
|
|
nsresult rv = NS_OK;
|
|
|
|
// Create the custom content container.
|
|
mCustomContentContainer = doc->CreateHTMLElement(nsGkAtoms::div);
|
|
#ifdef DEBUG
|
|
// We restyle our mCustomContentContainer, even though it's root anonymous
|
|
// content. Normally that's not OK because the frame constructor doesn't know
|
|
// how to order the frame tree in such cases, but we make this work for this
|
|
// particular case, so it's OK.
|
|
mCustomContentContainer->SetProperty(nsGkAtoms::restylableAnonymousNode,
|
|
reinterpret_cast<void*>(true));
|
|
#endif // DEBUG
|
|
|
|
aElements.AppendElement(mCustomContentContainer);
|
|
|
|
// XXX add :moz-native-anonymous or will that be automatically set?
|
|
rv = mCustomContentContainer->SetAttr(kNameSpaceID_None, nsGkAtoms::_class,
|
|
NS_LITERAL_STRING("moz-custom-content-container"),
|
|
true);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Append all existing AnonymousContent nodes stored at document level if any.
|
|
size_t len = doc->GetAnonymousContents().Length();
|
|
for (size_t i = 0; i < len; ++i) {
|
|
nsCOMPtr<Element> node = doc->GetAnonymousContents()[i]->GetContentNode();
|
|
mCustomContentContainer->AppendChildTo(node->AsContent(), true);
|
|
}
|
|
|
|
// Only create a frame for mCustomContentContainer if it has some children.
|
|
if (len == 0) {
|
|
HideCustomContentContainer();
|
|
}
|
|
|
|
RefPtr<AccessibleCaretEventHub> eventHub =
|
|
PresContext()->GetPresShell()->GetAccessibleCaretEventHub();
|
|
if (eventHub) {
|
|
// AccessibleCaret will insert anonymous caret elements.
|
|
eventHub->Init();
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter)
|
|
{
|
|
aElements.AppendElement(mCustomContentContainer);
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
|
{
|
|
nsIScrollableFrame* sf =
|
|
PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
|
|
if (sf) {
|
|
sf->RemoveScrollPositionListener(this);
|
|
}
|
|
|
|
// Elements inserted in the custom content container have the same lifetime as
|
|
// the document, so before destroying the container, make sure to keep a clone
|
|
// of each of them at document level so they can be re-appended on reframe.
|
|
if (mCustomContentContainer) {
|
|
nsCOMPtr<nsIDocument> doc = mContent->OwnerDoc();
|
|
ErrorResult rv;
|
|
|
|
nsTArray<RefPtr<mozilla::dom::AnonymousContent>>& docAnonContents =
|
|
doc->GetAnonymousContents();
|
|
for (size_t i = 0, len = docAnonContents.Length(); i < len; ++i) {
|
|
AnonymousContent* content = docAnonContents[i];
|
|
nsCOMPtr<nsINode> clonedElement = content->GetContentNode()->CloneNode(true, rv);
|
|
content->SetContentNode(clonedElement->AsElement());
|
|
}
|
|
}
|
|
nsContentUtils::DestroyAnonymousContent(&mCustomContentContainer);
|
|
|
|
nsContainerFrame::DestroyFrom(aDestructRoot);
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::ScrollPositionWillChange(nscoord aX, nscoord aY)
|
|
{
|
|
if (mDoPaintFocus) {
|
|
mDoPaintFocus = false;
|
|
PresContext()->FrameManager()->GetRootFrame()->InvalidateFrameSubtree();
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCanvasFrame::SetHasFocus(bool aHasFocus)
|
|
{
|
|
if (mDoPaintFocus != aHasFocus) {
|
|
mDoPaintFocus = aHasFocus;
|
|
PresContext()->FrameManager()->GetRootFrame()->InvalidateFrameSubtree();
|
|
|
|
if (!mAddedScrollPositionListener) {
|
|
nsIScrollableFrame* sf =
|
|
PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
|
|
if (sf) {
|
|
sf->AddScrollPositionListener(this);
|
|
mAddedScrollPositionListener = true;
|
|
}
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
void
|
|
nsCanvasFrame::SetInitialChildList(ChildListID aListID,
|
|
nsFrameList& aChildList)
|
|
{
|
|
NS_ASSERTION(aListID != kPrincipalList ||
|
|
aChildList.IsEmpty() || aChildList.OnlyChild(),
|
|
"Primary child list can have at most one frame in it");
|
|
nsContainerFrame::SetInitialChildList(aListID, aChildList);
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::AppendFrames(ChildListID aListID,
|
|
nsFrameList& aFrameList)
|
|
{
|
|
MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
|
|
if (!mFrames.IsEmpty()) {
|
|
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
|
|
// We only allow native anonymous child frames to be in principal child
|
|
// list in canvas frame.
|
|
MOZ_ASSERT(e.get()->GetContent()->IsInNativeAnonymousSubtree(),
|
|
"invalid child list");
|
|
}
|
|
}
|
|
nsFrame::VerifyDirtyBitSet(aFrameList);
|
|
nsContainerFrame::AppendFrames(aListID, aFrameList);
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::InsertFrames(ChildListID aListID,
|
|
nsIFrame* aPrevFrame,
|
|
nsFrameList& aFrameList)
|
|
{
|
|
// Because we only support a single child frame inserting is the same
|
|
// as appending
|
|
MOZ_ASSERT(!aPrevFrame, "unexpected previous sibling frame");
|
|
AppendFrames(aListID, aFrameList);
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::RemoveFrame(ChildListID aListID,
|
|
nsIFrame* aOldFrame)
|
|
{
|
|
MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
|
|
nsContainerFrame::RemoveFrame(aListID, aOldFrame);
|
|
}
|
|
#endif
|
|
|
|
nsRect nsCanvasFrame::CanvasArea() const
|
|
{
|
|
// Not clear which overflow rect we want here, but it probably doesn't
|
|
// matter.
|
|
nsRect result(GetVisualOverflowRect());
|
|
|
|
nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
|
|
if (scrollableFrame) {
|
|
nsRect portRect = scrollableFrame->GetScrollPortRect();
|
|
result.UnionRect(result, nsRect(nsPoint(0, 0), portRect.Size()));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void
|
|
nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
|
|
nsRenderingContext* aCtx)
|
|
{
|
|
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
|
nsPoint offset = ToReferenceFrame();
|
|
nsRect bgClipRect = frame->CanvasArea() + offset;
|
|
if (NS_GET_A(mColor) > 0) {
|
|
DrawTarget* drawTarget = aCtx->GetDrawTarget();
|
|
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
|
|
Rect devPxRect =
|
|
NSRectToSnappedRect(bgClipRect, appUnitsPerDevPixel, *drawTarget);
|
|
drawTarget->FillRect(devPxRect, ColorPattern(ToDeviceColor(mColor)));
|
|
}
|
|
}
|
|
|
|
#ifdef MOZ_DUMP_PAINTING
|
|
void
|
|
nsDisplayCanvasBackgroundColor::WriteDebugInfo(std::stringstream& aStream)
|
|
{
|
|
aStream << " (rgba "
|
|
<< (int)NS_GET_R(mColor) << ","
|
|
<< (int)NS_GET_G(mColor) << ","
|
|
<< (int)NS_GET_B(mColor) << ","
|
|
<< (int)NS_GET_A(mColor) << ")";
|
|
}
|
|
#endif
|
|
|
|
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
|
|
static void BlitSurface(DrawTarget* aDest, const gfxRect& aRect, DrawTarget* aSource)
|
|
{
|
|
RefPtr<SourceSurface> source = aSource->Snapshot();
|
|
aDest->DrawSurface(source,
|
|
Rect(aRect.x, aRect.y, aRect.width, aRect.height),
|
|
Rect(0, 0, aRect.width, aRect.height));
|
|
}
|
|
#endif
|
|
|
|
void
|
|
nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
|
|
nsRenderingContext* aCtx)
|
|
{
|
|
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
|
nsPoint offset = ToReferenceFrame();
|
|
nsRect bgClipRect = frame->CanvasArea() + offset;
|
|
|
|
#ifndef MOZ_GFX_OPTIMIZE_MOBILE
|
|
RefPtr<gfxContext> dest = aCtx->ThebesContext();
|
|
gfxRect destRect;
|
|
if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) &&
|
|
aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() &&
|
|
!dest->CurrentMatrix().HasNonIntegerTranslation()) {
|
|
// Snap image rectangle to nearest pixel boundaries. This is the right way
|
|
// to snap for this context, because we checked HasNonIntegerTranslation
|
|
// above.
|
|
destRect.Round();
|
|
RefPtr<DrawTarget> dt = static_cast<DrawTarget*>(
|
|
Frame()->Properties().Get(nsIFrame::CachedBackgroundImageDT()));
|
|
DrawTarget* destDT = dest->GetDrawTarget();
|
|
if (dt) {
|
|
BlitSurface(destDT, destRect, dt);
|
|
return;
|
|
}
|
|
|
|
dt = destDT->CreateSimilarDrawTarget(IntSize(ceil(destRect.width),
|
|
ceil(destRect.height)),
|
|
SurfaceFormat::B8G8R8A8);
|
|
if (dt) {
|
|
RefPtr<gfxContext> ctx = new gfxContext(dt);
|
|
ctx->SetMatrix(ctx->CurrentMatrix().Translate(-destRect.x, -destRect.y));
|
|
nsRenderingContext context(ctx);
|
|
PaintInternal(aBuilder, &context, bgClipRect, &bgClipRect);
|
|
BlitSurface(dest->GetDrawTarget(), destRect, dt);
|
|
frame->Properties().Set(nsIFrame::CachedBackgroundImageDT(),
|
|
dt.forget().take());
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
PaintInternal(aBuilder, aCtx, mVisibleRect, &bgClipRect);
|
|
}
|
|
|
|
void
|
|
nsDisplayCanvasThemedBackground::Paint(nsDisplayListBuilder* aBuilder,
|
|
nsRenderingContext* aCtx)
|
|
{
|
|
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
|
nsPoint offset = ToReferenceFrame();
|
|
nsRect bgClipRect = frame->CanvasArea() + offset;
|
|
|
|
PaintInternal(aBuilder, aCtx, mVisibleRect, &bgClipRect);
|
|
}
|
|
|
|
/**
|
|
* A display item to paint the focus ring for the document.
|
|
*
|
|
* The only reason this can't use nsDisplayGeneric is overriding GetBounds.
|
|
*/
|
|
class nsDisplayCanvasFocus : public nsDisplayItem {
|
|
public:
|
|
nsDisplayCanvasFocus(nsDisplayListBuilder* aBuilder, nsCanvasFrame *aFrame)
|
|
: nsDisplayItem(aBuilder, aFrame)
|
|
{
|
|
MOZ_COUNT_CTOR(nsDisplayCanvasFocus);
|
|
}
|
|
virtual ~nsDisplayCanvasFocus() {
|
|
MOZ_COUNT_DTOR(nsDisplayCanvasFocus);
|
|
}
|
|
|
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
|
|
bool* aSnap) override
|
|
{
|
|
*aSnap = false;
|
|
// This is an overestimate, but that's not a problem.
|
|
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
|
return frame->CanvasArea() + ToReferenceFrame();
|
|
}
|
|
|
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
|
nsRenderingContext* aCtx) override
|
|
{
|
|
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
|
frame->PaintFocus(aCtx->GetDrawTarget(), ToReferenceFrame());
|
|
}
|
|
|
|
NS_DISPLAY_DECL_NAME("CanvasFocus", TYPE_CANVAS_FOCUS)
|
|
};
|
|
|
|
void
|
|
nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|
const nsRect& aDirtyRect,
|
|
const nsDisplayListSet& aLists)
|
|
{
|
|
if (GetPrevInFlow()) {
|
|
DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
|
|
}
|
|
|
|
// Force a background to be shown. We may have a background propagated to us,
|
|
// in which case StyleBackground wouldn't have the right background
|
|
// and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
|
|
// a background.
|
|
// We don't have any border or outline, and our background draws over
|
|
// the overflow area, so just add nsDisplayCanvasBackground instead of
|
|
// calling DisplayBorderBackgroundOutline.
|
|
if (IsVisibleForPainting(aBuilder)) {
|
|
nsStyleContext* bgSC;
|
|
const nsStyleBackground* bg = nullptr;
|
|
bool isThemed = IsThemed();
|
|
if (!isThemed && nsCSSRendering::FindBackground(this, &bgSC)) {
|
|
bg = bgSC->StyleBackground();
|
|
}
|
|
aLists.BorderBackground()->AppendNewToTop(
|
|
new (aBuilder) nsDisplayCanvasBackgroundColor(aBuilder, this));
|
|
|
|
if (isThemed) {
|
|
aLists.BorderBackground()->AppendNewToTop(
|
|
new (aBuilder) nsDisplayCanvasThemedBackground(aBuilder, this));
|
|
return;
|
|
}
|
|
|
|
if (!bg) {
|
|
return;
|
|
}
|
|
|
|
bool needBlendContainer = false;
|
|
|
|
// Create separate items for each background layer.
|
|
const nsStyleImageLayers& layers = bg->mImage;
|
|
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, layers) {
|
|
if (layers.mLayers[i].mImage.IsEmpty()) {
|
|
continue;
|
|
}
|
|
if (layers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) {
|
|
needBlendContainer = true;
|
|
}
|
|
nsDisplayCanvasBackgroundImage* bgItem =
|
|
new (aBuilder) nsDisplayCanvasBackgroundImage(aBuilder, this, i, bg);
|
|
if (bgItem->ShouldFixToViewport(aBuilder)) {
|
|
aLists.BorderBackground()->AppendNewToTop(
|
|
nsDisplayFixedPosition::CreateForFixedBackground(aBuilder, this, bgItem, i));
|
|
} else {
|
|
aLists.BorderBackground()->AppendNewToTop(bgItem);
|
|
}
|
|
}
|
|
|
|
if (needBlendContainer) {
|
|
aLists.BorderBackground()->AppendNewToTop(
|
|
new (aBuilder) nsDisplayBlendContainer(aBuilder, this, aLists.BorderBackground()));
|
|
}
|
|
}
|
|
|
|
for (nsIFrame* kid : PrincipalChildList()) {
|
|
// Put our child into its own pseudo-stack.
|
|
BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
|
|
}
|
|
|
|
#ifdef DEBUG_CANVAS_FOCUS
|
|
nsCOMPtr<nsIContent> focusContent;
|
|
aPresContext->EventStateManager()->
|
|
GetFocusedContent(getter_AddRefs(focusContent));
|
|
|
|
bool hasFocus = false;
|
|
nsCOMPtr<nsISupports> container;
|
|
aPresContext->GetContainer(getter_AddRefs(container));
|
|
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
|
|
if (docShell) {
|
|
docShell->GetHasFocus(&hasFocus);
|
|
printf("%p - nsCanvasFrame::Paint R:%d,%d,%d,%d DR: %d,%d,%d,%d\n", this,
|
|
mRect.x, mRect.y, mRect.width, mRect.height,
|
|
aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
|
|
}
|
|
printf("%p - Focus: %s c: %p DoPaint:%s\n", docShell.get(), hasFocus?"Y":"N",
|
|
focusContent.get(), mDoPaintFocus?"Y":"N");
|
|
#endif
|
|
|
|
if (!mDoPaintFocus)
|
|
return;
|
|
// Only paint the focus if we're visible
|
|
if (!StyleVisibility()->IsVisible())
|
|
return;
|
|
|
|
aLists.Outlines()->AppendNewToTop(new (aBuilder)
|
|
nsDisplayCanvasFocus(aBuilder, this));
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::PaintFocus(DrawTarget* aDrawTarget, nsPoint aPt)
|
|
{
|
|
nsRect focusRect(aPt, GetSize());
|
|
|
|
nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
|
|
if (scrollableFrame) {
|
|
nsRect portRect = scrollableFrame->GetScrollPortRect();
|
|
focusRect.width = portRect.width;
|
|
focusRect.height = portRect.height;
|
|
focusRect.MoveBy(scrollableFrame->GetScrollPosition());
|
|
}
|
|
|
|
// XXX use the root frame foreground color, but should we find BODY frame
|
|
// for HTML documents?
|
|
nsIFrame* root = mFrames.FirstChild();
|
|
const nsStyleColor* color = root ? root->StyleColor() : StyleColor();
|
|
if (!color) {
|
|
NS_ERROR("current color cannot be found");
|
|
return;
|
|
}
|
|
|
|
nsCSSRendering::PaintFocus(PresContext(), aDrawTarget,
|
|
focusRect, color->mColor);
|
|
}
|
|
|
|
/* virtual */ nscoord
|
|
nsCanvasFrame::GetMinISize(nsRenderingContext *aRenderingContext)
|
|
{
|
|
nscoord result;
|
|
DISPLAY_MIN_WIDTH(this, result);
|
|
if (mFrames.IsEmpty())
|
|
result = 0;
|
|
else
|
|
result = mFrames.FirstChild()->GetMinISize(aRenderingContext);
|
|
return result;
|
|
}
|
|
|
|
/* virtual */ nscoord
|
|
nsCanvasFrame::GetPrefISize(nsRenderingContext *aRenderingContext)
|
|
{
|
|
nscoord result;
|
|
DISPLAY_PREF_WIDTH(this, result);
|
|
if (mFrames.IsEmpty())
|
|
result = 0;
|
|
else
|
|
result = mFrames.FirstChild()->GetPrefISize(aRenderingContext);
|
|
return result;
|
|
}
|
|
|
|
void
|
|
nsCanvasFrame::Reflow(nsPresContext* aPresContext,
|
|
nsHTMLReflowMetrics& aDesiredSize,
|
|
const nsHTMLReflowState& aReflowState,
|
|
nsReflowStatus& aStatus)
|
|
{
|
|
MarkInReflow();
|
|
DO_GLOBAL_REFLOW_COUNT("nsCanvasFrame");
|
|
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
|
|
NS_FRAME_TRACE_REFLOW_IN("nsCanvasFrame::Reflow");
|
|
|
|
// Initialize OUT parameter
|
|
aStatus = NS_FRAME_COMPLETE;
|
|
|
|
nsCanvasFrame* prevCanvasFrame = static_cast<nsCanvasFrame*>
|
|
(GetPrevInFlow());
|
|
if (prevCanvasFrame) {
|
|
AutoFrameListPtr overflow(aPresContext,
|
|
prevCanvasFrame->StealOverflowFrames());
|
|
if (overflow) {
|
|
NS_ASSERTION(overflow->OnlyChild(),
|
|
"must have doc root as canvas frame's only child");
|
|
nsContainerFrame::ReparentFrameViewList(*overflow, prevCanvasFrame, this);
|
|
// Prepend overflow to the our child list. There may already be
|
|
// children placeholders for fixed-pos elements, which don't get
|
|
// reflowed but must not be lost until the canvas frame is destroyed.
|
|
mFrames.InsertFrames(this, nullptr, *overflow);
|
|
}
|
|
}
|
|
|
|
// Set our size up front, since some parts of reflow depend on it
|
|
// being already set. Note that the computed height may be
|
|
// unconstrained; that's ok. Consumers should watch out for that.
|
|
SetSize(nsSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight()));
|
|
|
|
// Reflow our one and only normal child frame. It's either the root
|
|
// element's frame or a placeholder for that frame, if the root element
|
|
// is abs-pos or fixed-pos. We may have additional children which
|
|
// are placeholders for continuations of fixed-pos content, but those
|
|
// don't need to be reflowed. The normal child is always comes before
|
|
// the fixed-pos placeholders, because we insert it at the start
|
|
// of the child list, above.
|
|
nsHTMLReflowMetrics kidDesiredSize(aReflowState);
|
|
if (mFrames.IsEmpty()) {
|
|
// We have no child frame, so return an empty size
|
|
aDesiredSize.Width() = aDesiredSize.Height() = 0;
|
|
} else {
|
|
nsIFrame* kidFrame = mFrames.FirstChild();
|
|
bool kidDirty = (kidFrame->GetStateBits() & NS_FRAME_IS_DIRTY) != 0;
|
|
|
|
nsHTMLReflowState
|
|
kidReflowState(aPresContext, aReflowState, kidFrame,
|
|
aReflowState.AvailableSize(kidFrame->GetWritingMode()));
|
|
|
|
if (aReflowState.IsBResize() &&
|
|
(kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE)) {
|
|
// Tell our kid it's being block-dir resized too. Bit of a
|
|
// hack for framesets.
|
|
kidReflowState.SetBResize(true);
|
|
}
|
|
|
|
WritingMode wm = aReflowState.GetWritingMode();
|
|
WritingMode kidWM = kidReflowState.GetWritingMode();
|
|
nsSize containerSize = aReflowState.ComputedPhysicalSize();
|
|
|
|
LogicalMargin margin = kidReflowState.ComputedLogicalMargin();
|
|
LogicalPoint kidPt(kidWM, margin.IStart(kidWM), margin.BStart(kidWM));
|
|
|
|
kidReflowState.ApplyRelativePositioning(&kidPt, containerSize);
|
|
|
|
// Reflow the frame
|
|
ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState,
|
|
kidWM, kidPt, containerSize, 0, aStatus);
|
|
|
|
// Complete the reflow and position and size the child frame
|
|
FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, &kidReflowState,
|
|
kidWM, kidPt, containerSize, 0);
|
|
|
|
if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
|
|
nsIFrame* nextFrame = kidFrame->GetNextInFlow();
|
|
NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW,
|
|
"If it's incomplete and has no nif yet, it must flag a nif reflow.");
|
|
if (!nextFrame) {
|
|
nextFrame = aPresContext->PresShell()->FrameConstructor()->
|
|
CreateContinuingFrame(aPresContext, kidFrame, this);
|
|
SetOverflowFrames(nsFrameList(nextFrame, nextFrame));
|
|
// Root overflow containers will be normal children of
|
|
// the canvas frame, but that's ok because there
|
|
// aren't any other frames we need to isolate them from
|
|
// during reflow.
|
|
}
|
|
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
|
|
nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
|
|
}
|
|
}
|
|
|
|
// If the child frame was just inserted, then we're responsible for making sure
|
|
// it repaints
|
|
if (kidDirty) {
|
|
// But we have a new child, which will affect our background, so
|
|
// invalidate our whole rect.
|
|
// Note: Even though we request to be sized to our child's size, our
|
|
// scroll frame ensures that we are always the size of the viewport.
|
|
// Also note: GetPosition() on a CanvasFrame is always going to return
|
|
// (0, 0). We only want to invalidate GetRect() since Get*OverflowRect()
|
|
// could also include overflow to our top and left (out of the viewport)
|
|
// which doesn't need to be painted.
|
|
nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
|
|
viewport->InvalidateFrame();
|
|
}
|
|
|
|
// Return our desired size. Normally it's what we're told, but
|
|
// sometimes we can be given an unconstrained height (when a window
|
|
// is sizing-to-content), and we should compute our desired height.
|
|
LogicalSize finalSize(wm);
|
|
finalSize.ISize(wm) = aReflowState.ComputedISize();
|
|
if (aReflowState.ComputedBSize() == NS_UNCONSTRAINEDSIZE) {
|
|
finalSize.BSize(wm) = kidFrame->GetLogicalSize(wm).BSize(wm) +
|
|
kidReflowState.ComputedLogicalMargin().BStartEnd(wm);
|
|
} else {
|
|
finalSize.BSize(wm) = aReflowState.ComputedBSize();
|
|
}
|
|
|
|
aDesiredSize.SetSize(wm, finalSize);
|
|
aDesiredSize.SetOverflowAreasToDesiredBounds();
|
|
aDesiredSize.mOverflowAreas.UnionWith(
|
|
kidDesiredSize.mOverflowAreas + kidFrame->GetPosition());
|
|
}
|
|
|
|
if (prevCanvasFrame) {
|
|
ReflowOverflowContainerChildren(aPresContext, aReflowState,
|
|
aDesiredSize.mOverflowAreas, 0,
|
|
aStatus);
|
|
}
|
|
|
|
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
|
|
|
|
NS_FRAME_TRACE_REFLOW_OUT("nsCanvasFrame::Reflow", aStatus);
|
|
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
|
|
}
|
|
|
|
nsIAtom*
|
|
nsCanvasFrame::GetType() const
|
|
{
|
|
return nsGkAtoms::canvasFrame;
|
|
}
|
|
|
|
nsresult
|
|
nsCanvasFrame::GetContentForEvent(WidgetEvent* aEvent,
|
|
nsIContent** aContent)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aContent);
|
|
nsresult rv = nsFrame::GetContentForEvent(aEvent,
|
|
aContent);
|
|
if (NS_FAILED(rv) || !*aContent) {
|
|
nsIFrame* kid = mFrames.FirstChild();
|
|
if (kid) {
|
|
rv = kid->GetContentForEvent(aEvent,
|
|
aContent);
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
#ifdef DEBUG_FRAME_DUMP
|
|
nsresult
|
|
nsCanvasFrame::GetFrameName(nsAString& aResult) const
|
|
{
|
|
return MakeFrameName(NS_LITERAL_STRING("Canvas"), aResult);
|
|
}
|
|
#endif
|