/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */
// Main header first: #include"SVGViewportFrame.h"
void SVGViewportFrame::PaintSVG(gfxContext& aContext, const gfxMatrix& aTransform,
imgDrawingParams& aImgParams) {
NS_ASSERTION(HasAnyStateBits(NS_FRAME_IS_NONDISPLAY), "Only painting of non-display SVG should take this code path");
gfxClipAutoSaveRestore autoSaveClip(&aContext);
if (StyleDisplay()->IsScrollableOverflow()) { float x, y, width, height; static_cast<SVGViewportElement*>(GetContent())
->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
void SVGViewportFrame::ReflowSVG() { // mRect must be set before FinishAndStoreOverflow is called in order // for our overflow areas to be clipped correctly. float x, y, width, height; static_cast<SVGViewportElement*>(GetContent())
->GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
mRect = nsLayoutUtils::RoundGfxRectToAppRect(gfxRect(x, y, width, height),
AppUnitsPerCSSPixel());
// If we have a filter, we need to invalidate ourselves because filter // output can change even if none of our descendants need repainting. if (StyleEffects()->HasFilters()) {
InvalidateFrame();
}
SVGDisplayContainerFrame::ReflowSVG();
}
void SVGViewportFrame::NotifySVGChanged(uint32_t aFlags) {
MOZ_ASSERT(aFlags & (TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED), "Invalidation logic may need adjusting");
if (aFlags & COORD_CONTEXT_CHANGED) {
SVGViewportElement* svg = static_cast<SVGViewportElement*>(GetContent());
if (xOrYIsPercentage || widthOrHeightIsPercentage) { // Ancestor changes can't affect how we render from the perspective of // any rendering observers that we may have, so we don't need to // invalidate them. We also don't need to invalidate ourself, since our // changed ancestor will have invalidated its entire area, which includes // our area. // For perf reasons we call this before calling NotifySVGChanged() below.
SVGUtils::ScheduleReflowSVG(this);
}
// Coordinate context changes affect mCanvasTM if we have a // percentage 'x' or 'y', or if we have a percentage 'width' or 'height' AND // a 'viewBox'.
if (svg->HasViewBox() || !widthOrHeightIsPercentage) { // Remove COORD_CONTEXT_CHANGED, since we establish the coordinate // context for our descendants and this notification won't change its // dimensions:
aFlags &= ~COORD_CONTEXT_CHANGED;
if (!aFlags) { return; // No notification flags left
}
}
}
SVGBBox SVGViewportFrame::GetBBoxContribution(const Matrix& aToBBoxUserspace,
uint32_t aFlags) { // XXXjwatt It seems like authors would want the result to be clipped by the // viewport we establish if IsScrollableOverflow() is true. We should // consider doing that. See bug 1350755.
SVGBBox bbox;
if (aFlags & SVGUtils::eForGetClientRects) { // XXXjwatt For consistency with the old code this code includes the // viewport we establish in the result, but only includes the bounds of our // descendants if they are not clipped to that viewport. However, this is // both inconsistent with Chrome and with the specs. See bug 1350755. // Ideally getClientRects/getBoundingClientRect should be consistent with // getBBox. float x, y, w, h; static_cast<SVGViewportElement*>(GetContent())
->GetAnimatedLengthValues(&x, &y, &w, &h, nullptr); if (w < 0.0f) {
w = 0.0f;
} if (h < 0.0f) {
h = 0.0f;
}
Rect viewport(x, y, w, h);
bbox = aToBBoxUserspace.TransformBounds(viewport); if (StyleDisplay()->IsScrollableOverflow()) { return bbox;
} // Else we're not clipping to our viewport so we fall through and include // the bounds of our children.
}
if (aAttribute == nsGkAtoms::x || aAttribute == nsGkAtoms::y) {
nsLayoutUtils::PostRestyleEvent(
mContent->AsElement(), RestyleHint{0},
nsChangeHint_InvalidateRenderingObservers);
SVGUtils::ScheduleReflowSVG(this);
} elseif (aAttribute == nsGkAtoms::viewBox ||
(aAttribute == nsGkAtoms::preserveAspectRatio &&
content->HasViewBoxOrSyntheticViewBox())) {
content->ChildrenOnlyTransformChanged(); // SchedulePaint sets a global state flag so we only need to call it // once (on ourself is fine), not once on each child (despite bug // 828240).
SchedulePaint();
}
}
}
return NS_OK;
}
nsIFrame* SVGViewportFrame::GetFrameForPoint(const gfxPoint& aPoint) {
MOZ_ASSERT_UNREACHABLE("A clipPath cannot contain svg or symbol elements"); return nullptr;
}
void SVGViewportFrame::NotifyViewportOrTransformChanged(uint32_t aFlags) { // The dimensions of inner-<svg> frames are purely defined by their "width" // and "height" attributes, and transform changes can only occur as a result // of changes to their "width", "height", "viewBox" or "preserveAspectRatio" // attributes. Changes to all of these attributes are handled in // AttributeChanged(), so we should never be called.
NS_ERROR("Not called for SVGViewportFrame");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.