Bug 1435989 - Add a 'ranges' attribute to the InspectorFontFace object, to expose ranges of text that were rendered with a specific font. r=bz,dholbert

This commit is contained in:
Jonathan Kew 2018-02-15 18:48:22 +00:00
parent 24e33e9a2b
commit 7a1f777b90
9 changed files with 88 additions and 24 deletions

View File

@ -3473,7 +3473,8 @@ nsRange::GetClientRectsAndTexts(
}
nsresult
nsRange::GetUsedFontFaces(nsTArray<nsAutoPtr<InspectorFontFace>>& aResult)
nsRange::GetUsedFontFaces(nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
uint32_t aMaxRanges)
{
NS_ENSURE_TRUE(mStart.Container(), NS_ERROR_UNEXPECTED);
@ -3517,17 +3518,17 @@ nsRange::GetUsedFontFaces(nsTArray<nsAutoPtr<InspectorFontFace>>& aResult)
int32_t offset = startContainer == endContainer ?
mEnd.Offset() : content->GetText()->GetLength();
nsLayoutUtils::GetFontFacesForText(frame, mStart.Offset(), offset,
true, fontFaces);
true, fontFaces, aMaxRanges);
continue;
}
if (node == endContainer) {
nsLayoutUtils::GetFontFacesForText(frame, 0, mEnd.Offset(),
true, fontFaces);
true, fontFaces, aMaxRanges);
continue;
}
}
nsLayoutUtils::GetFontFacesForFrames(frame, fontFaces);
nsLayoutUtils::GetFontFacesForFrames(frame, fontFaces, aMaxRanges);
}
// Take ownership of the InspectorFontFaces in the table and move them into

View File

@ -281,8 +281,12 @@ public:
return parentNode;
}
// aMaxRanges is the maximum number of text ranges to record for each face
// (pass 0 to just get the list of faces, without recording exact ranges
// where each face was used).
nsresult GetUsedFontFaces(
nsTArray<nsAutoPtr<mozilla::dom::InspectorFontFace>>& aResult);
nsTArray<nsAutoPtr<mozilla::dom::InspectorFontFace>>& aResult,
uint32_t aMaxRanges);
// nsIMutationObserver methods
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED

View File

