Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Dorel Luca
2019-06-12 15:05:58 +03:00
18 changed files with 327 additions and 50 deletions

View File

@@ -59,6 +59,25 @@ AutoInitializeImageLib::AutoInitializeImageLib() {
SpinPendingEvents(); SpinPendingEvents();
} }
void ImageBenchmarkBase::SetUp() {
nsCOMPtr<nsIInputStream> inputStream = LoadFile(mTestCase.mPath);
ASSERT_TRUE(inputStream != nullptr);
// Figure out how much data we have.
uint64_t length;
nsresult rv = inputStream->Available(&length);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Write the data into a SourceBuffer.
mSourceBuffer = new SourceBuffer();
mSourceBuffer->ExpectLength(length);
rv = mSourceBuffer->AppendFromInputStream(inputStream, length);
ASSERT_TRUE(NS_SUCCEEDED(rv));
mSourceBuffer->Complete(NS_OK);
}
void ImageBenchmarkBase::TearDown() {}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// General Helpers // General Helpers
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -732,5 +751,59 @@ ImageTestCase GreenMultipleSizesICOTestCase() {
IntSize(256, 256)); IntSize(256, 256));
} }
ImageTestCase PerfGrayJPGTestCase() {
return ImageTestCase("perf_gray.jpg", "image/jpeg", IntSize(1000, 1000));
}
ImageTestCase PerfCmykJPGTestCase() {
return ImageTestCase("perf_cmyk.jpg", "image/jpeg", IntSize(1000, 1000));
}
ImageTestCase PerfYCbCrJPGTestCase() {
return ImageTestCase("perf_ycbcr.jpg", "image/jpeg", IntSize(1000, 1000));
}
ImageTestCase PerfRgbPNGTestCase() {
return ImageTestCase("perf_srgb.png", "image/png", IntSize(1000, 1000));
}
ImageTestCase PerfRgbAlphaPNGTestCase() {
return ImageTestCase("perf_srgb_alpha.png", "image/png", IntSize(1000, 1000),
TEST_CASE_IS_TRANSPARENT);
}
ImageTestCase PerfGrayPNGTestCase() {
return ImageTestCase("perf_gray.png", "image/png", IntSize(1000, 1000));
}
ImageTestCase PerfGrayAlphaPNGTestCase() {
return ImageTestCase("perf_gray_alpha.png", "image/png", IntSize(1000, 1000),
TEST_CASE_IS_TRANSPARENT);
}
ImageTestCase PerfRgbLosslessWebPTestCase() {
return ImageTestCase("perf_srgb_lossless.webp", "image/webp",
IntSize(1000, 1000));
}
ImageTestCase PerfRgbAlphaLosslessWebPTestCase() {
return ImageTestCase("perf_srgb_alpha_lossless.webp", "image/webp",
IntSize(1000, 1000), TEST_CASE_IS_TRANSPARENT);
}
ImageTestCase PerfRgbLossyWebPTestCase() {
return ImageTestCase("perf_srgb_lossy.webp", "image/webp",
IntSize(1000, 1000));
}
ImageTestCase PerfRgbAlphaLossyWebPTestCase() {
return ImageTestCase("perf_srgb_alpha_lossy.webp", "image/webp",
IntSize(1000, 1000), TEST_CASE_IS_TRANSPARENT);
}
ImageTestCase PerfRgbGIFTestCase() {
return ImageTestCase("perf_srgb.gif", "image/gif", IntSize(1000, 1000));
}
} // namespace image } // namespace image
} // namespace mozilla } // namespace mozilla

View File

