Bug 875674 part.4 Implement firstRectForCharacterRange:actualRange: of NSTextInputClient r=roc+smichaud

This commit is contained in:
Masayuki Nakano 2013-07-11 16:46:35 +09:00
parent 47b3d4363e
commit e4cd688d65
5 changed files with 56 additions and 12 deletions

View File

@ -372,8 +372,13 @@ nsContentEventHandler::SetRangeFromFlatTextOffset(
nsRange* aRange,
uint32_t aNativeOffset,
uint32_t aNativeLength,
bool aExpandToClusterBoundaries)
bool aExpandToClusterBoundaries,
uint32_t* aNewNativeOffset)
{
if (aNewNativeOffset) {
*aNewNativeOffset = aNativeOffset;
}
nsCOMPtr<nsIContentIterator> iter = NS_NewPreContentIterator();
nsresult rv = iter->Init(mRootContent);
NS_ENSURE_SUCCESS(rv, rv);
@ -404,8 +409,12 @@ nsContentEventHandler::SetRangeFromFlatTextOffset(
ConvertToXPOffset(content, aNativeOffset - nativeOffset) : 0;
if (aExpandToClusterBoundaries) {
uint32_t oldXPOffset = xpOffset;
rv = ExpandToClusterBoundary(content, false, &xpOffset);
NS_ENSURE_SUCCESS(rv, rv);
if (aNewNativeOffset) {
*aNewNativeOffset -= (oldXPOffset - xpOffset);
}
}
rv = aRange->SetStart(domNode, int32_t(xpOffset));
@ -456,6 +465,9 @@ nsContentEventHandler::SetRangeFromFlatTextOffset(
MOZ_ASSERT(!mRootContent->IsNodeOfType(nsINode::eTEXT));
rv = aRange->SetStart(domNode, int32_t(mRootContent->GetChildCount()));
NS_ENSURE_SUCCESS(rv, rv);
if (aNewNativeOffset) {
*aNewNativeOffset = nativeOffset;
}
}
rv = aRange->SetEnd(domNode, int32_t(mRootContent->GetChildCount()));
NS_ASSERTION(NS_SUCCEEDED(rv), "nsIDOMRange::SetEnd failed");
@ -574,7 +586,10 @@ nsContentEventHandler::OnQueryTextRect(nsQueryContentEvent* aEvent)
nsRefPtr<nsRange> range = new nsRange(mRootContent);
rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset,
aEvent->mInput.mLength, true);
aEvent->mInput.mLength, true,
&aEvent->mReply.mOffset);
NS_ENSURE_SUCCESS(rv, rv);
rv = GenerateFlatTextContent(range, aEvent->mReply.mString);
NS_ENSURE_SUCCESS(rv, rv);
// used to iterate over all contents and their frames
@ -717,6 +732,7 @@ nsContentEventHandler::OnQueryCaretRect(nsQueryContentEvent* aEvent)
NS_ENSURE_SUCCESS(rv, rv);
aEvent->mReply.mRect =
rect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel());
aEvent->mReply.mOffset = aEvent->mInput.mOffset;
aEvent->mSucceeded = true;
return NS_OK;
}
@ -724,7 +740,8 @@ nsContentEventHandler::OnQueryCaretRect(nsQueryContentEvent* aEvent)
// Otherwise, we should set the guessed caret rect.
nsRefPtr<nsRange> range = new nsRange(mRootContent);
rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset, 0, true);
rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset, 0, true,
&aEvent->mReply.mOffset);
NS_ENSURE_SUCCESS(rv, rv);
int32_t offsetInFrame;

View File

@ -91,7 +91,8 @@ protected:
nsresult SetRangeFromFlatTextOffset(nsRange* aRange,
uint32_t aNativeOffset,
uint32_t aNativeLength,
bool aExpandToClusterBoundaries);
bool aExpandToClusterBoundaries,
uint32_t* aNewNativeOffset = nullptr);
// Find the first textframe for the range, and get the start offset in
// the frame.
nsresult GetStartFrameAndOffset(nsRange* aRange,

View File

@ -874,12 +874,15 @@ public:
* @param aRange A range of text to examine. Its position is
* an offset from the beginning of the focused
* editor or document.
* @param aActualRange If this is not null, this returns the actual
* range used for computing the result.
* @return An NSRect containing the first character in
* aRange, in screen coordinates.
* If the length of aRange is 0, the width will
* be 0.
*/
NSRect FirstRectForCharacterRange(NSRange& aRange);
NSRect FirstRectForCharacterRange(NSRange& aRange,
NSRange* aActualRange = nullptr);
/**
* CharacterIndexForPoint() returns an offset of a character at aPoint.

View File

@ -2893,20 +2893,26 @@ IMEInputHandler::SelectedRange()
}
NSRect
IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange,
NSRange* aActualRange)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p IMEInputHandler::FirstRectForCharacterRange, Destroyed()=%s"
"aRange={ location=%llu, length=%llu }",
this, TrueOrFalse(Destroyed()), aRange.location, aRange.length));
("%p IMEInputHandler::FirstRectForCharacterRange, Destroyed()=%s, "
"aRange={ location=%llu, length=%llu }, aActualRange=%p }",
this, TrueOrFalse(Destroyed()), aRange.location, aRange.length,
aActualRange));
// XXX this returns first character rect or caret rect, it is limitation of
// now. We need more work for returns first line rect. But current
// implementation is enough for IMEs.
NSRect rect;
NSRect rect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
NSRange actualRange = NSMakeRange(NSNotFound, 0);
if (aActualRange) {
*aActualRange = actualRange;
}
if (Destroyed() || aRange.location == NSNotFound) {
return rect;
}
@ -2921,6 +2927,8 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
DispatchEvent(charRect);
if (charRect.mSucceeded) {
r = charRect.mReply.mRect;
actualRange.location = charRect.mReply.mOffset;
actualRange.length = charRect.mReply.mString.Length();
} else {
useCaretRect = true;
}
@ -2935,6 +2943,8 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
}
r = caretRect.mReply.mRect;
r.width = 0;
actualRange.location = caretRect.mReply.mOffset;
actualRange.length = 0;
}
nsIWidget* rootWidget = mWidget->GetTopLevelWidget();
@ -2949,11 +2959,17 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange)
rect = [rootView convertRect:rect toView:nil];
rect.origin = [rootWindow convertBaseToScreen:rect.origin];
if (aActualRange) {
*aActualRange = actualRange;
}
PR_LOG(gLog, PR_LOG_ALWAYS,
("%p IMEInputHandler::FirstRectForCharacterRange, "
"useCaretRect=%s rect={ x=%f, y=%f, width=%f, height=%f }",
"useCaretRect=%s rect={ x=%f, y=%f, width=%f, height=%f }, "
"actualRange={ location=%llu, length=%llu }",
this, TrueOrFalse(useCaretRect), rect.origin.x, rect.origin.y,
rect.size.width, rect.size.height));
rect.size.width, rect.size.height, actualRange.location,
actualRange.length));
return rect;

View File

@ -5095,6 +5095,13 @@ static int32_t RoundUp(double aDouble)
#pragma mark -
// NSTextInputClient implementation
- (NSRect)firstRectForCharacterRange:(NSRange)aRange
actualRange:(NSRangePointer)actualRange
{
NS_ENSURE_TRUE(mTextInputHandler, NSMakeRect(0.0, 0.0, 0.0, 0.0));
return mTextInputHandler->FirstRectForCharacterRange(aRange, actualRange);
}
- (NSInteger)windowLevel
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;