@ -64,7 +64,16 @@ namespace InspectorUtils {
unsigned long long state,
optional boolean clearActiveDocument = false);
unsigned long long getContentState(Element element);
[NewObject, Throws] sequence<InspectorFontFace> getUsedFontFaces(Range range);
// Get the font face(s) actually used to render the text in /range/,
// as a collection of InspectorFontFace objects (below).
// If /maxRanges/ is greater than zero, each InspectorFontFace will record
// up to /maxRanges/ fragments of content that used the face, for the caller
// to access via its .ranges attribute.
[NewObject, Throws] sequence<InspectorFontFace> getUsedFontFaces(
Range range,
optional unsigned long maxRanges = 0);
sequence<DOMString> getCSSPseudoElementNames();
void addPseudoClassLock(Element element,
DOMString pseudoClass,
@ -135,6 +144,14 @@ interface InspectorFontFace {
[NewObject,Throws] sequence<InspectorVariationInstance> getVariationInstances();
[NewObject,Throws] sequence<InspectorFontFeature> getFeatures();
// A list of Ranges of text rendered with this face.
// This will list the first /maxRanges/ ranges found when InspectorUtils.getUsedFontFaces
// was called (so it will be empty unless a non-zero maxRanges argument was passed).
// Note that this indicates how the document was rendered at the time of calling
// getUsedFontFaces; it does not reflect any subsequent modifications, so if styles
// have been modified since calling getUsedFontFaces, it may no longer be accurate.
[Constant,Cached] readonly attribute sequence<Range> ranges;
// meaningful only when the font is a user font defined using @font-face
readonly attribute CSSFontFaceRule? rule; // null if no associated @font-face rule
readonly attribute long srcIndex; // index in the rule's src list, -1 if no @font-face rule

View File

@ -8033,14 +8033,15 @@ nsLayoutUtils::AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot)
static void
GetFontFacesForFramesInner(nsIFrame* aFrame,
nsLayoutUtils::UsedFontFaceTable& aFontFaces)
nsLayoutUtils::UsedFontFaceTable& aFontFaces,
uint32_t aMaxRanges)
{
NS_PRECONDITION(aFrame, "NULL frame pointer");
if (aFrame->IsTextFrame()) {
if (!aFrame->GetPrevContinuation()) {
nsLayoutUtils::GetFontFacesForText(aFrame, 0, INT32_MAX, true,
aFontFaces);
aFontFaces, aMaxRanges);
}
return;
}
@ -8052,19 +8053,20 @@ GetFontFacesForFramesInner(nsIFrame* aFrame,
for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
nsIFrame* child = e.get();
child = nsPlaceholderFrame::GetRealFrameFor(child);
GetFontFacesForFramesInner(child, aFontFaces);
GetFontFacesForFramesInner(child, aFontFaces, aMaxRanges);
}
}
}
/* static */ nsresult
nsLayoutUtils::GetFontFacesForFrames(nsIFrame* aFrame,
UsedFontFaceTable& aFontFaces)
UsedFontFaceTable& aFontFaces,
uint32_t aMaxRanges)
{
NS_PRECONDITION(aFrame, "NULL frame pointer");
while (aFrame) {
GetFontFacesForFramesInner(aFrame, aFontFaces);
GetFontFacesForFramesInner(aFrame, aFontFaces, aMaxRanges);
aFrame = GetNextContinuationOrIBSplitSibling(aFrame);
}
@ -8073,9 +8075,12 @@ nsLayoutUtils::GetFontFacesForFrames(nsIFrame* aFrame,
static void
AddFontsFromTextRun(gfxTextRun* aTextRun,
nsIContent* aContent,
gfxSkipCharsIterator& aSkipIter,
uint32_t aOffset,
uint32_t aLength,
nsLayoutUtils::UsedFontFaceTable& aFontFaces)
nsLayoutUtils::UsedFontFaceTable& aFontFaces,
uint32_t aMaxRanges)
{
gfxTextRun::Range range(aOffset, aOffset + aLength);
gfxTextRun::GlyphRunIterator iter(aTextRun, range);
@ -8083,15 +8088,21 @@ AddFontsFromTextRun(gfxTextRun* aTextRun,
gfxFontEntry *fe = iter.GetGlyphRun()->mFont->GetFontEntry();
// if we have already listed this face, just make sure the match type is
// recorded
InspectorFontFace* existingFace = aFontFaces.Get(fe);
if (existingFace) {
existingFace->AddMatchType(iter.GetGlyphRun()->mMatchType);
InspectorFontFace* fontFace = aFontFaces.Get(fe);
if (fontFace) {
fontFace->AddMatchType(iter.GetGlyphRun()->mMatchType);
} else {
// A new font entry we haven't seen before
InspectorFontFace* ff =
new InspectorFontFace(fe, aTextRun->GetFontGroup(),
iter.GetGlyphRun()->mMatchType);
aFontFaces.Put(fe, ff);
fontFace = new InspectorFontFace(fe, aTextRun->GetFontGroup(),
iter.GetGlyphRun()->mMatchType);
aFontFaces.Put(fe, fontFace);
}
if (fontFace->RangeCount() < aMaxRanges) {
uint32_t start = aSkipIter.ConvertSkippedToOriginal(iter.GetStringStart());
uint32_t end = aSkipIter.ConvertSkippedToOriginal(iter.GetStringEnd());
RefPtr<nsRange> range;
nsRange::CreateRange(aContent, start, aContent, end, getter_AddRefs(range));
fontFace->AddRange(range);
}
}
}
@ -8101,7 +8112,8 @@ nsLayoutUtils::GetFontFacesForText(nsIFrame* aFrame,
int32_t aStartOffset,
int32_t aEndOffset,
bool aFollowContinuations,
UsedFontFaceTable& aFontFaces)
UsedFontFaceTable& aFontFaces,
uint32_t aMaxRanges)
{
NS_PRECONDITION(aFrame, "NULL frame pointer");
@ -8136,7 +8148,8 @@ nsLayoutUtils::GetFontFacesForText(nsIFrame* aFrame,
uint32_t skipStart = iter.ConvertOriginalToSkipped(fstart);
uint32_t skipEnd = iter.ConvertOriginalToSkipped(fend);
AddFontsFromTextRun(textRun, skipStart, skipEnd - skipStart, aFontFaces);
AddFontsFromTextRun(textRun, aFrame->GetContent(), iter,
skipStart, skipEnd - skipStart, aFontFaces, aMaxRanges);
curr = next;
} while (aFollowContinuations && curr);

View File

@ -2278,21 +2278,25 @@ public:
/**
* Adds all font faces used in the frame tree starting from aFrame
* to the list aFontFaceList.
* aMaxRanges: maximum number of text ranges to record for each face.
*/
static nsresult GetFontFacesForFrames(nsIFrame* aFrame,
UsedFontFaceTable& aResult);
UsedFontFaceTable& aResult,
uint32_t aMaxRanges);
/**
* Adds all font faces used within the specified range of text in aFrame,
* and optionally its continuations, to the list in aFontFaceList.
* Pass 0 and INT32_MAX for aStartOffset and aEndOffset to specify the
* entire text is to be considered.
* aMaxRanges: maximum number of text ranges to record for each face.
*/
static nsresult GetFontFacesForText(nsIFrame* aFrame,
int32_t aStartOffset,
int32_t aEndOffset,
bool aFollowContinuations,
UsedFontFaceTable& aResult);
UsedFontFaceTable& aResult,
uint32_t aMaxRanges);
/**
* Walks the frame tree starting at aFrame looking for textRuns.

View File

@ -294,5 +294,17 @@ InspectorFontFace::GetFeatures(nsTArray<InspectorFontFeature>& aResult,
}
}
void
InspectorFontFace::GetRanges(nsTArray<RefPtr<nsRange>>& aResult)
{
aResult = mRanges;
}
void
InspectorFontFace::AddRange(nsRange* aRange)
{
mRanges.AppendElement(aRange);
}
} // namespace dom
} // namespace mozilla

View File

@ -9,6 +9,7 @@
#include "mozilla/dom/InspectorUtilsBinding.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "nsRange.h"
class gfxFontEntry;
class gfxFontGroup;
@ -42,6 +43,11 @@ public:
gfxFontEntry* GetFontEntry() const { return mFontEntry; }
void AddMatchType(uint8_t aMatchType) { mMatchType |= aMatchType; }
void AddRange(nsRange* aRange);
size_t RangeCount() const {
return mRanges.Length();
}
// Web IDL
bool FromFontGroup();
bool FromLanguagePrefs();
@ -62,6 +68,8 @@ public:
void GetFeatures(nsTArray<InspectorFontFeature>& aResult,
ErrorResult& aRV);
void GetRanges(nsTArray<RefPtr<nsRange>>& aResult);
bool WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto,
JS::MutableHandle<JSObject*> aReflector)
@ -73,6 +81,8 @@ protected:
RefPtr<gfxFontEntry> mFontEntry;
RefPtr<gfxFontGroup> mFontGroup;
uint8_t mMatchType;
nsTArray<RefPtr<nsRange>> mRanges;
};
} // namespace dom

View File

@ -1030,10 +1030,11 @@ InspectorUtils::GetCleanStyleContextForElement(dom::Element* aElement,
/* static */ void
InspectorUtils::GetUsedFontFaces(GlobalObject& aGlobalObject,
nsRange& aRange,
uint32_t aMaxRanges,
nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
ErrorResult& aRv)
{
nsresult rv = aRange.GetUsedFontFaces(aResult);
nsresult rv = aRange.GetUsedFontFaces(aResult, aMaxRanges);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}

View File

@ -222,6 +222,8 @@ public:
static void GetUsedFontFaces(GlobalObject& aGlobal,
nsRange& aRange,
uint32_t aMaxRanges, // max number of ranges to
// record for each face
nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
ErrorResult& aRv);