Diff
Modified: trunk/Source/WebCore/ChangeLog (281293 => 281294)
--- trunk/Source/WebCore/ChangeLog 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/ChangeLog 2021-08-20 04:53:20 UTC (rev 281294)
@@ -1,5 +1,61 @@
2021-08-19 Myles C. Maxfield <[email protected]>
+ The fast text codepath does not handle run initial advances
+ https://bugs.webkit.org/show_bug.cgi?id=227979
+
+ Reviewed by Alan Bujtas.
+
+ This is the next step to delete the complex text codepath from Cocoa ports.
+
+ The initial advance contributes to the layout width of text. Its purpose is to move
+ all the visually successive glyphs to the right. For the leftmost run, WidthIterator
+ saves this initial advance to the GlyphBuffer, because knowing it is necessary to
+ compute the paint location of glyphs (inside GlyphBuffer::flatten()). For all other
+ runs other than the leftmost run, those runs' initial advance is added to the advance
+ width of whichever glyph ends up being just to the left of the run. In LTR, this is
+ the last glyph of the last (logical) run, whereas in RTL this is the first glyph of
+ the next (logical) run.
+
+ Because this is just adding infrastructure, it doesn't add any tests yet. This will be
+ tested when we delete the complex text codepath.
+
+ * platform/graphics/ComplexTextController.h: Because we're going to stop using
+ ComplexTextController, we should move this (presumably helpful) comment somewhere
+ where it will be accessible to the Cocoa ports. This would be GlyphBuffer::flatten().
+ * platform/graphics/Font.cpp:
+ (WebCore::Font::applyTransforms const): Return the initial advance.
+ * platform/graphics/Font.h: Ditto.
+ * platform/graphics/FontCascade.cpp:
+ (WebCore::FontCascade::widthOfTextRange const):
+ (WebCore::FontCascade::widthForSimpleText const): Make sure that the initial advance
+ contributes to layout width.
+ (WebCore::FontCascade::layoutSimpleText const): The initial advance is actually NOT
+ supposed to point directly to the first glyph's paint position. See
+ https://bugs.webkit.org/show_bug.cgi?id=228180.
+ (WebCore::FontCascade::drawEmphasisMarks const):
+ * platform/graphics/GlyphBuffer.h:
+ (WebCore::GlyphBuffer::flatten):
+ (WebCore::GlyphBuffer::isFlattened const):
+ * platform/graphics/WidthIterator.cpp:
+ (WebCore::WidthIterator::applyFontTransforms): Return the initial advance.
+ (WebCore::expandWithInitialAdvance):
+ (WebCore::WidthIterator::applyInitialAdvance): This implements the logic above, where
+ the initial advance of non-leftmost runs get added to the visually previous glyph's
+ advance. For LTR, we can just add it directly to the previously-recorded glyph advance.
+ However, for RTL, we have to save the initial advance to a variable, which is named
+ m_leftoverInitialAdvance, and apply it when we encounter the next run. This is because
+ WidthIterator encounters run in logical order.
+ (WebCore::WidthIterator::commitCurrentFontRange):
+ (WebCore::WidthIterator::finalize): For RTL, if the last run has an initial advance,
+ we need to save it to the GlyphBuffer's initial advance field. We know if the last run
+ has an initial advance because there will still be data in m_leftoverInitialAdvance
+ left over.
+ * platform/graphics/WidthIterator.h:
+ * platform/graphics/coretext/FontCoreText.cpp:
+ (WebCore::Font::applyTransforms const): Return the initial advance.
+
+2021-08-19 Myles C. Maxfield <[email protected]>
+
[Cocoa] Stop honoring any dot-prefixed font names
https://bugs.webkit.org/show_bug.cgi?id=228177
Modified: trunk/Source/WebCore/platform/graphics/ComplexTextController.h (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/ComplexTextController.h 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/ComplexTextController.h 2021-08-20 04:53:20 UTC (rev 281294)
@@ -105,33 +105,6 @@
unsigned endOffsetAt(unsigned i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; }
const CGGlyph* glyphs() const { return m_glyphs.data(); }
- /*
- * This is the format of the information CoreText gives us about each run:
- *
- * ----->X (Paint glyph position) X (Paint glyph position) X (Paint glyph position)
- * / 7 7 7
- * / / / /
- * (Initial advance) / / (Glyph origin) / (Glyph origin) / (Glyph origin)
- * ------------------- / / /
- * / / / /
- * X X--------------------------X--------------------------X--------------------------X
- * (text position ^) (base advance) (base advance) (base advance)
- *
- *
- *
- *
- *
- * And here is the output we transform this into (for each run):
- *
- * ----->X------------------------->X------------------------->X
- * / (Paint advance) (Paint advance) \
- * / \
- * (Initial advance) / \ (Paint advance)
- * ------------------- ----------------
- * / \
- * X--------------------------------------------------X--------------------------X--------------------------X
- * (text position ^) (layout advance) (layout advance) (layout advance)
- */
void growInitialAdvanceHorizontally(float delta) { m_initialAdvance.expand(delta, 0); }
FloatSize initialAdvance() const { return m_initialAdvance; }
const FloatSize* baseAdvances() const { return m_baseAdvances.data(); }
Modified: trunk/Source/WebCore/platform/graphics/Font.cpp (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/Font.cpp 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp 2021-08-20 04:53:20 UTC (rev 281294)
@@ -542,8 +542,9 @@
}
#if !USE(CORE_TEXT)
-void Font::applyTransforms(GlyphBuffer&, unsigned, unsigned, bool, bool, const AtomString&, StringView, TextDirection) const
+GlyphBufferAdvance Font::applyTransforms(GlyphBuffer&, unsigned, unsigned, bool, bool, const AtomString&, StringView, TextDirection) const
{
+ return makeGlyphBufferAdvance();
}
#endif
Modified: trunk/Source/WebCore/platform/graphics/Font.h (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/Font.h 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/Font.h 2021-08-20 04:53:20 UTC (rev 281294)
@@ -206,7 +206,7 @@
#endif
bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
- void applyTransforms(GlyphBuffer&, unsigned beginningGlyphIndex, unsigned beginningStringIndex, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection) const;
+ GlyphBufferAdvance applyTransforms(GlyphBuffer&, unsigned beginningGlyphIndex, unsigned beginningStringIndex, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection) const;
// Returns nullopt if none of the glyphs are OT-SVG glyphs.
std::optional<BitVector> findOTSVGGlyphs(const GlyphBufferGlyph*, unsigned count) const;
Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2021-08-20 04:53:20 UTC (rev 281294)
@@ -254,6 +254,8 @@
simpleIterator.advance(run.length(), glyphBuffer);
totalWidth = simpleIterator.runWidthSoFar();
simpleIterator.finalize(glyphBuffer);
+ // FIXME: Finalizing the WidthIterator can affect the total width.
+ // We might need to adjust the various widths we've measured to account for that.
}
if (outWidthBeforeRange)
@@ -319,7 +321,7 @@
glyphBuffer.add(glyph, font, glyphWidth, i);
}
- font.applyTransforms(glyphBuffer, 0, 0, enableKerning(), requiresShaping(), fontDescription().computedLocale(), text, textDirection);
+ auto initialAdvance = font.applyTransforms(glyphBuffer, 0, 0, enableKerning(), requiresShaping(), fontDescription().computedLocale(), text, textDirection);
// This is needed only to match the result of the slow path.
// Same glyph widths but different floating point arithmetic can produce different run width.
float runWidthDifferenceWithTransformApplied = -runWidth;
@@ -327,6 +329,8 @@
runWidthDifferenceWithTransformApplied += WebCore::width(glyphBuffer.advanceAt(i));
runWidth += runWidthDifferenceWithTransformApplied;
+ runWidth += WebCore::width(initialAdvance);
+
if (cacheEntry)
*cacheEntry = runWidth;
return runWidth;
@@ -1270,11 +1274,6 @@
initialAdvance = beforeWidth;
}
glyphBuffer.expandInitialAdvance(initialAdvance);
- if (!glyphBuffer.isEmpty()) {
- // The initial advance is supposed to point directly to the first glyph's paint position.
- // See the ascii-art diagram in ComplexTextController.h.
- glyphBuffer.expandInitialAdvance(makeGlyphBufferAdvance(x(glyphBuffer.originAt(0)), y(glyphBuffer.originAt(0))));
- }
// The glyph buffer is currently in logical order,
// but we need to return the results in visual order.
@@ -1326,6 +1325,7 @@
return !font.isInterstitial() || font.visibility() == Font::Visibility::Visible || customFontNotReadyAction == FontCascade::CustomFontNotReadyAction::UseFallbackIfFontNotReady;
}
+// This function assumes the GlyphBuffer's initial advance has already been incorporated into the start point.
void FontCascade::drawGlyphBuffer(GraphicsContext& context, const GlyphBuffer& glyphBuffer, FloatPoint& point, CustomFontNotReadyAction customFontNotReadyAction) const
{
ASSERT(glyphBuffer.isFlattened());
@@ -1387,6 +1387,9 @@
Glyph markGlyph = markGlyphData.value().glyph;
Glyph spaceGlyph = markFontData->spaceGlyph();
+ // FIXME: This needs to take the initial advance into account.
+ // The problem might actually be harder for complex text, though.
+ // Putting a mark over every glyph probably isn't great in complex scripts.
float middleOfLastGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, 0);
FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(*markFontData, markGlyph), point.y());
Modified: trunk/Source/WebCore/platform/graphics/GlyphBuffer.h (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/GlyphBuffer.h 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/GlyphBuffer.h 2021-08-20 04:53:20 UTC (rev 281294)
@@ -165,31 +165,61 @@
m_offsetsInString.shrink(truncationPoint);
}
- // FontCascade::layoutText() returns a GlyphBuffer which includes layout information that is split
- // into "advances" and "origins". See the ASCII-art diagram in ComplexTextController.h
- // In order to get paint advances, we need to run this "flatten" operation.
- // This merges the layout advances and origins together,
- // leaves the paint advances in the "m_advances" field,
- // and zeros-out the origins in the "m_origins" field.
+ /*
+ * This is the unflattened format:
+ *
+ * X (Paint glyph position) X (Paint glyph position) X (Paint glyph position)
+ * 7 7 7
+ * / / /
+ * / (Origin) / (Origin) / (Origin)
+ * / / /
+ * / / /
+ * X---------------------->X------------------------->X------------------------->X------------------------->X
+ * (text position ^) (Initial advance) (Advance) (Advance) (Advance)
+ *
+ *
+ *
+ *
+ *
+ * And this is what we transform it into:
+ *
+ * ----->X------------------------->X------------------------->X
+ * / (Advance) (Advance) \
+ * / \
+ * (Initial advance) / \ (Advance)
+ * ------------------- ----------------
+ * / \
+ * X X
+ * (text position ^)
+ *
+ * This is an operation that discards all layout information, and preserves only paint information.
+ */
void flatten()
{
+ ASSERT(size() || (!width(m_initialAdvance) && !height(m_initialAdvance)));
+ if (size()) {
+ m_initialAdvance = makeGlyphBufferAdvance(
+ width(m_initialAdvance) + x(m_origins[0]),
+ height(m_initialAdvance) + y(m_origins[0]));
+ }
for (unsigned i = 0; i < size(); ++i) {
m_advances[i] = makeGlyphBufferAdvance(
-x(m_origins[i]) + width(m_advances[i]) + (i + 1 < size() ? x(m_origins[i + 1]) : 0),
- -y(m_origins[i]) + height(m_advances[i]) + (i + 1 < size() ? y(m_origins[i + 1]) : 0)
- );
+ -y(m_origins[i]) + height(m_advances[i]) + (i + 1 < size() ? y(m_origins[i + 1]) : 0));
m_origins[i] = makeGlyphBufferOrigin();
}
}
+#if ASSERT_ENABLED
bool isFlattened() const
{
for (unsigned i = 0; i < size(); ++i) {
- if (m_origins[i] != makeGlyphBufferOrigin())
+ if (x(m_origins[i]) || y(m_origins[i]))
return false;
}
return true;
}
+#endif
private:
void swap(unsigned index1, unsigned index2)
Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.cpp (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/WidthIterator.cpp 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.cpp 2021-08-20 04:53:20 UTC (rev 281294)
@@ -90,13 +90,13 @@
return TransformsType::NotForced;
}
-inline float WidthIterator::applyFontTransforms(GlyphBuffer& glyphBuffer, unsigned lastGlyphCount, unsigned currentCharacterIndex, const Font& font, bool force, CharactersTreatedAsSpace& charactersTreatedAsSpace)
+inline auto WidthIterator::applyFontTransforms(GlyphBuffer& glyphBuffer, unsigned lastGlyphCount, unsigned currentCharacterIndex, const Font& font, bool force, CharactersTreatedAsSpace& charactersTreatedAsSpace) -> ApplyFontTransformsResult
{
ASSERT_UNUSED(currentCharacterIndex, shouldApplyFontTransforms(glyphBuffer, lastGlyphCount, currentCharacterIndex) != WidthIterator::TransformsType::None);
auto glyphBufferSize = glyphBuffer.size();
if (!force && glyphBufferSize <= lastGlyphCount + 1)
- return 0;
+ return { 0, makeGlyphBufferAdvance() };
GlyphBufferAdvance* advances = glyphBuffer.advances(0);
float beforeWidth = 0;
@@ -105,7 +105,7 @@
ASSERT(lastGlyphCount <= glyphBufferSize);
- font.applyTransforms(glyphBuffer, lastGlyphCount, m_currentCharacterIndex, m_enableKerning, m_requiresShaping, m_font.fontDescription().computedLocale(), m_run.text(), m_run.direction());
+ auto initialAdvance = font.applyTransforms(glyphBuffer, lastGlyphCount, m_currentCharacterIndex, m_enableKerning, m_requiresShaping, m_font.fontDescription().computedLocale(), m_run.text(), m_run.direction());
#if USE(CTFONTSHAPEGLYPHS_WORKAROUND)
// <rdar://problem/80798113>: If a character is not in BMP, and we don't have a glyph for it,
@@ -154,7 +154,7 @@
for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i)
afterWidth += width(advances[i]);
- return afterWidth - beforeWidth;
+ return { afterWidth - beforeWidth, initialAdvance };
}
static inline std::pair<bool, bool> expansionLocation(bool ideograph, bool treatAsSpace, bool ltr, bool isAfterExpansion, bool forbidLeftExpansion, bool forbidRightExpansion, bool forceLeftExpansion, bool forceRightExpansion)
@@ -186,11 +186,52 @@
return std::make_pair(expandLeft, expandRight);
}
+static void expandWithInitialAdvance(GlyphBufferAdvance& advanceToExpand, const GlyphBufferAdvance& initialAdvance)
+{
+ setWidth(advanceToExpand, width(advanceToExpand) + width(initialAdvance));
+ setHeight(advanceToExpand, height(advanceToExpand) + height(initialAdvance));
+}
+
+void WidthIterator::applyInitialAdvance(GlyphBuffer& glyphBuffer, std::optional<GlyphBufferAdvance> initialAdvance, unsigned lastGlyphCount)
+{
+ ASSERT(glyphBuffer.size() >= lastGlyphCount);
+
+ if (glyphBuffer.size() <= lastGlyphCount)
+ return;
+
+ ASSERT(lastGlyphCount || (!width(m_leftoverInitialAdvance) && !height(m_leftoverInitialAdvance)));
+
+ if (m_run.direction() == TextDirection::RTL && lastGlyphCount) {
+ auto& visuallyLastAdvance = *glyphBuffer.advances(lastGlyphCount);
+ expandWithInitialAdvance(visuallyLastAdvance, m_leftoverInitialAdvance);
+ m_runWidthSoFar += width(m_leftoverInitialAdvance);
+ m_leftoverInitialAdvance = makeGlyphBufferAdvance();
+ }
+
+ if (initialAdvance) {
+ if (m_run.direction() == TextDirection::RTL)
+ m_leftoverInitialAdvance = initialAdvance.value();
+ else {
+ if (lastGlyphCount) {
+ auto& visuallyPreviousAdvance = *glyphBuffer.advances(lastGlyphCount - 1);
+ expandWithInitialAdvance(visuallyPreviousAdvance, initialAdvance.value());
+ m_runWidthSoFar += width(initialAdvance.value());
+ } else
+ glyphBuffer.expandInitialAdvance(initialAdvance.value());
+ }
+ }
+}
+
void WidthIterator::commitCurrentFontRange(GlyphBuffer& glyphBuffer, unsigned lastGlyphCount, unsigned currentCharacterIndex, const Font& font, const Font& primaryFont, UChar32 character, float widthOfCurrentFontRange, CharactersTreatedAsSpace& charactersTreatedAsSpace)
{
+ std::optional<GlyphBufferAdvance> initialAdvance;
auto transformsType = shouldApplyFontTransforms(glyphBuffer, lastGlyphCount, currentCharacterIndex);
- if (transformsType != TransformsType::None)
- m_runWidthSoFar += applyFontTransforms(glyphBuffer, lastGlyphCount, currentCharacterIndex, font, transformsType == TransformsType::Forced, charactersTreatedAsSpace);
+ if (transformsType != TransformsType::None) {
+ auto applyFontTransformsResult = applyFontTransforms(glyphBuffer, lastGlyphCount, currentCharacterIndex, font, transformsType == TransformsType::Forced, charactersTreatedAsSpace);
+ m_runWidthSoFar += applyFontTransformsResult.additionalAdvance;
+ initialAdvance = applyFontTransformsResult.initialAdvance;
+ }
+ applyInitialAdvance(glyphBuffer, initialAdvance, lastGlyphCount);
m_currentCharacterIndex = currentCharacterIndex;
if (widthOfCurrentFontRange && m_fallbackFonts && &font != &primaryFont) {
@@ -479,7 +520,9 @@
void WidthIterator::finalize(GlyphBuffer& buffer)
{
ASSERT(m_run.rtl() || !m_leftoverJustificationWidth);
- // In LTR this does nothing. In RTL, this adds left width by moving the whole run to the right.
+ // In LTR these do nothing. In RTL, these add left width by moving the whole run to the right.
+ buffer.expandInitialAdvance(m_leftoverInitialAdvance);
+ m_runWidthSoFar += width(m_leftoverInitialAdvance);
buffer.expandInitialAdvance(m_leftoverJustificationWidth);
m_runWidthSoFar += m_leftoverJustificationWidth;
m_leftoverJustificationWidth = 0;
Modified: trunk/Source/WebCore/platform/graphics/WidthIterator.h (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/WidthIterator.h 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/WidthIterator.h 2021-08-20 04:53:20 UTC (rev 281294)
@@ -63,8 +63,13 @@
enum class TransformsType { None, Forced, NotForced };
TransformsType shouldApplyFontTransforms(const GlyphBuffer&, unsigned lastGlyphCount, unsigned currentCharacterIndex) const;
- float applyFontTransforms(GlyphBuffer&, unsigned lastGlyphCount, unsigned currentCharacterIndex, const Font&, bool force, CharactersTreatedAsSpace&);
+ struct ApplyFontTransformsResult {
+ float additionalAdvance;
+ GlyphBufferAdvance initialAdvance;
+ };
+ ApplyFontTransformsResult applyFontTransforms(GlyphBuffer&, unsigned lastGlyphCount, unsigned currentCharacterIndex, const Font&, bool force, CharactersTreatedAsSpace&);
void commitCurrentFontRange(GlyphBuffer&, unsigned lastGlyphCount, unsigned currentCharacterIndex, const Font&, const Font& primaryFont, UChar32 character, float widthOfCurrentFontRange, CharactersTreatedAsSpace&);
+ void applyInitialAdvance(GlyphBuffer&, std::optional<GlyphBufferAdvance> initialAdvance, unsigned lastGlyphCount);
bool hasExtraSpacing() const;
void applyExtraSpacingAfterShaping(GlyphBuffer&, unsigned characterStartIndex, unsigned glyphBufferStartIndex, unsigned characterDestinationIndex, float startingRunWidth);
@@ -82,6 +87,7 @@
HashSet<const Font*>* m_fallbackFonts { nullptr };
std::optional<unsigned> m_lastCharacterIndex;
+ GlyphBufferAdvance m_leftoverInitialAdvance { makeGlyphBufferAdvance() };
unsigned m_currentCharacterIndex { 0 };
float m_leftoverJustificationWidth { 0 };
float m_runWidthSoFar { 0 };
Modified: trunk/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp (281293 => 281294)
--- trunk/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp 2021-08-20 04:07:08 UTC (rev 281293)
+++ trunk/Source/WebCore/platform/graphics/coretext/FontCoreText.cpp 2021-08-20 04:53:20 UTC (rev 281294)
@@ -584,11 +584,10 @@
#endif
-void Font::applyTransforms(GlyphBuffer& glyphBuffer, unsigned beginningGlyphIndex, unsigned beginningStringIndex, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection textDirection) const
+GlyphBufferAdvance Font::applyTransforms(GlyphBuffer& glyphBuffer, unsigned beginningGlyphIndex, unsigned beginningStringIndex, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection textDirection) const
{
UNUSED_PARAM(requiresShaping);
- // FIXME: Implement GlyphBuffer initial advance.
#if USE(CTFONTSHAPEGLYPHS)
auto handler = ^(CFRange range, CGGlyph** newGlyphsPointer, CGSize** newAdvancesPointer, CGPoint** newOffsetsPointer, CFIndex** newIndicesPointer)
{
@@ -616,18 +615,23 @@
for (unsigned i = 0; i < glyphBuffer.size() - beginningGlyphIndex; ++i)
glyphBuffer.offsetsInString(beginningGlyphIndex)[i] -= beginningStringIndex;
- CTFontShapeGlyphs(
+ auto numberOfInputGlyphs = glyphBuffer.size() - beginningGlyphIndex;
+
+ auto initialAdvance = CTFontShapeGlyphs(
m_platformData.ctFont(),
glyphBuffer.glyphs(beginningGlyphIndex),
- reinterpret_cast<CGSize*>(glyphBuffer.advances(beginningGlyphIndex)),
- reinterpret_cast<CGPoint*>(glyphBuffer.origins(beginningGlyphIndex)),
+ glyphBuffer.advances(beginningGlyphIndex),
+ glyphBuffer.origins(beginningGlyphIndex),
glyphBuffer.offsetsInString(beginningGlyphIndex),
reinterpret_cast<const UniChar*>(upconvertedCharacters.get()),
- glyphBuffer.size() - beginningGlyphIndex,
+ numberOfInputGlyphs,
options,
localeString.get(),
handler);
+ ASSERT(numberOfInputGlyphs || glyphBuffer.size() == beginningGlyphIndex);
+ ASSERT(numberOfInputGlyphs || (!initialAdvance.width && !initialAdvance.height));
+
for (unsigned i = 0; i < glyphBuffer.size() - beginningGlyphIndex; ++i)
glyphBuffer.offsetsInString(beginningGlyphIndex)[i] += beginningStringIndex;
@@ -652,11 +656,15 @@
CTFontTransformOptions options = (enableKerning ? kCTFontTransformApplyPositioning : 0) | kCTFontTransformApplyShaping;
CTFontTransformGlyphs(m_platformData.ctFont(), glyphBuffer.glyphs(beginningGlyphIndex), reinterpret_cast<CGSize*>(glyphBuffer.advances(beginningGlyphIndex)), glyphBuffer.size() - beginningGlyphIndex, options);
+
+ auto initialAdvance = makeGlyphBufferAdvance();
#endif
// See the comment above in this function where the other call to reverse() is.
if (textDirection == TextDirection::RTL)
glyphBuffer.reverse(beginningGlyphIndex, glyphBuffer.size() - beginningGlyphIndex);
+
+ return initialAdvance;
}
static int extractNumber(CFNumberRef number)