Skip to content

Commit

Permalink
Bug 1203871 - Part 2. Implement eQueryTextRectArray. r=masayuki
Browse files Browse the repository at this point in the history
It will use on ContentCache.  Also, SetRangeFromFlatTextOffset issue will hanle on another bug.

MozReview-Commit-ID: 9Yu8bLlcZS5
  • Loading branch information
makotokato committed Jun 23, 2016
1 parent aa1740d commit f72ef5e
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 0 deletions.
81 changes: 81 additions & 0 deletions dom/events/ContentEventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,8 @@ ContentEventHandler::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
return OnQueryCaretRect(aEvent);
case eQueryTextRect:
return OnQueryTextRect(aEvent);
case eQueryTextRectArray:
return OnQueryTextRectArray(aEvent);
case eQueryEditorRect:
return OnQueryEditorRect(aEvent);
case eQueryContentState:
Expand Down Expand Up @@ -1393,6 +1395,85 @@ static nsINode* AdjustTextRectNode(nsINode* aNode,
return node;
}

static
nsIFrame*
GetFirstFrameInRange(nsRange* aRange)
{
// used to iterate over all contents and their frames
nsCOMPtr<nsIContentIterator> iter = NS_NewContentIterator();
iter->Init(aRange);

// get the starting frame
int32_t nodeOffset = aRange->StartOffset();
nsINode* node = iter->GetCurrentNode();
if (!node) {
node = AdjustTextRectNode(aRange->GetStartParent(), nodeOffset);
}
nsIFrame* firstFrame = nullptr;
GetFrameForTextRect(node, nodeOffset, true, &firstFrame);
return firstFrame;
}

nsresult
ContentEventHandler::OnQueryTextRectArray(WidgetQueryContentEvent* aEvent)
{
nsresult rv = Init(aEvent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

LineBreakType lineBreakType = GetLineBreakType(aEvent);
RefPtr<nsRange> range = new nsRange(mRootContent);
uint32_t offset = aEvent->mInput.mOffset;

LayoutDeviceIntRect rect;
WritingMode writingMode;
while (aEvent->mInput.mLength > aEvent->mReply.mRectArray.Length()) {
rv = SetRangeFromFlatTextOffset(range, offset, 1, lineBreakType, true,
nullptr);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

// get the starting frame
nsIFrame* firstFrame = GetFirstFrameInRange(range);
if (NS_WARN_IF(!firstFrame)) {
return NS_ERROR_FAILURE;
}

// get the starting frame rect
nsRect frameRect(nsPoint(0, 0), firstFrame->GetRect().Size());
rv = ConvertToRootRelativeOffset(firstFrame, frameRect);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

int32_t nodeOffset = range->StartOffset();
AutoTArray<nsRect, 16> charRects;
rv = firstFrame->GetCharacterRectsInRange(
nodeOffset,
aEvent->mInput.mLength - aEvent->mReply.mRectArray.Length(),
charRects);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

for (size_t i = 0; i < charRects.Length(); i++) {
nsRect charRect = charRects[i];
charRect.x += frameRect.x;
charRect.y += frameRect.y;

rect = LayoutDeviceIntRect::FromUnknownRect(
charRect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));

aEvent->mReply.mRectArray.AppendElement(rect);
}
offset += charRects.Length();
}
aEvent->mSucceeded = true;
return NS_OK;
}

nsresult
ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
{
Expand Down
5 changes: 5 additions & 0 deletions dom/events/ContentEventHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class MOZ_STACK_CLASS ContentEventHandler
nsresult OnQueryCaretRect(WidgetQueryContentEvent* aEvent);
// eQueryTextRect event handler
nsresult OnQueryTextRect(WidgetQueryContentEvent* aEvent);
// eQueryTextRectArray event handler
nsresult OnQueryTextRectArray(WidgetQueryContentEvent* aEvent);
// eQueryEditorRect event handler
nsresult OnQueryEditorRect(WidgetQueryContentEvent* aEvent);
// eQueryContentState event handler
Expand Down Expand Up @@ -299,6 +301,9 @@ class MOZ_STACK_CLASS ContentEventHandler
FontRangeArray& aFontRanges,
uint32_t& aLength,
LineBreakType aLineBreakType);
nsresult QueryTextRectByRange(nsRange* aRange,
LayoutDeviceIntRect& aRect,
WritingMode& aWritingMode);
};

} // namespace mozilla
Expand Down
1 change: 1 addition & 0 deletions dom/events/EventStateManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,7 @@ EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
case eQuerySelectionAsTransferable:
case eQueryCharacterAtPoint:
case eQueryDOMWidgetHittest:
case eQueryTextRectArray:
break;
default:
return;
Expand Down
3 changes: 3 additions & 0 deletions widget/EventMessageList.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ NS_EVENT_MESSAGE(eQueryCaretRect)
// valid character range given offset and length. Result is relative to top
// level widget coordinates
NS_EVENT_MESSAGE(eQueryTextRect)
// Query for the bounding rect array of a range of characters.
// Thiis similar event of eQueryTextRect.
NS_EVENT_MESSAGE(eQueryTextRectArray)
// Query for the bounding rect of the current focused frame. Result is relative
// to top level widget coordinates
NS_EVENT_MESSAGE(eQueryEditorRect)
Expand Down
12 changes: 12 additions & 0 deletions widget/TextEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,16 @@ class WidgetQueryContentEvent : public WidgetGUIEvent
mRefPoint = aPoint;
}

void InitForQueryTextRectArray(uint32_t aOffset, uint32_t aLength,
const Options& aOptions = Options())
{
NS_ASSERTION(mMessage == eQueryTextRectArray,
"wrong initializer is called");
mInput.mOffset = aOffset;
mInput.mLength = aLength;
Init(aOptions);
}

void RequestFontRanges()
{
NS_ASSERTION(mMessage == eQueryTextContent,
Expand Down Expand Up @@ -833,6 +843,8 @@ class WidgetQueryContentEvent : public WidgetGUIEvent
nsCOMPtr<nsITransferable> mTransferable;
// Used by eQueryTextContent with font ranges requested
AutoTArray<mozilla::FontRange, 1> mFontRanges;
// Used by eQueryTextRectArray
nsTArray<mozilla::LayoutDeviceIntRect> mRectArray;
// true if selection is reversed (end < start)
bool mReversed;
// true if the selection exists
Expand Down

0 comments on commit f72ef5e

Please sign in to comment.