зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1820029: Inline HyperTextAccessible::TextBounds to TextLeafPoint::CharBounds r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D171503
This commit is contained in:
Родитель
f77b49974e
Коммит
60f92a62cb
|
@ -17,6 +17,7 @@
|
|||
#include "mozilla/dom/CharacterData.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/HTMLInputElement.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/intl/Segmenter.h"
|
||||
#include "mozilla/intl/WordBreaker.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
|
@ -1462,6 +1463,55 @@ TextLeafPoint TextLeafPoint::NeighborLeafPoint(
|
|||
: 0);
|
||||
}
|
||||
|
||||
LayoutDeviceIntRect TextLeafPoint::ComputeBoundsFromFrame() const {
|
||||
LocalAccessible* local = mAcc->AsLocal();
|
||||
MOZ_ASSERT(local, "Can't compute bounds in frame from non-local acc");
|
||||
nsIFrame* frame = local->GetFrame();
|
||||
MOZ_ASSERT(frame, "No frame found for acc!");
|
||||
|
||||
if (!frame->IsTextFrame()) {
|
||||
return local->Bounds();
|
||||
}
|
||||
|
||||
// Substring must be entirely within the same text node.
|
||||
MOZ_ASSERT(frame->IsPrimaryFrame(),
|
||||
"Cannot compute content offset on non-primary frame");
|
||||
nsIFrame::RenderedText text = frame->GetRenderedText(
|
||||
mOffset, mOffset + 1, nsIFrame::TextOffsetType::OffsetsInRenderedText,
|
||||
nsIFrame::TrailingWhitespace::DontTrim);
|
||||
int32_t contentOffset = text.mOffsetWithinNodeText;
|
||||
int32_t contentOffsetInFrame;
|
||||
// Get the right frame continuation -- not really a child, but a sibling of
|
||||
// the primary frame passed in
|
||||
nsresult rv = frame->GetChildFrameContainingOffset(
|
||||
contentOffset, false, &contentOffsetInFrame, &frame);
|
||||
NS_ENSURE_SUCCESS(rv, LayoutDeviceIntRect());
|
||||
|
||||
// Start with this frame's screen rect, which we will shrink based on
|
||||
// the char we care about within it.
|
||||
nsRect frameScreenRect = frame->GetScreenRectInAppUnits();
|
||||
|
||||
// Add the point where the char starts to the frameScreenRect
|
||||
nsPoint frameTextStartPoint;
|
||||
rv = frame->GetPointFromOffset(contentOffset, &frameTextStartPoint);
|
||||
NS_ENSURE_SUCCESS(rv, LayoutDeviceIntRect());
|
||||
|
||||
// Use the next offset to calculate the width
|
||||
// XXX(morgan) does this work for vertical text?
|
||||
nsPoint frameTextEndPoint;
|
||||
rv = frame->GetPointFromOffset(contentOffset + 1, &frameTextEndPoint);
|
||||
NS_ENSURE_SUCCESS(rv, LayoutDeviceIntRect());
|
||||
|
||||
frameScreenRect.SetRectX(
|
||||
frameScreenRect.X() +
|
||||
std::min(frameTextStartPoint.x, frameTextEndPoint.x),
|
||||
mozilla::Abs(frameTextStartPoint.x - frameTextEndPoint.x));
|
||||
|
||||
nsPresContext* presContext = local->Document()->PresContext();
|
||||
return LayoutDeviceIntRect::FromAppUnitsToNearest(
|
||||
frameScreenRect, presContext->AppUnitsPerDevPixel());
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsTArray<int32_t> TextLeafPoint::GetSpellingErrorOffsets(
|
||||
LocalAccessible* aAcc) {
|
||||
|
@ -1660,11 +1710,32 @@ LayoutDeviceIntRect TextLeafPoint::CharBounds() {
|
|||
}
|
||||
|
||||
if (LocalAccessible* local = mAcc->AsLocal()) {
|
||||
HyperTextAccessible* ht = HyperTextFor(local);
|
||||
MOZ_ASSERT(ht, "Could not find hypertext for text acc?");
|
||||
return ht->CharBounds(
|
||||
static_cast<int32_t>(ht->TransformOffset(local, mOffset, true)),
|
||||
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
|
||||
if (!local->IsTextLeaf() || nsAccUtils::TextLength(local) == 0) {
|
||||
// Empty content, use our own bounds to at least get x,y coordinates
|
||||
return local->Bounds();
|
||||
}
|
||||
|
||||
if (mOffset >= 0 &&
|
||||
static_cast<uint32_t>(mOffset) > nsAccUtils::TextLength(local)) {
|
||||
NS_ERROR("Wrong in offset");
|
||||
return LayoutDeviceIntRect();
|
||||
}
|
||||
|
||||
LayoutDeviceIntRect bounds = ComputeBoundsFromFrame();
|
||||
|
||||
// This document may have a resolution set, we will need to multiply
|
||||
// the document-relative coordinates by that value and re-apply the doc's
|
||||
// screen coordinates.
|
||||
nsPresContext* presContext = local->Document()->PresContext();
|
||||
nsIFrame* rootFrame = presContext->PresShell()->GetRootFrame();
|
||||
LayoutDeviceIntRect orgRectPixels =
|
||||
LayoutDeviceIntRect::FromAppUnitsToNearest(
|
||||
rootFrame->GetScreenRectInAppUnits(),
|
||||
presContext->AppUnitsPerDevPixel());
|
||||
bounds.MoveBy(-orgRectPixels.X(), -orgRectPixels.Y());
|
||||
bounds.ScaleRoundOut(presContext->PresShell()->GetResolution());
|
||||
bounds.MoveBy(orgRectPixels.X(), orgRectPixels.Y());
|
||||
return bounds;
|
||||
}
|
||||
|
||||
RemoteAccessible* remote = mAcc->AsRemote();
|
||||
|
|
|
@ -236,6 +236,15 @@ class TextLeafPoint final {
|
|||
// on given direction.
|
||||
TextLeafPoint NeighborLeafPoint(nsDirection aDirection, bool aIsEditable,
|
||||
bool aIgnoreListItemMarker) const;
|
||||
|
||||
/**
|
||||
* This function assumes mAcc is a LocalAccessible.
|
||||
* It iterates the continuations of mAcc's primary frame until it locates
|
||||
* the continuation containing mOffset (a rendered offset). It then uses
|
||||
* GetScreenRectInAppUnits to compute screen coords for the frame, resizing
|
||||
* such that the resulting rect contains only one character.
|
||||
*/
|
||||
LayoutDeviceIntRect ComputeBoundsFromFrame() const;
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(TextLeafPoint::BoundaryFlags)
|
||||
|
|
Загрузка…
Ссылка в новой задаче