@@ -18,6 +18,7 @@
#include "gfxColor.h" #include "gfxColor.h"
#include "imgITools.h" #include "imgITools.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "SurfaceFlags.h"
#include "SurfacePipe.h" #include "SurfacePipe.h"
#include "SurfacePipeFactory.h" #include "SurfacePipeFactory.h"
@@ -86,6 +87,7 @@ struct ImageTestCase {
mSize(aSize), mSize(aSize),
mOutputSize(aSize), mOutputSize(aSize),
mFlags(aFlags), mFlags(aFlags),
mSurfaceFlags(DefaultSurfaceFlags()),
mColor(BGRAColor::Green()) {} mColor(BGRAColor::Green()) {}
ImageTestCase(const char* aPath, const char* aMimeType, gfx::IntSize aSize, ImageTestCase(const char* aPath, const char* aMimeType, gfx::IntSize aSize,
@@ -96,6 +98,7 @@ struct ImageTestCase {
mSize(aSize), mSize(aSize),
mOutputSize(aOutputSize), mOutputSize(aOutputSize),
mFlags(aFlags), mFlags(aFlags),
mSurfaceFlags(DefaultSurfaceFlags()),
mColor(BGRAColor::Green()) {} mColor(BGRAColor::Green()) {}
const char* mPath; const char* mPath;
@@ -103,6 +106,7 @@ struct ImageTestCase {
gfx::IntSize mSize; gfx::IntSize mSize;
gfx::IntSize mOutputSize; gfx::IntSize mOutputSize;
uint32_t mFlags; uint32_t mFlags;
SurfaceFlags mSurfaceFlags;
BGRAColor mColor; BGRAColor mColor;
}; };
@@ -122,6 +126,22 @@ class AutoInitializeImageLib {
AutoInitializeImageLib(); AutoInitializeImageLib();
}; };
/**
* A test fixture class used for benchmark tests. It preloads the image data
* from disk to avoid including that in the timing.
*/
class ImageBenchmarkBase : public ::testing::Test {
protected:
ImageBenchmarkBase(const ImageTestCase& aTestCase) : mTestCase(aTestCase) {}
void SetUp() override;
void TearDown() override;
AutoInitializeImageLib mInit;
ImageTestCase mTestCase;
RefPtr<SourceBuffer> mSourceBuffer;
};
/// Spins on the main thread to process any pending events. /// Spins on the main thread to process any pending events.
void SpinPendingEvents(); void SpinPendingEvents();
@@ -465,6 +485,19 @@ ImageTestCase LargeICOWithBMPTestCase();
ImageTestCase LargeICOWithPNGTestCase(); ImageTestCase LargeICOWithPNGTestCase();
ImageTestCase GreenMultipleSizesICOTestCase(); ImageTestCase GreenMultipleSizesICOTestCase();
ImageTestCase PerfGrayJPGTestCase();
ImageTestCase PerfCmykJPGTestCase();
ImageTestCase PerfYCbCrJPGTestCase();
ImageTestCase PerfRgbPNGTestCase();
ImageTestCase PerfRgbAlphaPNGTestCase();
ImageTestCase PerfGrayPNGTestCase();
ImageTestCase PerfGrayAlphaPNGTestCase();
ImageTestCase PerfRgbLosslessWebPTestCase();
ImageTestCase PerfRgbAlphaLosslessWebPTestCase();
ImageTestCase PerfRgbLossyWebPTestCase();
ImageTestCase PerfRgbAlphaLossyWebPTestCase();
ImageTestCase PerfRgbGIFTestCase();
} // namespace image } // namespace image
} // namespace mozilla } // namespace mozilla

View File

