Diff
Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/ChangeLog 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog 2017-04-13 20:58:07 UTC (rev 215335)
@@ -1,5 +1,43 @@
2017-04-12 Myles C. Maxfield <mmaxfi...@apple.com>
+ [Cocoa] Prepare ComplexTextController for unit testing
+ https://bugs.webkit.org/show_bug.cgi?id=167493
+
+ Reviewed by Dean Jackson.
+
+ ComplexTextController has three phases:
+ 1. Interrogate Core Text about some text
+ 2. Compute layout advances and paint advances from the information retrieved from
+ Core Text
+ 3. Iterate through the layout advances or paint advances.
+
+ This patch tests phases 2 and 3 by chopping ComplexTextController between
+ phases 1 and 2, and injecting foreign metrics from a unit test. These metrics
+ have been gathered from real-world uses; however, a layout test is not appropriate
+ because the fonts which produced these metrics are not licensed appropriately.
+ The tests can enforce the correct behavior by using ComplexTextController's
+ public API.
+
+ This is in preparation for https://bugs.webkit.org/show_bug.cgi?id=166013.
+ However, the fix for that bug is quite large, so I've split out this smaller piece
+ to ease the reviewing burden. The tests I've added are disabled for now (because
+ they fail), but will be enabled by the fix to that bug.
+
+ No new tests because there is no behavior change.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/graphics/FontCascade.h:
+ * platform/graphics/FontDescription.h:
+ * platform/graphics/mac/ComplexTextController.cpp:
+ (WebCore::ComplexTextController::ComplexTextController):
+ (WebCore::ComplexTextController::finishConstruction):
+ * platform/graphics/mac/ComplexTextController.h:
+ (WebCore::ComplexTextController::ComplexTextRun::createForTesting):
+ * platform/graphics/mac/ComplexTextControllerCoreText.mm:
+ (WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
+
+2017-04-12 Myles C. Maxfield <mmaxfi...@apple.com>
+
REGRESSION(r211382): Complex text with justification erroneously overflows containers
https://bugs.webkit.org/show_bug.cgi?id=170399
<rdar://problem/31442008>
Modified: branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-04-13 20:58:07 UTC (rev 215335)
@@ -1461,7 +1461,7 @@
37B327D31D17096A005737FA /* PIPSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 37B327D21D17096A005737FA /* PIPSPI.h */; };
37BAAE581980D1DD005DFE71 /* ProtectionSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 37BAAE571980D1DD005DFE71 /* ProtectionSpace.h */; settings = {ATTRIBUTES = (Private, ); }; };
37C236101097EE7700EF9F72 /* ComplexTextController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37C2360E1097EE7700EF9F72 /* ComplexTextController.cpp */; };
- 37C236111097EE7700EF9F72 /* ComplexTextController.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C2360F1097EE7700EF9F72 /* ComplexTextController.h */; };
+ 37C236111097EE7700EF9F72 /* ComplexTextController.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C2360F1097EE7700EF9F72 /* ComplexTextController.h */; settings = {ATTRIBUTES = (Private, ); }; };
37C238221098C84200EF9F72 /* ComplexTextControllerCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */; };
37D456FD1A9A50D8003330A1 /* LocalizableStrings.pm in Copy Scripts */ = {isa = PBXBuildFile; fileRef = 37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */; };
37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */; };
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/FontCascade.h (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/FontCascade.h 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/FontCascade.h 2017-04-13 20:58:07 UTC (rev 215335)
@@ -114,7 +114,7 @@
class FontCascade {
public:
WEBCORE_EXPORT FontCascade();
- WEBCORE_EXPORT FontCascade(const FontCascadeDescription&, float letterSpacing, float wordSpacing);
+ WEBCORE_EXPORT FontCascade(const FontCascadeDescription&, float letterSpacing = 0, float wordSpacing = 0);
// This constructor is only used if the platform wants to start with a native font.
WEBCORE_EXPORT FontCascade(const FontPlatformData&, FontSmoothingMode = AutoSmoothing);
@@ -129,7 +129,7 @@
int pixelSize() const { return fontDescription().computedPixelSize(); }
float size() const { return fontDescription().computedSize(); }
- void update(RefPtr<FontSelector>&&) const;
+ WEBCORE_EXPORT void update(RefPtr<FontSelector>&&) const;
enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady };
WEBCORE_EXPORT float drawText(GraphicsContext&, const TextRun&, const FloatPoint&, unsigned from = 0, std::optional<unsigned> to = std::nullopt, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/FontDescription.h (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/FontDescription.h 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/FontDescription.h 2017-04-13 20:58:07 UTC (rev 215335)
@@ -197,7 +197,7 @@
// FIXME: Move to a file of its own.
class FontCascadeDescription : public FontDescription {
public:
- FontCascadeDescription();
+ WEBCORE_EXPORT FontCascadeDescription();
bool operator==(const FontCascadeDescription&) const;
bool operator!=(const FontCascadeDescription& other) const { return !(*this == other); }
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp 2017-04-13 20:58:07 UTC (rev 215335)
@@ -133,6 +133,23 @@
computeExpansionOpportunity();
collectComplexTextRuns();
+
+ finishConstruction();
+}
+
+ComplexTextController::ComplexTextController(const FontCascade& font, const TextRun& run, Vector<Ref<ComplexTextRun>>& runs)
+ : m_font(font)
+ , m_run(run)
+ , m_end(run.length())
+{
+ for (auto& run : runs)
+ m_complexTextRuns.append(run.ptr());
+
+ finishConstruction();
+}
+
+void ComplexTextController::finishConstruction()
+{
adjustGlyphsAndAdvances();
if (!m_isLTROnly) {
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.h (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.h 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextController.h 2017-04-13 20:58:07 UTC (rev 215335)
@@ -57,8 +57,11 @@
public:
ComplexTextController(const FontCascade&, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const Font*>* fallbackFonts = 0, bool forTextEmphasis = false);
+ class ComplexTextRun;
+ WEBCORE_EXPORT ComplexTextController(const FontCascade&, const TextRun&, Vector<Ref<ComplexTextRun>>&);
+
// Advance and emit glyphs up to the specified character.
- void advance(unsigned to, GlyphBuffer* = nullptr, GlyphIterationStyle = IncludePartialGlyphs, HashSet<const Font*>* fallbackFonts = nullptr);
+ WEBCORE_EXPORT void advance(unsigned to, GlyphBuffer* = nullptr, GlyphIterationStyle = IncludePartialGlyphs, HashSet<const Font*>* fallbackFonts = nullptr);
// Compute the character offset for a given x coordinate.
unsigned offsetForPosition(float x, bool includePartialGlyphs);
@@ -73,8 +76,6 @@
float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; }
float maxGlyphBoundingBoxY() const { return m_maxGlyphBoundingBoxY; }
-
-private:
class ComplexTextRun : public RefCounted<ComplexTextRun> {
public:
static Ref<ComplexTextRun> create(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange)
@@ -87,6 +88,11 @@
return adoptRef(*new ComplexTextRun(font, characters, stringLocation, stringLength, ltr));
}
+ static Ref<ComplexTextRun> createForTesting(Vector<CGSize> advances, Vector<CGPoint> origins, Vector<CGGlyph> glyphs, Vector<CFIndex> stringIndices, CGSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange, bool ltr)
+ {
+ return adoptRef(*new ComplexTextRun(advances, origins, glyphs, stringIndices, initialAdvance, font, characters, stringLocation, stringLength, runRange, ltr));
+ }
+
unsigned glyphCount() const { return m_glyphCount; }
const Font& font() const { return m_font; }
const UChar* characters() const { return m_characters; }
@@ -136,6 +142,7 @@
private:
ComplexTextRun(CTRunRef, const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange);
ComplexTextRun(const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr);
+ WEBCORE_EXPORT ComplexTextRun(Vector<CGSize> advances, Vector<CGPoint> origins, Vector<CGGlyph> glyphs, Vector<CFIndex> stringIndices, CGSize initialAdvance, const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange, bool ltr);
Vector<CGSize, 64> m_baseAdvancesVector;
Vector<CGPoint, 64> m_glyphOrigins;
@@ -154,9 +161,12 @@
unsigned m_glyphCount;
unsigned m_stringLocation;
bool m_isLTR;
- bool m_isMonotonic;
+ bool m_isMonotonic { true };
};
+
+private:
void computeExpansionOpportunity();
+ void finishConstruction();
static unsigned stringBegin(const ComplexTextRun& run) { return run.stringLocation() + run.indexBegin(); }
static unsigned stringEnd(const ComplexTextRun& run) { return run.stringLocation() + run.indexEnd(); }
Modified: branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm (215334 => 215335)
--- branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm 2017-04-13 20:58:07 UTC (rev 215335)
@@ -111,14 +111,14 @@
, m_font(font)
, m_characters(characters)
, m_stringLength(stringLength)
+ , m_coreTextIndices(CTRunGetStringIndicesPtr(ctRun))
+ , m_glyphs(CTRunGetGlyphsPtr(ctRun))
, m_indexBegin(runRange.location)
, m_indexEnd(runRange.location + runRange.length)
+ , m_glyphCount(CTRunGetGlyphCount(ctRun))
, m_stringLocation(stringLocation)
, m_isLTR(!(CTRunGetStatus(ctRun) & kCTRunStatusRightToLeft))
- , m_isMonotonic(true)
{
- m_glyphCount = CTRunGetGlyphCount(ctRun);
- m_coreTextIndices = CTRunGetStringIndicesPtr(ctRun);
if (!m_coreTextIndices) {
m_coreTextIndicesVector.grow(m_glyphCount);
CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), m_coreTextIndicesVector.data());
@@ -125,7 +125,6 @@
m_coreTextIndices = m_coreTextIndicesVector.data();
}
- m_glyphs = CTRunGetGlyphsPtr(ctRun);
if (!m_glyphs) {
m_glyphsVector.grow(m_glyphCount);
CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), m_glyphsVector.data());
@@ -161,7 +160,6 @@
, m_indexEnd(stringLength)
, m_stringLocation(stringLocation)
, m_isLTR(ltr)
- , m_isMonotonic(true)
{
m_coreTextIndicesVector.reserveInitialCapacity(m_stringLength);
unsigned r = 0;
@@ -184,6 +182,27 @@
m_baseAdvances = m_baseAdvancesVector.data();
}
+
+ComplexTextController::ComplexTextRun::ComplexTextRun(Vector<CGSize> advances, Vector<CGPoint> origins, Vector<CGGlyph> glyphs, Vector<CFIndex> stringIndices, CGSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange, bool ltr)
+ : m_baseAdvancesVector(advances)
+ , m_glyphOrigins(origins)
+ , m_glyphsVector(glyphs)
+ , m_coreTextIndicesVector(stringIndices)
+ , m_initialAdvance(initialAdvance)
+ , m_font(font)
+ , m_characters(characters)
+ , m_stringLength(stringLength)
+ , m_coreTextIndices(m_coreTextIndicesVector.data())
+ , m_glyphs(m_glyphsVector.data())
+ , m_baseAdvances(m_baseAdvancesVector.data())
+ , m_indexBegin(runRange.location)
+ , m_indexEnd(runRange.location + runRange.length)
+ , m_glyphCount(glyphs.size())
+ , m_stringLocation(stringLocation)
+ , m_isLTR(ltr)
+{
+}
+
struct ProviderInfo {
const UChar* cp;
unsigned length;
Modified: branches/safari-603-branch/Tools/ChangeLog (215334 => 215335)
--- branches/safari-603-branch/Tools/ChangeLog 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Tools/ChangeLog 2017-04-13 20:58:07 UTC (rev 215335)
@@ -1,5 +1,19 @@
2017-04-12 Myles C. Maxfield <mmaxfi...@apple.com>
+ [Cocoa] Prepare ComplexTextController for unit testing
+ https://bugs.webkit.org/show_bug.cgi?id=167493
+
+ Reviewed by Dean Jackson.
+
+ Create four unit tests.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp: Added.
+ (TestWebKitAPI::ComplexTextControllerTest::SetUp):
+ (TestWebKitAPI::TEST_F):
+
+2017-04-12 Myles C. Maxfield <mmaxfi...@apple.com>
+
REGRESSION(r211382): Complex text with justification erroneously overflows containers
https://bugs.webkit.org/show_bug.cgi?id=170399
<rdar://problem/31442008>
Modified: branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (215334 => 215335)
--- branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-04-13 20:08:35 UTC (rev 215334)
+++ branches/safari-603-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2017-04-13 20:58:07 UTC (rev 215335)
@@ -45,6 +45,7 @@
1C2B81831C891F0900A5529F /* CancelFontSubresourcePlugIn.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C2B81811C891EFA00A5529F /* CancelFontSubresourcePlugIn.mm */; };
1C2B81861C89259D00A5529F /* webfont.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1C2B81841C8924A200A5529F /* webfont.html */; };
1C2B81871C8925A000A5529F /* Ahem.ttf in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1C2B81851C89252300A5529F /* Ahem.ttf */; };
+ 1C9EB8411E380DA1005C6442 /* ComplexTextController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C9EB8401E380DA1005C6442 /* ComplexTextController.cpp */; };
1F83571B1D3FFB2300E3967B /* WKBackForwardList.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F83571A1D3FFB0E00E3967B /* WKBackForwardList.mm */; };
26DF5A6315A2A27E003689C2 /* CancelLoadFromResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 26DF5A6115A2A22B003689C2 /* CancelLoadFromResourceLoadDelegate.html */; };
26F52EAD1828827B0023D412 /* geolocationGetCurrentPosition.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 26F52EAC1828820E0023D412 /* geolocationGetCurrentPosition.html */; };
@@ -819,6 +820,7 @@
1C2B81811C891EFA00A5529F /* CancelFontSubresourcePlugIn.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CancelFontSubresourcePlugIn.mm; sourceTree = "<group>"; };
1C2B81841C8924A200A5529F /* webfont.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = webfont.html; sourceTree = "<group>"; };
1C2B81851C89252300A5529F /* Ahem.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Ahem.ttf; sourceTree = "<group>"; };
+ 1C9EB8401E380DA1005C6442 /* ComplexTextController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexTextController.cpp; sourceTree = "<group>"; };
1CB9BC371A67482300FE5678 /* WeakPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakPtr.cpp; sourceTree = "<group>"; };
1CF0D3781BBF2F3D00B4EF54 /* WKRetainPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKRetainPtr.cpp; sourceTree = "<group>"; };
1F83571A1D3FFB0E00E3967B /* WKBackForwardList.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKBackForwardList.mm; path = Tests/WebKit2/WKBackForwardList.mm; sourceTree = SOURCE_ROOT; };
@@ -1595,6 +1597,7 @@
440A1D3814A0103A008A66F2 /* URL.cpp */,
5C6E65411D5CEF8500F7862E /* URLParser.cpp */,
9C64DC311D76198A004B598E /* YouTubePluginReplacement.cpp */,
+ 1C9EB8401E380DA1005C6442 /* ComplexTextController.cpp */,
);
path = WebCore;
sourceTree = "<group>";
@@ -2688,6 +2691,7 @@
2DFF7B6D1DA487AF00814614 /* SnapshotStore.mm in Sources */,
5C6E65441D5CEFD400F7862E /* URLParser.cpp in Sources */,
7CCE7F271A411AF600447C4C /* UserContentController.mm in Sources */,
+ 1C9EB8411E380DA1005C6442 /* ComplexTextController.cpp in Sources */,
7CCE7F2D1A411B1000447C4C /* UserContentTest.mm in Sources */,
7C882E0A1C80C764006BF731 /* UserContentWorld.mm in Sources */,
7CCB99211D3B41F6003922F6 /* UserInitiatedActionInNavigationAction.mm in Sources */,
Added: branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp (0 => 215335)
--- branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp (rev 0)
+++ branches/safari-603-branch/Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp 2017-04-13 20:58:07 UTC (rev 215335)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <_javascript_Core/InitializeThreading.h>
+#include <WebCore/ComplexTextController.h>
+#include <WebCore/FontCascade.h>
+#include <wtf/MainThread.h>
+#include <wtf/RunLoop.h>
+
+using namespace WebCore;
+
+namespace TestWebKitAPI {
+
+class ComplexTextControllerTest : public testing::Test {
+public:
+ virtual void SetUp()
+ {
+ WTF::initializeMainThread();
+ JSC::initializeThreading();
+ RunLoop::initializeMainRunLoop();
+ }
+};
+
+TEST_F(ComplexTextControllerTest, TotalWidthWithJustification)
+{
+ FontCascadeDescription description;
+ description.setOneFamily("Times");
+ description.setComputedSize(80);
+ FontCascade font(description);
+ font.update(nullptr);
+
+ Vector<CGSize> advances = { CGSizeMake(1, 0), CGSizeMake(2, 0), CGSizeMake(4, 0), CGSizeMake(8, 0), CGSizeMake(16, 0) };
+#if USE_LAYOUT_SPECIFIC_ADVANCES
+ Vector<CGPoint> origins = { CGPointZero, CGPointZero, CGPointZero, CGPointZero, CGPointZero };
+#else
+ Vector<CGPoint> origins = { };
+#endif
+
+ CGSize initialAdvance = CGSizeZero;
+
+ UChar characters[] = { 0x644, ' ', 0x644, ' ', 0x644 };
+ size_t charactersLength = WTF_ARRAY_LENGTH(characters);
+ TextRun textRun(StringView(characters, charactersLength), 0, 14, DefaultExpansion, RTL);
+ auto run = ComplexTextController::ComplexTextRun::createForTesting(advances, origins, { 5, 6, 7, 8, 9 }, { 4, 3, 2, 1, 0 }, initialAdvance, font.primaryFont(), characters, 0, charactersLength, CFRangeMake(0, 5), false);
+ Vector<Ref<ComplexTextController::ComplexTextRun>> runs;
+ runs.append(WTFMove(run));
+ ComplexTextController controller(font, textRun, runs);
+
+ EXPECT_NEAR(controller.totalWidth(), 1 + 20 + 7 + 4 + 20 + 7 + 16, 0.0001);
+ GlyphBuffer glyphBuffer;
+ EXPECT_NEAR(controller.runWidthSoFar(), 0, 0.0001);
+ controller.advance(5, &glyphBuffer);
+ EXPECT_EQ(glyphBuffer.size(), 5U);
+ EXPECT_NEAR(glyphBuffer.advanceAt(0).width() + glyphBuffer.advanceAt(1).width() + glyphBuffer.advanceAt(2).width() + glyphBuffer.advanceAt(3).width() + glyphBuffer.advanceAt(4).width(), controller.totalWidth(), 0.0001);
+}
+
+}