mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 917755. Part 1: Add nsLayoutUtils::TransformCSSPoints and nsLayoutUtils::GetFirstNonAnonymousFrame. r=matspal
--HG-- extra : rebase_source : 06e2c83a984d12fce29cd23b93dde54a2e05cf43
This commit is contained in:
parent
3edac283b7
commit
242ffba63c
@ -1893,6 +1893,66 @@ nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncesto
|
||||
return ctm;
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2)
|
||||
{
|
||||
nsAutoTArray<nsIFrame*,100> ancestors1;
|
||||
nsAutoTArray<nsIFrame*,100> ancestors2;
|
||||
nsIFrame* commonAncestor = nullptr;
|
||||
if (aFrame1->PresContext() == aFrame2->PresContext()) {
|
||||
commonAncestor = aFrame1->PresContext()->PresShell()->GetRootFrame();
|
||||
}
|
||||
for (nsIFrame* f = aFrame1; f != commonAncestor;
|
||||
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
||||
ancestors1.AppendElement(f);
|
||||
}
|
||||
for (nsIFrame* f = aFrame2; f != commonAncestor;
|
||||
f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
|
||||
ancestors2.AppendElement(f);
|
||||
}
|
||||
uint32_t minLengths = std::min(ancestors1.Length(), ancestors2.Length());
|
||||
for (uint32_t i = 1; i <= minLengths; ++i) {
|
||||
if (ancestors1[ancestors1.Length() - i] == ancestors2[ancestors2.Length() - i]) {
|
||||
commonAncestor = ancestors1[ancestors1.Length() - i];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return commonAncestor;
|
||||
}
|
||||
|
||||
nsLayoutUtils::TransformResult
|
||||
nsLayoutUtils::TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame,
|
||||
uint32_t aPointCount, CSSPoint* aPoints)
|
||||
{
|
||||
nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame);
|
||||
if (!nearestCommonAncestor) {
|
||||
return NO_COMMON_ANCESTOR;
|
||||
}
|
||||
gfx3DMatrix downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor);
|
||||
if (downToDest.IsSingular()) {
|
||||
return NONINVERTIBLE_TRANSFORM;
|
||||
}
|
||||
downToDest.Invert();
|
||||
gfx3DMatrix upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor);
|
||||
CSSToLayoutDeviceScale devPixelsPerCSSPixelFromFrame(
|
||||
double(nsPresContext::AppUnitsPerCSSPixel())/
|
||||
aFromFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame(
|
||||
double(nsPresContext::AppUnitsPerCSSPixel())/
|
||||
aToFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
for (uint32_t i = 0; i < aPointCount; ++i) {
|
||||
LayoutDevicePoint devPixels = aPoints[i] * devPixelsPerCSSPixelFromFrame;
|
||||
gfxPoint toDevPixels = downToDest.ProjectPoint(
|
||||
upToAncestor.ProjectPoint(gfxPoint(devPixels.x, devPixels.y)));
|
||||
// Divide here so that when the devPixelsPerCSSPixels are the same, we get the correct
|
||||
// answer instead of some inaccuracy multiplying a number by its reciprocal.
|
||||
aPoints[i] = LayoutDevicePoint(toDevPixels.x, toDevPixels.y) /
|
||||
devPixelsPerCSSPixelToFrame;
|
||||
}
|
||||
return TRANSFORM_SUCCEEDED;
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
|
||||
gfx3DMatrix* aTransform)
|
||||
@ -2586,6 +2646,43 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback)
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame)
|
||||
{
|
||||
while (aFrame) {
|
||||
nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo();
|
||||
|
||||
if (pseudoType == nsCSSAnonBoxes::tableOuter) {
|
||||
nsIFrame* f = GetFirstNonAnonymousFrame(aFrame->GetFirstPrincipalChild());
|
||||
if (f) {
|
||||
return f;
|
||||
}
|
||||
nsIFrame* kid = aFrame->GetFirstChild(nsIFrame::kCaptionList);
|
||||
if (kid) {
|
||||
f = GetFirstNonAnonymousFrame(kid);
|
||||
if (f) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
} else if (pseudoType == nsCSSAnonBoxes::mozAnonymousBlock ||
|
||||
pseudoType == nsCSSAnonBoxes::mozAnonymousPositionedBlock ||
|
||||
pseudoType == nsCSSAnonBoxes::mozMathMLAnonymousBlock ||
|
||||
pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock) {
|
||||
for (nsIFrame* kid = aFrame->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) {
|
||||
nsIFrame* f = GetFirstNonAnonymousFrame(kid);
|
||||
if (f) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return aFrame;
|
||||
}
|
||||
|
||||
aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct BoxToRect : public nsLayoutUtils::BoxCallback {
|
||||
nsIFrame* mRelativeTo;
|
||||
nsLayoutUtils::RectCallback* mCallback;
|
||||
|
@ -6,6 +6,29 @@
|
||||
#ifndef nsLayoutUtils_h__
|
||||
#define nsLayoutUtils_h__
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "GraphicsFilter.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "FrameMetrics.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsCSSProperty.h"
|
||||
#include "nsStyleCoord.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsRuleNode.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "Units.h"
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
class nsIFormControlFrame;
|
||||
class nsPresContext;
|
||||
class nsIContent;
|
||||
@ -30,32 +53,11 @@ class gfxContext;
|
||||
class nsPIDOMWindow;
|
||||
class imgIRequest;
|
||||
class nsIDocument;
|
||||
class gfxPoint;
|
||||
struct nsStyleFont;
|
||||
struct nsStyleImageOrientation;
|
||||
struct nsOverflowAreas;
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "GraphicsFilter.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "FrameMetrics.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsCSSProperty.h"
|
||||
#include "nsStyleCoord.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsRuleNode.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace mozilla {
|
||||
class SVGImageContext;
|
||||
struct IntrinsicSize;
|
||||
@ -107,6 +109,7 @@ class nsLayoutUtils
|
||||
public:
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
typedef FrameMetrics::ViewID ViewID;
|
||||
typedef mozilla::CSSPoint CSSPoint;
|
||||
|
||||
/**
|
||||
* Finds previously assigned ViewID for the given content element, if any.
|
||||
@ -683,6 +686,24 @@ public:
|
||||
*/
|
||||
static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor);
|
||||
|
||||
/**
|
||||
* Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
|
||||
* account all relevant transformations on the frames up to (but excluding)
|
||||
* their nearest common ancestor.
|
||||
* If we encounter a transform that we need to invert but which is
|
||||
* non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have
|
||||
* no common ancestor, we return NO_COMMON_ANCESTOR.
|
||||
* If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed
|
||||
* in-place, otherwise they are untouched.
|
||||
*/
|
||||
enum TransformResult {
|
||||
TRANSFORM_SUCCEEDED,
|
||||
NO_COMMON_ANCESTOR,
|
||||
NONINVERTIBLE_TRANSFORM
|
||||
};
|
||||
static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame,
|
||||
uint32_t aPointCount, CSSPoint* aPoints);
|
||||
|
||||
/**
|
||||
* Return true if a "layer transform" could be computed for aFrame,
|
||||
* and optionally return the computed transform. The returned
|
||||
@ -877,6 +898,12 @@ public:
|
||||
*/
|
||||
static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
|
||||
|
||||
/**
|
||||
* Find the first frame descendant of aFrame (including aFrame) which is
|
||||
* not an anonymous frame that getBoxQuads/getClientRects should ignore.
|
||||
*/
|
||||
static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame);
|
||||
|
||||
class RectCallback {
|
||||
public:
|
||||
virtual void AddRect(const nsRect& aRect) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user