@@ -0,0 +1,158 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "gtest/MozGTestBench.h"
#include "Common.h"
#include "Decoder.h"
#include "DecoderFactory.h"
#include "IDecodingTask.h"
#include "mozilla/RefPtr.h"
#include "ProgressTracker.h"
#include "SourceBuffer.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
namespace {
static void CheckDecoderState(const ImageTestCase& aTestCase, Decoder* aDecoder,
const IntSize& aOutputSize) {
// Decoder should match what we asked for in the MIME type.
EXPECT_NE(aDecoder->GetType(), DecoderType::UNKNOWN);
EXPECT_EQ(aDecoder->GetType(),
DecoderFactory::GetDecoderType(aTestCase.mMimeType));
EXPECT_TRUE(aDecoder->GetDecodeDone());
EXPECT_FALSE(aDecoder->HasError());
// Verify that the decoder made the expected progress.
Progress progress = aDecoder->TakeProgress();
EXPECT_FALSE(bool(progress & FLAG_HAS_ERROR));
EXPECT_FALSE(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR));
EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE));
EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE));
EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE));
EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT),
bool(progress & FLAG_HAS_TRANSPARENCY));
EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
bool(progress & FLAG_IS_ANIMATED));
// The decoder should get the correct size.
IntSize size = aDecoder->Size();
EXPECT_EQ(aTestCase.mSize.width, size.width);
EXPECT_EQ(aTestCase.mSize.height, size.height);
// Get the current frame, which is always the first frame of the image
// because CreateAnonymousDecoder() forces a first-frame-only decode.
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
// Verify that the resulting surfaces matches our expectations.
EXPECT_TRUE(surface->IsDataSourceSurface());
EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::B8G8R8X8 ||
surface->GetFormat() == SurfaceFormat::B8G8R8A8);
EXPECT_EQ(aOutputSize, surface->GetSize());
}
template <typename Func>
static void WithSingleChunkDecode(const ImageTestCase& aTestCase,
SourceBuffer* aSourceBuffer,
const Maybe<IntSize>& aOutputSize,
Func aResultChecker) {
auto sourceBuffer = WrapNotNull(RefPtr<SourceBuffer>(aSourceBuffer));
// Create a decoder.
DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
decoderType, sourceBuffer, aOutputSize, DecoderFlags::FIRST_FRAME_ONLY,
aTestCase.mSurfaceFlags);
ASSERT_TRUE(decoder != nullptr);
RefPtr<IDecodingTask> task =
new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
// Run the full decoder synchronously.
task->Run();
// Call the lambda to verify the expected results.
aResultChecker(decoder);
}
static void CheckDecode(const ImageTestCase& aTestCase,
SourceBuffer* aSourceBuffer) {
WithSingleChunkDecode(
aTestCase, aSourceBuffer, Nothing(), [&](Decoder* aDecoder) {
CheckDecoderState(aTestCase, aDecoder, aTestCase.mSize);
});
}
static void CheckDownscaleDuringDecode(const ImageTestCase& aTestCase,
SourceBuffer* aSourceBuffer) {
IntSize outputSize(20, 20);
WithSingleChunkDecode(aTestCase, aSourceBuffer, Some(outputSize),
[&](Decoder* aDecoder) {
CheckDecoderState(aTestCase, aDecoder, outputSize);
});
}
#define IMAGE_GTEST_BENCH_FIXTURE(test_fixture, test_case) \
class test_fixture : public ImageBenchmarkBase { \
protected: \
test_fixture() : ImageBenchmarkBase(test_case()) {} \
};
#define IMAGE_GTEST_NATIVE_BENCH_F(test_fixture) \
MOZ_GTEST_BENCH_F(test_fixture, Native, \
[this] { CheckDecode(mTestCase, mSourceBuffer); });
#define IMAGE_GTEST_DOWNSCALE_BENCH_F(test_fixture) \
MOZ_GTEST_BENCH_F(test_fixture, Downscale, [this] { \
CheckDownscaleDuringDecode(mTestCase, mSourceBuffer); \
});
#define IMAGE_GTEST_NO_COLOR_MANAGEMENT_BENCH_F(test_fixture) \
MOZ_GTEST_BENCH_F(test_fixture, NoColorManagement, [this] { \
ImageTestCase testCase = mTestCase; \
testCase.mSurfaceFlags |= SurfaceFlags::NO_COLORSPACE_CONVERSION; \
CheckDecode(testCase, mSourceBuffer); \
});
#define IMAGE_GTEST_NO_PREMULTIPLY_BENCH_F(test_fixture) \
MOZ_GTEST_BENCH_F(test_fixture, NoPremultiplyAlpha, [this] { \
ImageTestCase testCase = mTestCase; \
testCase.mSurfaceFlags |= SurfaceFlags::NO_PREMULTIPLY_ALPHA; \
CheckDecode(testCase, mSourceBuffer); \
});
#define IMAGE_GTEST_BENCH_F(type, test) \
IMAGE_GTEST_BENCH_FIXTURE(ImageDecodersPerf_##type##_##test, \
Perf##test##type##TestCase) \
IMAGE_GTEST_NATIVE_BENCH_F(ImageDecodersPerf_##type##_##test) \
IMAGE_GTEST_DOWNSCALE_BENCH_F(ImageDecodersPerf_##type##_##test) \
IMAGE_GTEST_NO_COLOR_MANAGEMENT_BENCH_F(ImageDecodersPerf_##type##_##test)
#define IMAGE_GTEST_BENCH_ALPHA_F(type, test) \
IMAGE_GTEST_BENCH_F(type, test) \
IMAGE_GTEST_NO_PREMULTIPLY_BENCH_F(ImageDecodersPerf_##type##_##test)
IMAGE_GTEST_BENCH_F(JPG, YCbCr)
IMAGE_GTEST_BENCH_F(JPG, Cmyk)
IMAGE_GTEST_BENCH_F(JPG, Gray)
IMAGE_GTEST_BENCH_F(PNG, Rgb)
IMAGE_GTEST_BENCH_F(PNG, Gray)
IMAGE_GTEST_BENCH_ALPHA_F(PNG, RgbAlpha)
IMAGE_GTEST_BENCH_ALPHA_F(PNG, GrayAlpha)
IMAGE_GTEST_BENCH_F(WebP, RgbLossless)
IMAGE_GTEST_BENCH_F(WebP, RgbLossy)
IMAGE_GTEST_BENCH_ALPHA_F(WebP, RgbAlphaLossless)
IMAGE_GTEST_BENCH_ALPHA_F(WebP, RgbAlphaLossy)
IMAGE_GTEST_BENCH_F(GIF, Rgb)
} // namespace

View File

@@ -25,6 +25,7 @@ UNIFIED_SOURCES = [
if not(CONFIG['OS_TARGET'] == 'WINNT' and CONFIG['CPU_ARCH'] == 'aarch64'): if not(CONFIG['OS_TARGET'] == 'WINNT' and CONFIG['CPU_ARCH'] == 'aarch64'):
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'TestDecoders.cpp', 'TestDecoders.cpp',
'TestDecodersPerf.cpp',
'TestDecodeToSurface.cpp', 'TestDecodeToSurface.cpp',
'TestMetadata.cpp', 'TestMetadata.cpp',
'TestSourceBuffer.cpp', 'TestSourceBuffer.cpp',
@@ -77,6 +78,18 @@ TEST_HARNESS_FILES.gtest += [
'invalid-truncated-metadata.bmp', 'invalid-truncated-metadata.bmp',
'large.webp', 'large.webp',
'no-frame-delay.gif', 'no-frame-delay.gif',
'perf_cmyk.jpg',
'perf_gray.jpg',
'perf_gray.png',
'perf_gray_alpha.png',
'perf_srgb.gif',
'perf_srgb.png',
'perf_srgb_alpha.png',
'perf_srgb_alpha_lossless.webp',
'perf_srgb_alpha_lossy.webp',
'perf_srgb_lossless.webp',
'perf_srgb_lossy.webp',
'perf_ycbcr.jpg',
'rle4.bmp', 'rle4.bmp',
'rle8.bmp', 'rle8.bmp',
'transparent-ico-with-and-mask.ico', 'transparent-ico-with-and-mask.ico',

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -536,6 +536,9 @@ already_AddRefed<nsIContentViewer> NS_NewContentViewer() {
} }
void nsDocumentViewer::PrepareToStartLoad() { void nsDocumentViewer::PrepareToStartLoad() {
MOZ_DIAGNOSTIC_ASSERT(!GetIsPrintPreview(),
"Print preview tab should never navigate");
mStopped = false; mStopped = false;
mLoaded = false; mLoaded = false;
mAttachedToParent = false; mAttachedToParent = false;
@@ -550,9 +553,6 @@ void nsDocumentViewer::PrepareToStartLoad() {
if (mPrintJob) { if (mPrintJob) {
mPrintJob->Destroy(); mPrintJob->Destroy();
mPrintJob = nullptr; mPrintJob = nullptr;
# ifdef NS_PRINT_PREVIEW
SetIsPrintPreview(false);
# endif
} }
#endif // NS_PRINTING #endif // NS_PRINTING

View File

@@ -16,10 +16,6 @@
#include "gfxTypes.h" #include "gfxTypes.h"
#include "gfxUtils.h" #include "gfxUtils.h"
#include "LookAndFeel.h" #include "LookAndFeel.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PatternHelpers.h"
#include "mozilla/Likely.h"
#include "mozilla/PresShell.h"
#include "nsAlgorithm.h" #include "nsAlgorithm.h"
#include "nsBidiPresUtils.h" #include "nsBidiPresUtils.h"
#include "nsBlockFrame.h" #include "nsBlockFrame.h"
@@ -30,14 +26,10 @@
#include "SVGObserverUtils.h" #include "SVGObserverUtils.h"
#include "nsSVGOuterSVGFrame.h" #include "nsSVGOuterSVGFrame.h"
#include "nsSVGPaintServerFrame.h" #include "nsSVGPaintServerFrame.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/SVGRect.h"
#include "mozilla/dom/SVGTextContentElementBinding.h"
#include "nsSVGIntegrationUtils.h" #include "nsSVGIntegrationUtils.h"
#include "nsSVGUtils.h" #include "nsSVGUtils.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsTextFrame.h" #include "nsTextFrame.h"
#include "nsTextNode.h"
#include "SVGAnimatedNumberList.h" #include "SVGAnimatedNumberList.h"
#include "SVGContentUtils.h" #include "SVGContentUtils.h"
#include "SVGContextPaint.h" #include "SVGContextPaint.h"
@@ -48,6 +40,14 @@
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsFrameSelection.h" #include "nsFrameSelection.h"
#include "nsStyleStructInlines.h" #include "nsStyleStructInlines.h"
#include "mozilla/Likely.h"
#include "mozilla/PresShell.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/SVGRect.h"
#include "mozilla/dom/SVGTextContentElementBinding.h"
#include "mozilla/dom/Text.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PatternHelpers.h"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <limits> #include <limits>
@@ -234,16 +234,16 @@ static bool IsNonEmptyTextFrame(nsIFrame* aFrame) {
/** /**
* Takes an nsIFrame and if it is a text frame that has some text content, * Takes an nsIFrame and if it is a text frame that has some text content,
* returns it as an nsTextFrame and its corresponding nsTextNode. * returns it as an nsTextFrame and its corresponding Text.
* *
* @param aFrame The frame to look at. * @param aFrame The frame to look at.
* @param aTextFrame aFrame as an nsTextFrame (output). * @param aTextFrame aFrame as an nsTextFrame (output).
* @param aTextNode The nsTextNode content of aFrame (output). * @param aTextNode The Text content of aFrame (output).
* @return true if aFrame is a non-empty text frame, false otherwise. * @return true if aFrame is a non-empty text frame, false otherwise.
*/ */
static bool GetNonEmptyTextFrameAndNode(nsIFrame* aFrame, static bool GetNonEmptyTextFrameAndNode(nsIFrame* aFrame,
nsTextFrame*& aTextFrame, nsTextFrame*& aTextFrame,
nsTextNode*& aTextNode) { Text*& aTextNode) {
nsTextFrame* text = do_QueryFrame(aFrame); nsTextFrame* text = do_QueryFrame(aFrame);
bool isNonEmptyTextFrame = text && text->GetContentLength() != 0; bool isNonEmptyTextFrame = text && text->GetContentLength() != 0;
@@ -252,7 +252,7 @@ static bool GetNonEmptyTextFrameAndNode(nsIFrame* aFrame,
NS_ASSERTION(content && content->IsText(), NS_ASSERTION(content && content->IsText(),
"unexpected content type for nsTextFrame"); "unexpected content type for nsTextFrame");
nsTextNode* node = static_cast<nsTextNode*>(content); Text* node = content->AsText();
MOZ_ASSERT(node->TextLength() != 0, MOZ_ASSERT(node->TextLength() != 0,
"frame's GetContentLength() should be 0 if the text node " "frame's GetContentLength() should be 0 if the text node "
"has no content"); "has no content");
@@ -724,7 +724,7 @@ struct TextRenderedRun {
nscoord mBaseline; nscoord mBaseline;
/** /**
* The offset and length in mFrame's content nsTextNode that corresponds to * The offset and length in mFrame's content Text that corresponds to
* this text rendered run. These are original char indexes. * this text rendered run. These are original char indexes.
*/ */
uint32_t mTextFrameContentOffset; uint32_t mTextFrameContentOffset;
@@ -1092,7 +1092,7 @@ int32_t TextRenderedRun::GetCharNumAtPosition(nsPresContext* aContext,
enum SubtreePosition { eBeforeSubtree, eWithinSubtree, eAfterSubtree }; enum SubtreePosition { eBeforeSubtree, eWithinSubtree, eAfterSubtree };
/** /**
* An iterator class for nsTextNodes that are descendants of a given node, the * An iterator class for Text that are descendants of a given node, the
* root. Nodes are iterated in document order. An optional subtree can be * root. Nodes are iterated in document order. An optional subtree can be
* specified, in which case the iterator will track whether the current state of * specified, in which case the iterator will track whether the current state of
* the traversal over the tree is within that subtree or is past that subtree. * the traversal over the tree is within that subtree or is past that subtree.
@@ -1115,15 +1115,15 @@ class TextNodeIterator {
} }
/** /**
* Returns the current nsTextNode, or null if the iterator has finished. * Returns the current Text, or null if the iterator has finished.
*/ */
nsTextNode* Current() const { return static_cast<nsTextNode*>(mCurrent); } Text* Current() const { return mCurrent ? mCurrent->AsText() : nullptr; }
/** /**
* Advances to the next nsTextNode and returns it, or null if the end of * Advances to the next Text and returns it, or null if the end of
* iteration has been reached. * iteration has been reached.
*/ */
nsTextNode* Next(); Text* Next();
/** /**
* Returns whether the iterator is currently within the subtree rooted * Returns whether the iterator is currently within the subtree rooted
@@ -1140,7 +1140,7 @@ class TextNodeIterator {
private: private:
/** /**
* The root under which all nsTextNodes will be iterated over. * The root under which all Text will be iterated over.
*/ */
nsIContent* mRoot; nsIContent* mRoot;
@@ -1160,9 +1160,9 @@ class TextNodeIterator {
SubtreePosition mSubtreePosition; SubtreePosition mSubtreePosition;
}; };
nsTextNode* TextNodeIterator::Next() { Text* TextNodeIterator::Next() {
// Starting from mCurrent, we do a non-recursive traversal to the next // Starting from mCurrent, we do a non-recursive traversal to the next
// nsTextNode beneath mRoot, updating mSubtreePosition appropriately if we // Text beneath mRoot, updating mSubtreePosition appropriately if we
// encounter mSubtree. // encounter mSubtree.
if (mCurrent) { if (mCurrent) {
do { do {
@@ -1199,7 +1199,7 @@ nsTextNode* TextNodeIterator::Next() {
} while (mCurrent && !mCurrent->IsText()); } while (mCurrent && !mCurrent->IsText());
} }
return static_cast<nsTextNode*>(mCurrent); return mCurrent ? mCurrent->AsText() : nullptr;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1248,7 +1248,7 @@ static uint32_t GetUndisplayedCharactersBeforeFrame(nsTextFrame* aFrame) {
* Traverses the nsTextFrames for an SVGTextFrame and records a * Traverses the nsTextFrames for an SVGTextFrame and records a
* TextNodeCorrespondenceProperty on each for the number of undisplayed DOM * TextNodeCorrespondenceProperty on each for the number of undisplayed DOM
* characters between each frame. This is done by iterating simultaneously * characters between each frame. This is done by iterating simultaneously
* over the nsTextNodes and nsTextFrames and noting when nsTextNodes (or * over the Text and nsTextFrames and noting when Text (or
* parts of them) are skipped when finding the next nsTextFrame. * parts of them) are skipped when finding the next nsTextFrame.
*/ */
class TextNodeCorrespondenceRecorder { class TextNodeCorrespondenceRecorder {
@@ -1268,23 +1268,23 @@ class TextNodeCorrespondenceRecorder {
void TraverseAndRecord(nsIFrame* aFrame); void TraverseAndRecord(nsIFrame* aFrame);
/** /**
* Returns the next non-empty nsTextNode. * Returns the next non-empty Text.
*/ */
nsTextNode* NextNode(); Text* NextNode();
/** /**
* The iterator over the nsTextNodes that we use as we simultaneously * The iterator over the Text that we use as we simultaneously
* iterate over the nsTextFrames. * iterate over the nsTextFrames.
*/ */
TextNodeIterator mNodeIterator; TextNodeIterator mNodeIterator;
/** /**
* The previous nsTextNode we iterated over. * The previous Text we iterated over.
*/ */
nsTextNode* mPreviousNode; Text* mPreviousNode;
/** /**
* The index into the current nsTextNode's character content. * The index into the current Text's character content.
*/ */
uint32_t mNodeCharIndex; uint32_t mNodeCharIndex;
}; };
@@ -1302,7 +1302,7 @@ void TextNodeCorrespondenceRecorder::RecordCorrespondence(SVGTextFrame* aRoot) {
void TextNodeCorrespondenceRecorder::Record(SVGTextFrame* aRoot) { void TextNodeCorrespondenceRecorder::Record(SVGTextFrame* aRoot) {
if (!mNodeIterator.Current()) { if (!mNodeIterator.Current()) {
// If there are no nsTextNodes then there is nothing to do. // If there are no Text nodes then there is nothing to do.
return; return;
} }
@@ -1314,15 +1314,15 @@ void TextNodeCorrespondenceRecorder::Record(SVGTextFrame* aRoot) {
uint32_t undisplayed = 0; uint32_t undisplayed = 0;
if (mNodeIterator.Current()) { if (mNodeIterator.Current()) {
if (mPreviousNode && mPreviousNode->TextLength() != mNodeCharIndex) { if (mPreviousNode && mPreviousNode->TextLength() != mNodeCharIndex) {
// The last nsTextFrame ended part way through an nsTextNode. The // The last nsTextFrame ended part way through a Text node. The
// remaining characters count as undisplayed. // remaining characters count as undisplayed.
NS_ASSERTION(mNodeCharIndex < mPreviousNode->TextLength(), NS_ASSERTION(mNodeCharIndex < mPreviousNode->TextLength(),
"incorrect tracking of undisplayed characters in " "incorrect tracking of undisplayed characters in "
"text nodes"); "text nodes");
undisplayed += mPreviousNode->TextLength() - mNodeCharIndex; undisplayed += mPreviousNode->TextLength() - mNodeCharIndex;
} }
// All the remaining nsTextNodes that we iterate must also be undisplayed. // All the remaining Text that we iterate must also be undisplayed.
for (nsTextNode* textNode = mNodeIterator.Current(); textNode; for (Text* textNode = mNodeIterator.Current(); textNode;
textNode = NextNode()) { textNode = NextNode()) {
undisplayed += textNode->TextLength(); undisplayed += textNode->TextLength();
} }
@@ -1333,9 +1333,9 @@ void TextNodeCorrespondenceRecorder::Record(SVGTextFrame* aRoot) {
aRoot->mTrailingUndisplayedCharacters = undisplayed; aRoot->mTrailingUndisplayedCharacters = undisplayed;
} }
nsTextNode* TextNodeCorrespondenceRecorder::NextNode() { Text* TextNodeCorrespondenceRecorder::NextNode() {
mPreviousNode = mNodeIterator.Current(); mPreviousNode = mNodeIterator.Current();
nsTextNode* next; Text* next;
do { do {
next = mNodeIterator.Next(); next = mNodeIterator.Next();
} while (next && next->TextLength() == 0); } while (next && next->TextLength() == 0);
@@ -1353,7 +1353,7 @@ void TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame) {
} }
nsTextFrame* frame; // The current text frame. nsTextFrame* frame; // The current text frame.
nsTextNode* node; // The text node for the current text frame. Text* node; // The text node for the current text frame.
if (!GetNonEmptyTextFrameAndNode(aFrame, frame, node)) { if (!GetNonEmptyTextFrameAndNode(aFrame, frame, node)) {
// If this isn't an nsTextFrame, or is empty, nothing to do. // If this isn't an nsTextFrame, or is empty, nothing to do.
return; return;
@@ -1373,7 +1373,7 @@ void TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame) {
"incorrect tracking of correspondence between " "incorrect tracking of correspondence between "
"text frames and text nodes"); "text frames and text nodes");
} else { } else {
// Each whole nsTextNode we find before we get to the text node for the // Each whole Text we find before we get to the text node for the
// first text frame must be undisplayed. // first text frame must be undisplayed.
while (mNodeIterator.Current() != node) { while (mNodeIterator.Current() != node) {
undisplayed += mNodeIterator.Current()->TextLength(); undisplayed += mNodeIterator.Current()->TextLength();
@@ -1401,11 +1401,11 @@ void TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame) {
NS_ASSERTION(mNodeCharIndex < mPreviousNode->TextLength(), NS_ASSERTION(mNodeCharIndex < mPreviousNode->TextLength(),
"incorrect tracking of undisplayed characters in " "incorrect tracking of undisplayed characters in "
"text nodes"); "text nodes");
// Any trailing characters at the end of the previous nsTextNode are // Any trailing characters at the end of the previous Text are
// undisplayed. // undisplayed.
undisplayed = mPreviousNode->TextLength() - mNodeCharIndex; undisplayed = mPreviousNode->TextLength() - mNodeCharIndex;
} }
// Each whole nsTextNode we find before we get to the text node for // Each whole Text we find before we get to the text node for
// the current text frame must be undisplayed. // the current text frame must be undisplayed.
while (mNodeIterator.Current() && mNodeIterator.Current() != node) { while (mNodeIterator.Current() && mNodeIterator.Current() != node) {
undisplayed += mNodeIterator.Current()->TextLength(); undisplayed += mNodeIterator.Current()->TextLength();
@@ -1421,7 +1421,7 @@ void TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame) {
frame->SetProperty(TextNodeCorrespondenceProperty(), frame->SetProperty(TextNodeCorrespondenceProperty(),
new TextNodeCorrespondence(undisplayed)); new TextNodeCorrespondence(undisplayed));
// Remember how far into the current nsTextNode we are. // Remember how far into the current Text we are.
mNodeCharIndex = frame->GetContentEnd(); mNodeCharIndex = frame->GetContentEnd();
} }
@@ -1859,7 +1859,7 @@ TextRenderedRun TextRenderedRunIterator::Next() {
} }
// Convert the global run start/end indexes into an offset/length into the // Convert the global run start/end indexes into an offset/length into the
// current frame's nsTextNode. // current frame's Text.
offset = offset =
frame->GetContentOffset() + runStart - mFrameStartTextElementCharIndex; frame->GetContentOffset() + runStart - mFrameStartTextElementCharIndex;
length = runEnd - runStart; length = runEnd - runStart;
@@ -2112,7 +2112,7 @@ class CharIterator {
} }
/** /**
* Gets the original character offsets within the nsTextNode for the * Gets the original character offsets within the Text for the
* cluster/ligature group the current character is a part of. * cluster/ligature group the current character is a part of.
* *
* @param aOriginalOffset The offset of the start of the cluster/ligature * @param aOriginalOffset The offset of the start of the cluster/ligature
@@ -3582,14 +3582,14 @@ SVGBBox SVGTextFrame::GetBBoxContribution(const Matrix& aToBBoxUserspace,
// SVGTextFrame SVG DOM methods // SVGTextFrame SVG DOM methods
/** /**
* Returns whether the specified node has any non-empty nsTextNodes * Returns whether the specified node has any non-empty Text
* beneath it. * beneath it.
*/ */
static bool HasTextContent(nsIContent* aContent) { static bool HasTextContent(nsIContent* aContent) {
NS_ASSERTION(aContent, "expected non-null aContent"); NS_ASSERTION(aContent, "expected non-null aContent");
TextNodeIterator it(aContent); TextNodeIterator it(aContent);
for (nsTextNode* text = it.Current(); text; text = it.Next()) { for (Text* text = it.Current(); text; text = it.Next()) {
if (text->TextLength() != 0) { if (text->TextLength() != 0) {
return true; return true;
} }
@@ -3605,7 +3605,7 @@ static uint32_t GetTextContentLength(nsIContent* aContent) {
uint32_t length = 0; uint32_t length = 0;
TextNodeIterator it(aContent); TextNodeIterator it(aContent);
for (nsTextNode* text = it.Current(); text; text = it.Next()) { for (Text* text = it.Current(); text; text = it.Next()) {
length += text->TextLength(); length += text->TextLength();
} }
return length; return length;
@@ -3795,7 +3795,7 @@ nsresult SVGTextFrame::GetSubStringLength(nsIContent* aContent,
frameStartTextElementCharIndex += frit.UndisplayedCharacters(); frameStartTextElementCharIndex += frit.UndisplayedCharacters();
textElementCharIndex = frameStartTextElementCharIndex; textElementCharIndex = frameStartTextElementCharIndex;
// Offset into frame's nsTextNode: // Offset into frame's Text:
const uint32_t untrimmedOffset = frame->GetContentOffset(); const uint32_t untrimmedOffset = frame->GetContentOffset();
const uint32_t untrimmedLength = frame->GetContentEnd() - untrimmedOffset; const uint32_t untrimmedLength = frame->GetContentEnd() - untrimmedOffset;
@@ -4169,7 +4169,7 @@ bool SVGTextFrame::ResolvePositionsForNode(nsIContent* aContent,
nsTArray<gfxPoint>& aDeltas) { nsTArray<gfxPoint>& aDeltas) {
if (aContent->IsText()) { if (aContent->IsText()) {
// We found a text node. // We found a text node.
uint32_t length = static_cast<nsTextNode*>(aContent)->TextLength(); uint32_t length = aContent->AsText()->TextLength();
if (length) { if (length) {
uint32_t end = aIndex + length; uint32_t end = aIndex + length;
if (MOZ_UNLIKELY(end > mPositions.Length())) { if (MOZ_UNLIKELY(end > mPositions.Length())) {