mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1048752. Part 19: Create nsCaret::GetPaintGeometry to call during painting. r=tn
This is the start of the changes to caret-drawing proper. The idea is to combine GetCaretFrame and GetCaretRect into a method GetPaintGeometry which looks like GetGeometry but returns values needed for painting (i.e. including bidi decorations, and returning a null frame if we're not supposed to paint due to specific caret state, e.g. in the "off" phase of the blink cycle). Mostly a straightforward refactoring but there are a few interesting changes: -- nsDisplayCaret stores its bounds instead of getting them from nsCaret on demand. Eventually those bounds will not be stored in nsCaret at all. -- nsDisplayCaret::GetBounds returns true for aSnap. nsCaret draws snapped rects, so why not. -- I removed "if (caretRect.Intersects(aDirtyRect))" in EnterPresShell. As far as I can tell, this check is incorrect because it doesn't take transforms into account. Since there's at most one drawn caret per window, hence we do this at most once per paint, I don't think there's any real performance advantage to having this check. --HG-- extra : rebase_source : c98d3a5994478b482d19cc2e2ac83ab51bd17e00
This commit is contained in:
parent
1b1473f94c
commit
27a3fe0069
@ -476,6 +476,13 @@ nsIFrame * nsCaret::GetCaretFrame(int32_t *aOffset)
|
||||
return frame;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCaret::GetPaintGeometry(nsRect* aRect)
|
||||
{
|
||||
aRect->UnionRect(mCaretRect, GetHookRect());
|
||||
return GetCaretFrame();
|
||||
}
|
||||
|
||||
void nsCaret::UpdateCaretPosition()
|
||||
{
|
||||
// We'll recalculate anyway if we're not drawn right now.
|
||||
|
@ -113,17 +113,14 @@ class nsCaret : public nsISelectionListener
|
||||
* @param aOffset is result of the caret offset in the content.
|
||||
*/
|
||||
nsIFrame* GetCaretFrame(int32_t *aOffset = nullptr);
|
||||
/** GetCaretRect
|
||||
* Get the current caret rect. Only call this when GetCaretFrame returns
|
||||
* non-null.
|
||||
* This rect includes any extra decorations for bidi.
|
||||
/**
|
||||
* Returns a frame to paint in, and the bounds of the painted caret
|
||||
* relative to that frame.
|
||||
* The rectangle includes bidi decorations.
|
||||
* Returns null if the caret should not be drawn (including if it's blinked
|
||||
* off).
|
||||
*/
|
||||
nsRect GetCaretRect()
|
||||
{
|
||||
nsRect r;
|
||||
r.UnionRect(mCaretRect, GetHookRect());
|
||||
return r;
|
||||
}
|
||||
nsIFrame* GetPaintGeometry(nsRect* aRect);
|
||||
/**
|
||||
* A simple wrapper around GetGeometry. Does not take any caret state into
|
||||
* account other than the current selection.
|
||||
|
@ -942,19 +942,10 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
|
||||
return;
|
||||
|
||||
nsRefPtr<nsCaret> caret = state->mPresShell->GetCaret();
|
||||
state->mCaretFrame = caret->GetCaretFrame();
|
||||
NS_ASSERTION(state->mCaretFrame == caret->GetCaretFrame(),
|
||||
"GetCaretFrame() is unstable");
|
||||
|
||||
state->mCaretFrame = caret->GetPaintGeometry(&state->mCaretRect);
|
||||
if (state->mCaretFrame) {
|
||||
// Check if the dirty rect intersects with the caret's dirty rect.
|
||||
nsRect caretRect =
|
||||
caret->GetCaretRect() + state->mCaretFrame->GetOffsetTo(aReferenceFrame);
|
||||
if (caretRect.Intersects(aDirtyRect)) {
|
||||
// Okay, our rects intersect, let's mark the frame and all of its ancestors.
|
||||
mFramesMarkedForDisplay.AppendElement(state->mCaretFrame);
|
||||
MarkFrameForDisplay(state->mCaretFrame, nullptr);
|
||||
}
|
||||
mFramesMarkedForDisplay.AppendElement(state->mCaretFrame);
|
||||
MarkFrameForDisplay(state->mCaretFrame, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2743,10 +2734,10 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
nsDisplayCaret::nsDisplayCaret(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aCaretFrame,
|
||||
nsCaret *aCaret)
|
||||
nsIFrame* aCaretFrame)
|
||||
: nsDisplayItem(aBuilder, aCaretFrame)
|
||||
, mCaret(aCaret)
|
||||
, mCaret(aBuilder->GetCaret())
|
||||
, mBounds(aBuilder->GetCaretRect() + ToReferenceFrame())
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayCaret);
|
||||
}
|
||||
@ -2761,9 +2752,9 @@ nsDisplayCaret::~nsDisplayCaret()
|
||||
nsRect
|
||||
nsDisplayCaret::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
||||
{
|
||||
*aSnap = false;
|
||||
*aSnap = true;
|
||||
// The caret returns a rect in the coordinates of mFrame.
|
||||
return mCaret->GetCaretRect() + ToReferenceFrame();
|
||||
return mBounds;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -353,6 +353,12 @@ public:
|
||||
nsIFrame* GetCaretFrame() {
|
||||
return CurrentPresShellState()->mCaretFrame;
|
||||
}
|
||||
/**
|
||||
* Get the rectangle we're supposed to draw the caret into.
|
||||
*/
|
||||
const nsRect& GetCaretRect() {
|
||||
return CurrentPresShellState()->mCaretRect;
|
||||
}
|
||||
/**
|
||||
* Get the caret associated with the current presshell.
|
||||
*/
|
||||
@ -703,6 +709,7 @@ private:
|
||||
struct PresShellState {
|
||||
nsIPresShell* mPresShell;
|
||||
nsIFrame* mCaretFrame;
|
||||
nsRect mCaretRect;
|
||||
nsRect mPrevDirtyRect;
|
||||
uint32_t mFirstFrameMarkedForDisplay;
|
||||
bool mIsBackgroundOnly;
|
||||
@ -1951,8 +1958,7 @@ protected:
|
||||
|
||||
class nsDisplayCaret : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame,
|
||||
nsCaret *aCaret);
|
||||
nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame);
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayCaret();
|
||||
#endif
|
||||
@ -1962,6 +1968,7 @@ public:
|
||||
NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
|
||||
protected:
|
||||
nsRefPtr<nsCaret> mCaret;
|
||||
nsRect mBounds;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1553,8 +1553,7 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
|
||||
if (!IsVisibleForPainting(aBuilder))
|
||||
return;
|
||||
|
||||
aList->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayCaret(aBuilder, this, aBuilder->GetCaret()));
|
||||
aList->AppendNewToTop(new (aBuilder) nsDisplayCaret(aBuilder, this));
|
||||
}
|
||||
|
||||
nscolor
|
||||
|
@ -3640,7 +3640,8 @@ SVGTextFrame::PaintSVG(nsRenderingContext* aContext,
|
||||
gfxMatrix currentMatrix = gfx->CurrentMatrix();
|
||||
|
||||
nsRefPtr<nsCaret> caret = presContext->PresShell()->GetCaret();
|
||||
nsIFrame* caretFrame = caret->GetCaretFrame();
|
||||
nsRect caretRect;
|
||||
nsIFrame* caretFrame = caret->GetPaintGeometry(&caretRect);
|
||||
|
||||
TextRenderedRunIterator it(this, TextRenderedRunIterator::eVisibleFrames);
|
||||
TextRenderedRun run = it.Current();
|
||||
|
Loading…
Reference in New Issue
Block a user