зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1094056 - Use nsCaret::GetGeometryForFrame to determine position of selection carets. r=roc
This commit is contained in:
Родитель
179821a35d
Коммит
8733cb18e1
|
@ -377,19 +377,6 @@ IsRightToLeft(nsIFrame* aFrame)
|
|||
aFrame->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reduce rect to 1 css pixel width along either left or right edge base on
|
||||
* aToRightEdge parameter.
|
||||
*/
|
||||
static void
|
||||
ReduceRectToVerticalEdge(nsRect& aRect, bool aToRightEdge)
|
||||
{
|
||||
if (aToRightEdge) {
|
||||
aRect.x = aRect.XMost() - AppUnitsPerCSSPixel();
|
||||
}
|
||||
aRect.width = AppUnitsPerCSSPixel();
|
||||
}
|
||||
|
||||
static nsIFrame*
|
||||
FindFirstNodeWithFrame(nsIDocument* aDocument,
|
||||
nsRange* aRange,
|
||||
|
@ -472,16 +459,6 @@ SelectionCarets::UpdateSelectionCarets()
|
|||
nsRefPtr<nsRange> firstRange = selection->GetRangeAt(0);
|
||||
nsRefPtr<nsRange> lastRange = selection->GetRangeAt(rangeCount - 1);
|
||||
|
||||
nsLayoutUtils::FirstAndLastRectCollector collectorStart;
|
||||
nsRange::CollectClientRects(&collectorStart, firstRange,
|
||||
firstRange->GetStartParent(), firstRange->StartOffset(),
|
||||
firstRange->GetEndParent(), firstRange->EndOffset(), true, true);
|
||||
|
||||
nsLayoutUtils::FirstAndLastRectCollector collectorEnd;
|
||||
nsRange::CollectClientRects(&collectorEnd, lastRange,
|
||||
lastRange->GetStartParent(), lastRange->StartOffset(),
|
||||
lastRange->GetEndParent(), lastRange->EndOffset(), true, true);
|
||||
|
||||
nsIFrame* canvasFrame = mPresShell->GetCanvasFrame();
|
||||
nsIFrame* rootFrame = mPresShell->GetRootFrame();
|
||||
|
||||
|
@ -522,17 +499,29 @@ SelectionCarets::UpdateSelectionCarets()
|
|||
bool startFrameIsRTL = IsRightToLeft(startFrame);
|
||||
bool endFrameIsRTL = IsRightToLeft(endFrame);
|
||||
|
||||
// If start frame is LTR, then place start caret in first rect's leftmost
|
||||
// otherwise put it to first rect's rightmost.
|
||||
ReduceRectToVerticalEdge(collectorStart.mFirstRect, startFrameIsRTL);
|
||||
mPresShell->FlushPendingNotifications(Flush_Layout);
|
||||
nsRect firstRectInRootFrame =
|
||||
nsCaret::GetGeometryForFrame(startFrame, startOffset, nullptr);
|
||||
nsRect lastRectInRootFrame =
|
||||
nsCaret::GetGeometryForFrame(endFrame, endOffset, nullptr);
|
||||
|
||||
// Contrary to start frame, if end frame is LTR, put end caret to last
|
||||
// rect's rightmost position, otherwise, put it to last rect's leftmost.
|
||||
ReduceRectToVerticalEdge(collectorEnd.mLastRect, !endFrameIsRTL);
|
||||
// GetGeometryForFrame may return a rect that outside frame's rect. So
|
||||
// constrain rect inside frame's rect.
|
||||
firstRectInRootFrame = firstRectInRootFrame.ForceInside(startFrame->GetRectRelativeToSelf());
|
||||
lastRectInRootFrame = lastRectInRootFrame.ForceInside(endFrame->GetRectRelativeToSelf());
|
||||
nsRect firstRectInCanvasFrame = firstRectInRootFrame;
|
||||
nsRect lastRectInCanvasFrame =lastRectInRootFrame;
|
||||
nsLayoutUtils::TransformRect(startFrame, rootFrame, firstRectInRootFrame);
|
||||
nsLayoutUtils::TransformRect(endFrame, rootFrame, lastRectInRootFrame);
|
||||
nsLayoutUtils::TransformRect(startFrame, canvasFrame, firstRectInCanvasFrame);
|
||||
nsLayoutUtils::TransformRect(endFrame, canvasFrame, lastRectInCanvasFrame);
|
||||
|
||||
firstRectInRootFrame.Inflate(AppUnitsPerCSSPixel(), 0);
|
||||
lastRectInRootFrame.Inflate(AppUnitsPerCSSPixel(), 0);
|
||||
|
||||
nsAutoTArray<nsIFrame*, 16> hitFramesInFirstRect;
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame,
|
||||
collectorStart.mFirstRect,
|
||||
firstRectInRootFrame,
|
||||
hitFramesInFirstRect,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
|
||||
nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
|
@ -540,7 +529,7 @@ SelectionCarets::UpdateSelectionCarets()
|
|||
|
||||
nsAutoTArray<nsIFrame*, 16> hitFramesInLastRect;
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame,
|
||||
collectorEnd.mLastRect,
|
||||
lastRectInRootFrame,
|
||||
hitFramesInLastRect,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
|
||||
nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
|
@ -549,11 +538,8 @@ SelectionCarets::UpdateSelectionCarets()
|
|||
SetStartFrameVisibility(hitFramesInFirstRect.Contains(startFrame));
|
||||
SetEndFrameVisibility(hitFramesInLastRect.Contains(endFrame));
|
||||
|
||||
nsLayoutUtils::TransformRect(rootFrame, canvasFrame, collectorStart.mFirstRect);
|
||||
nsLayoutUtils::TransformRect(rootFrame, canvasFrame, collectorEnd.mLastRect);
|
||||
|
||||
SetStartFramePos(collectorStart.mFirstRect.BottomLeft());
|
||||
SetEndFramePos(collectorEnd.mLastRect.BottomRight());
|
||||
SetStartFramePos(firstRectInCanvasFrame.BottomLeft());
|
||||
SetEndFramePos(lastRectInCanvasFrame.BottomRight());
|
||||
SetVisibility(true);
|
||||
|
||||
// If range select only one character, append tilt class name to it.
|
||||
|
|
|
@ -149,6 +149,9 @@ class nsCaret MOZ_FINAL : public nsISelectionListener
|
|||
uint8_t aBidiLevel,
|
||||
nsIFrame** aReturnFrame,
|
||||
int32_t* aReturnOffset);
|
||||
static nsRect GetGeometryForFrame(nsIFrame* aFrame,
|
||||
int32_t aFrameOffset,
|
||||
nscoord* aBidiIndicatorSize);
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
|
@ -168,9 +171,6 @@ protected:
|
|||
};
|
||||
static Metrics ComputeMetrics(nsIFrame* aFrame, int32_t aOffset,
|
||||
nscoord aCaretHeight);
|
||||
static nsRect GetGeometryForFrame(nsIFrame* aFrame,
|
||||
int32_t aFrameOffset,
|
||||
nscoord* aBidiIndicatorSize);
|
||||
|
||||
void ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset,
|
||||
nsRect* aCaretRect, nsRect* aHookRect);
|
||||
|
|
|
@ -3400,20 +3400,6 @@ void nsLayoutUtils::RectListBuilder::AddRect(const nsRect& aRect) {
|
|||
mRectList->Append(rect);
|
||||
}
|
||||
|
||||
nsLayoutUtils::FirstAndLastRectCollector::FirstAndLastRectCollector()
|
||||
: mSeenFirstRect(false)
|
||||
{
|
||||
}
|
||||
|
||||
void nsLayoutUtils::FirstAndLastRectCollector::AddRect(const nsRect& aRect) {
|
||||
if (!mSeenFirstRect) {
|
||||
mSeenFirstRect = true;
|
||||
mFirstRect = aRect;
|
||||
}
|
||||
|
||||
mLastRect = aRect;
|
||||
}
|
||||
|
||||
nsIFrame* nsLayoutUtils::GetContainingBlockForClientRect(nsIFrame* aFrame)
|
||||
{
|
||||
return aFrame->PresContext()->PresShell()->GetRootFrame();
|
||||
|
|
|
@ -1026,21 +1026,6 @@ public:
|
|||
virtual void AddRect(const nsRect& aRect);
|
||||
};
|
||||
|
||||
/**
|
||||
* SelectionCaret draws carets base on range. The carets are at begin
|
||||
* and end position of range's client rects. This class help us to
|
||||
* collect first and last rect for drawing carets.
|
||||
*/
|
||||
struct FirstAndLastRectCollector : public RectCallback {
|
||||
nsRect mFirstRect;
|
||||
nsRect mLastRect;
|
||||
bool mSeenFirstRect;
|
||||
|
||||
FirstAndLastRectCollector();
|
||||
|
||||
virtual void AddRect(const nsRect& aRect);
|
||||
};
|
||||
|
||||
static nsIFrame* GetContainingBlockForClientRect(nsIFrame* aFrame);
|
||||
|
||||
enum {
|
||||
|
|
Загрузка…
Ссылка в новой задаче