| Differences between
and this patch
- a/Source/WebCore/ChangeLog +42 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2017-02-06  Myles C. Maxfield  <mmaxfield@apple.com>
2
3
        Migrate ComplexTextController to use platform-independent types
4
        https://bugs.webkit.org/show_bug.cgi?id=167833
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        ComplexTextController will eventually be used on all ports to perform complex text layout.
9
        This is a mechanical patch which migrates the shared parts of ComplexTextController away from
10
        using CoreGraphics and CoreFoundation types in favor of WebCore/platform types. Eventually,
11
        ComplexTextController will get moved to PAL but there is a layering violation (TextLayout) to
12
        fix first.
13
14
        No new tests because there is no behavior change.
15
16
        * platform/graphics/GlyphBuffer.h:
17
        (WebCore::GlyphBufferAdvance::GlyphBufferAdvance):
18
        * platform/graphics/mac/ComplexTextController.cpp:
19
        (WebCore::ComplexTextController::offsetForPosition):
20
        (WebCore::advanceByCombiningCharacterSequence):
21
        (WebCore::ComplexTextController::ComplexTextRun::indexAt):
22
        (WebCore::ComplexTextController::ComplexTextRun::setIsNonMonotonic):
23
        (WebCore::ComplexTextController::advance):
24
        (WebCore::ComplexTextController::adjustGlyphsAndAdvances):
25
        * platform/graphics/mac/ComplexTextController.h:
26
        (WebCore::ComplexTextController::ComplexTextRun::create):
27
        (WebCore::ComplexTextController::ComplexTextRun::stringLength):
28
        (WebCore::ComplexTextController::ComplexTextRun::indexBegin):
29
        (WebCore::ComplexTextController::ComplexTextRun::indexEnd):
30
        (WebCore::ComplexTextController::ComplexTextRun::endOffsetAt):
31
        (WebCore::ComplexTextController::ComplexTextRun::glyphs):
32
        (WebCore::ComplexTextController::ComplexTextRun::growInitialAdvanceHorizontally):
33
        (WebCore::ComplexTextController::ComplexTextRun::initialAdvance):
34
        (WebCore::ComplexTextController::ComplexTextRun::baseAdvances):
35
        (WebCore::ComplexTextController::ComplexTextRun::glyphOrigins):
36
        (WebCore::ComplexTextController::glyphOrigin):
37
        (WebCore::ComplexTextController::ComplexTextRun::createForTesting): Deleted.
38
        * platform/graphics/mac/ComplexTextControllerCoreText.mm:
39
        (SOFT_LINK):
40
        (WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun):
41
        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
42
1
2017-02-06  Said Abou-Hallawa  <sabouhallawa@apple.com>
43
2017-02-06  Said Abou-Hallawa  <sabouhallawa@apple.com>
2
44
3
        Rename AnimationController to CSSAnimationController
45
        Rename AnimationController to CSSAnimationController
- a/Source/WebCore/platform/graphics/GlyphBuffer.h -1 / +6 lines
Lines 62-68 typedef Glyph GlyphBufferGlyph; a/Source/WebCore/platform/graphics/GlyphBuffer.h_sec1
62
struct GlyphBufferAdvance : CGSize {
62
struct GlyphBufferAdvance : CGSize {
63
public:
63
public:
64
    GlyphBufferAdvance() : CGSize(CGSizeZero) { }
64
    GlyphBufferAdvance() : CGSize(CGSizeZero) { }
65
    GlyphBufferAdvance(CGSize size) : CGSize(size)
65
    GlyphBufferAdvance(CGSize size)
66
        : CGSize(size)
67
    {
68
    }
69
    GlyphBufferAdvance(float width, float height)
70
        : CGSize(CGSizeMake(width, height))
66
    {
71
    {
67
    }
72
    }
68
73
- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp -73 / +71 lines
Lines 175-235 unsigned ComplexTextController::offsetForPosition(float h, bool includePartialGl a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec1
175
    if (h < 0)
175
    if (h < 0)
176
        return m_run.ltr() ? 0 : m_end;
176
        return m_run.ltr() ? 0 : m_end;
177
177
178
    CGFloat x = h;
178
    float x = h;
179
179
180
    size_t runCount = m_complexTextRuns.size();
180
    size_t runCount = m_complexTextRuns.size();
181
    size_t offsetIntoAdjustedGlyphs = 0;
181
    unsigned offsetIntoAdjustedGlyphs = 0;
182
182
183
    for (size_t r = 0; r < runCount; ++r) {
183
    for (size_t r = 0; r < runCount; ++r) {
184
        const ComplexTextRun& complexTextRun = *m_complexTextRuns[r];
184
        const ComplexTextRun& complexTextRun = *m_complexTextRuns[r];
185
        for (unsigned j = 0; j < complexTextRun.glyphCount(); ++j) {
185
        for (unsigned j = 0; j < complexTextRun.glyphCount(); ++j) {
186
            size_t index = offsetIntoAdjustedGlyphs + j;
186
            unsigned index = offsetIntoAdjustedGlyphs + j;
187
            CGFloat adjustedAdvance = m_adjustedBaseAdvances[index].width;
187
            float adjustedAdvance = m_adjustedBaseAdvances[index].width();
188
            if (x < adjustedAdvance) {
188
            if (x < adjustedAdvance) {
189
                CFIndex hitGlyphStart = complexTextRun.indexAt(j);
189
                unsigned hitGlyphStart = complexTextRun.indexAt(j);
190
                CFIndex hitGlyphEnd;
190
                unsigned hitGlyphEnd;
191
                if (m_run.ltr())
191
                if (m_run.ltr())
192
                    hitGlyphEnd = std::max<CFIndex>(hitGlyphStart, j + 1 < complexTextRun.glyphCount() ? complexTextRun.indexAt(j + 1) : static_cast<CFIndex>(complexTextRun.indexEnd()));
192
                    hitGlyphEnd = std::max(hitGlyphStart, j + 1 < complexTextRun.glyphCount() ? complexTextRun.indexAt(j + 1) : complexTextRun.indexEnd());
193
                else
193
                else
194
                    hitGlyphEnd = std::max<CFIndex>(hitGlyphStart, j > 0 ? complexTextRun.indexAt(j - 1) : static_cast<CFIndex>(complexTextRun.indexEnd()));
194
                    hitGlyphEnd = std::max(hitGlyphStart, j > 0 ? complexTextRun.indexAt(j - 1) : complexTextRun.indexEnd());
195
195
196
                // FIXME: Instead of dividing the glyph's advance equally between the characters, this
196
                // FIXME: Instead of dividing the glyph's advance equally between the characters, this
197
                // could use the glyph's "ligature carets". This is available in CoreText via CTFontGetLigatureCaretPositions().
197
                // could use the glyph's "ligature carets". This is available in CoreText via CTFontGetLigatureCaretPositions().
198
                CFIndex hitIndex = hitGlyphStart + (hitGlyphEnd - hitGlyphStart) * (m_run.ltr() ? x / adjustedAdvance : 1 - x / adjustedAdvance);
198
                unsigned hitIndex = hitGlyphStart + (hitGlyphEnd - hitGlyphStart) * (m_run.ltr() ? x / adjustedAdvance : 1 - x / adjustedAdvance);
199
                int stringLength = complexTextRun.stringLength();
199
                unsigned stringLength = complexTextRun.stringLength();
200
                UBreakIterator* cursorPositionIterator = cursorMovementIterator(StringView(complexTextRun.characters(), stringLength));
200
                UBreakIterator* cursorPositionIterator = cursorMovementIterator(StringView(complexTextRun.characters(), stringLength));
201
                int clusterStart;
201
                unsigned clusterStart;
202
                if (ubrk_isBoundary(cursorPositionIterator, hitIndex))
202
                if (ubrk_isBoundary(cursorPositionIterator, hitIndex))
203
                    clusterStart = hitIndex;
203
                    clusterStart = hitIndex;
204
                else {
204
                else {
205
                    clusterStart = ubrk_preceding(cursorPositionIterator, hitIndex);
205
                    int preceeding = ubrk_preceding(cursorPositionIterator, hitIndex);
206
                    if (clusterStart == UBRK_DONE)
206
                    clusterStart = preceeding == UBRK_DONE ? 0 : preceeding;
207
                        clusterStart = 0;
208
                }
207
                }
209
208
210
                if (!includePartialGlyphs)
209
                if (!includePartialGlyphs)
211
                    return complexTextRun.stringLocation() + clusterStart;
210
                    return complexTextRun.stringLocation() + clusterStart;
212
211
213
                int clusterEnd = ubrk_following(cursorPositionIterator, hitIndex);
212
                int following = ubrk_following(cursorPositionIterator, hitIndex);
214
                if (clusterEnd == UBRK_DONE)
213
                unsigned clusterEnd = following == UBRK_DONE ? stringLength : following;
215
                    clusterEnd = stringLength;
216
214
217
                CGFloat clusterWidth;
215
                float clusterWidth;
218
                // FIXME: The search stops at the boundaries of complexTextRun. In theory, it should go on into neighboring ComplexTextRuns
216
                // FIXME: The search stops at the boundaries of complexTextRun. In theory, it should go on into neighboring ComplexTextRuns
219
                // derived from the same CTLine. In practice, we do not expect there to be more than one CTRun in a CTLine, as no
217
                // derived from the same CTLine. In practice, we do not expect there to be more than one CTRun in a CTLine, as no
220
                // reordering and no font fallback should occur within a CTLine.
218
                // reordering and no font fallback should occur within a CTLine.
221
                if (clusterEnd - clusterStart > 1) {
219
                if (clusterEnd - clusterStart > 1) {
222
                    clusterWidth = adjustedAdvance;
220
                    clusterWidth = adjustedAdvance;
223
                    int firstGlyphBeforeCluster = j - 1;
221
                    if (j) {
224
                    while (firstGlyphBeforeCluster >= 0 && complexTextRun.indexAt(firstGlyphBeforeCluster) >= clusterStart && complexTextRun.indexAt(firstGlyphBeforeCluster) < clusterEnd) {
222
                        unsigned firstGlyphBeforeCluster = j - 1;
225
                        CGFloat width = m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width;
223
                        while (complexTextRun.indexAt(firstGlyphBeforeCluster) >= clusterStart && complexTextRun.indexAt(firstGlyphBeforeCluster) < clusterEnd) {
226
                        clusterWidth += width;
224
                            float width = m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width();
227
                        x += width;
225
                            clusterWidth += width;
228
                        firstGlyphBeforeCluster--;
226
                            x += width;
227
                            if (!firstGlyphBeforeCluster)
228
                                break;
229
                            firstGlyphBeforeCluster--;
230
                        }
229
                    }
231
                    }
230
                    unsigned firstGlyphAfterCluster = j + 1;
232
                    unsigned firstGlyphAfterCluster = j + 1;
231
                    while (firstGlyphAfterCluster < complexTextRun.glyphCount() && complexTextRun.indexAt(firstGlyphAfterCluster) >= clusterStart && complexTextRun.indexAt(firstGlyphAfterCluster) < clusterEnd) {
233
                    while (firstGlyphAfterCluster < complexTextRun.glyphCount() && complexTextRun.indexAt(firstGlyphAfterCluster) >= clusterStart && complexTextRun.indexAt(firstGlyphAfterCluster) < clusterEnd) {
232
                        clusterWidth += m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width;
234
                        clusterWidth += m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width();
233
                        firstGlyphAfterCluster++;
235
                        firstGlyphAfterCluster++;
234
                    }
236
                    }
235
                } else {
237
                } else {
Lines 238-245 unsigned ComplexTextController::offsetForPosition(float h, bool includePartialGl a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec2
238
                }
240
                }
239
                if (x <= clusterWidth / 2)
241
                if (x <= clusterWidth / 2)
240
                    return complexTextRun.stringLocation() + (m_run.ltr() ? clusterStart : clusterEnd);
242
                    return complexTextRun.stringLocation() + (m_run.ltr() ? clusterStart : clusterEnd);
241
                else
243
                return complexTextRun.stringLocation() + (m_run.ltr() ? clusterEnd : clusterStart);
242
                    return complexTextRun.stringLocation() + (m_run.ltr() ? clusterEnd : clusterStart);
243
            }
244
            }
244
            x -= adjustedAdvance;
245
            x -= adjustedAdvance;
245
        }
246
        }
Lines 270-278 static bool advanceByCombiningCharacterSequence(const UChar*& iterator, const UC a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec3
270
    bool sawJoiner = false;
271
    bool sawJoiner = false;
271
    while (iterator < end) {
272
    while (iterator < end) {
272
        UChar32 nextCharacter;
273
        UChar32 nextCharacter;
273
        int markLength = 0;
274
        unsigned markLength = 0;
274
        bool shouldContinue = false;
275
        bool shouldContinue = false;
275
        U16_NEXT(iterator, markLength, end - iterator, nextCharacter);
276
        ASSERT(end >= iterator);
277
        U16_NEXT(iterator, markLength, static_cast<unsigned>(end - iterator), nextCharacter);
276
278
277
        if (isVariationSelector(nextCharacter) || isEmojiFitzpatrickModifier(nextCharacter))
279
        if (isVariationSelector(nextCharacter) || isEmojiFitzpatrickModifier(nextCharacter))
278
            shouldContinue = true;
280
            shouldContinue = true;
Lines 453-459 void ComplexTextController::collectComplexTextRuns() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec4
453
        m_complexTextRuns.reverse();
455
        m_complexTextRuns.reverse();
454
}
456
}
455
457
456
CFIndex ComplexTextController::ComplexTextRun::indexAt(size_t i) const
458
unsigned ComplexTextController::ComplexTextRun::indexAt(unsigned i) const
457
{
459
{
458
    ASSERT(i < m_glyphCount);
460
    ASSERT(i < m_glyphCount);
459
461
Lines 466-480 void ComplexTextController::ComplexTextRun::setIsNonMonotonic() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec5
466
    m_isMonotonic = false;
468
    m_isMonotonic = false;
467
469
468
    Vector<bool, 64> mappedIndices(m_stringLength, false);
470
    Vector<bool, 64> mappedIndices(m_stringLength, false);
469
    for (size_t i = 0; i < m_glyphCount; ++i) {
471
    for (unsigned i = 0; i < m_glyphCount; ++i) {
470
        ASSERT(indexAt(i) < static_cast<CFIndex>(m_stringLength));
472
        ASSERT(indexAt(i) < m_stringLength);
471
        mappedIndices[indexAt(i)] = true;
473
        mappedIndices[indexAt(i)] = true;
472
    }
474
    }
473
475
474
    m_glyphEndOffsets.grow(m_glyphCount);
476
    m_glyphEndOffsets.grow(m_glyphCount);
475
    for (unsigned i = 0; i < m_glyphCount; ++i) {
477
    for (unsigned i = 0; i < m_glyphCount; ++i) {
476
        CFIndex nextMappedIndex = m_indexEnd;
478
        unsigned nextMappedIndex = m_indexEnd;
477
        for (size_t j = indexAt(i) + 1; j < m_stringLength; ++j) {
479
        for (unsigned j = indexAt(i) + 1; j < m_stringLength; ++j) {
478
            if (mappedIndices[j]) {
480
            if (mappedIndices[j]) {
479
                nextMappedIndex = j;
481
                nextMappedIndex = j;
480
                break;
482
                break;
Lines 580-586 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, G a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec6
580
    while (m_currentRun < runCount) {
582
    while (m_currentRun < runCount) {
581
        const ComplexTextRun& complexTextRun = *m_complexTextRuns[currentRunIndex];
583
        const ComplexTextRun& complexTextRun = *m_complexTextRuns[currentRunIndex];
582
        bool ltr = complexTextRun.isLTR();
584
        bool ltr = complexTextRun.isLTR();
583
        size_t glyphCount = complexTextRun.glyphCount();
585
        unsigned glyphCount = complexTextRun.glyphCount();
584
        unsigned glyphIndexIntoCurrentRun = ltr ? m_glyphInCurrentRun : glyphCount - 1 - m_glyphInCurrentRun;
586
        unsigned glyphIndexIntoCurrentRun = ltr ? m_glyphInCurrentRun : glyphCount - 1 - m_glyphInCurrentRun;
585
        unsigned glyphIndexIntoComplexTextController = indexOfLeftmostGlyphInCurrentRun + glyphIndexIntoCurrentRun;
587
        unsigned glyphIndexIntoComplexTextController = indexOfLeftmostGlyphInCurrentRun + glyphIndexIntoCurrentRun;
586
        if (fallbackFonts && &complexTextRun.font() != &m_font.primaryFont())
588
        if (fallbackFonts && &complexTextRun.font() != &m_font.primaryFont())
Lines 590-630 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, G a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec7
590
        // When leftmostGlyph is 0, it represents the first glyph to draw, taking into
592
        // When leftmostGlyph is 0, it represents the first glyph to draw, taking into
591
        // account the text direction.
593
        // account the text direction.
592
        if (!indexOfLeftmostGlyphInCurrentRun && glyphBuffer)
594
        if (!indexOfLeftmostGlyphInCurrentRun && glyphBuffer)
593
            glyphBuffer->setInitialAdvance(complexTextRun.initialAdvance());
595
            glyphBuffer->setInitialAdvance(GlyphBufferAdvance(complexTextRun.initialAdvance().width(), complexTextRun.initialAdvance().height()));
594
596
595
        while (m_glyphInCurrentRun < glyphCount) {
597
        while (m_glyphInCurrentRun < glyphCount) {
596
            unsigned glyphStartOffset = complexTextRun.indexAt(glyphIndexIntoCurrentRun);
598
            unsigned glyphStartOffset = complexTextRun.indexAt(glyphIndexIntoCurrentRun);
597
            unsigned glyphEndOffset;
599
            unsigned glyphEndOffset;
598
            if (complexTextRun.isMonotonic()) {
600
            if (complexTextRun.isMonotonic()) {
599
                if (ltr)
601
                if (ltr)
600
                    glyphEndOffset = std::max<unsigned>(glyphStartOffset, static_cast<unsigned>(glyphIndexIntoCurrentRun + 1 < glyphCount ? complexTextRun.indexAt(glyphIndexIntoCurrentRun + 1) : complexTextRun.indexEnd()));
602
                    glyphEndOffset = std::max(glyphStartOffset, glyphIndexIntoCurrentRun + 1 < glyphCount ? complexTextRun.indexAt(glyphIndexIntoCurrentRun + 1) : complexTextRun.indexEnd());
601
                else
603
                else
602
                    glyphEndOffset = std::max<unsigned>(glyphStartOffset, static_cast<unsigned>(glyphIndexIntoCurrentRun > 0 ? complexTextRun.indexAt(glyphIndexIntoCurrentRun - 1) : complexTextRun.indexEnd()));
604
                    glyphEndOffset = std::max(glyphStartOffset, glyphIndexIntoCurrentRun > 0 ? complexTextRun.indexAt(glyphIndexIntoCurrentRun - 1) : complexTextRun.indexEnd());
603
            } else
605
            } else
604
                glyphEndOffset = complexTextRun.endOffsetAt(glyphIndexIntoCurrentRun);
606
                glyphEndOffset = complexTextRun.endOffsetAt(glyphIndexIntoCurrentRun);
605
607
606
            CGSize adjustedBaseAdvance = m_adjustedBaseAdvances[glyphIndexIntoComplexTextController];
608
            FloatSize adjustedBaseAdvance = m_adjustedBaseAdvances[glyphIndexIntoComplexTextController];
607
609
608
            if (glyphStartOffset + complexTextRun.stringLocation() >= m_currentCharacter)
610
            if (glyphStartOffset + complexTextRun.stringLocation() >= m_currentCharacter)
609
                return;
611
                return;
610
612
611
            if (glyphBuffer && !m_characterInCurrentGlyph) {
613
            if (glyphBuffer && !m_characterInCurrentGlyph) {
612
                auto currentGlyphOrigin = glyphOrigin(glyphIndexIntoComplexTextController);
614
                auto currentGlyphOrigin = glyphOrigin(glyphIndexIntoComplexTextController);
613
                GlyphBufferAdvance paintAdvance = adjustedBaseAdvance;
615
                GlyphBufferAdvance paintAdvance(adjustedBaseAdvance);
614
                if (!glyphIndexIntoCurrentRun) {
616
                if (!glyphIndexIntoCurrentRun) {
615
                    // The first layout advance of every run includes the "initial layout advance." However, here, we need
617
                    // The first layout advance of every run includes the "initial layout advance." However, here, we need
616
                    // paint advances, so subtract it out before transforming the layout advance into a paint advance.
618
                    // paint advances, so subtract it out before transforming the layout advance into a paint advance.
617
                    paintAdvance.setWidth(paintAdvance.width() - (complexTextRun.initialAdvance().width - currentGlyphOrigin.x));
619
                    paintAdvance.setWidth(paintAdvance.width() - (complexTextRun.initialAdvance().width() - currentGlyphOrigin.x()));
618
                    paintAdvance.setHeight(paintAdvance.height() - (complexTextRun.initialAdvance().height - currentGlyphOrigin.y));
620
                    paintAdvance.setHeight(paintAdvance.height() - (complexTextRun.initialAdvance().height() - currentGlyphOrigin.y()));
619
                }
621
                }
620
                paintAdvance.setWidth(paintAdvance.width() + glyphOrigin(glyphIndexIntoComplexTextController + 1).x - currentGlyphOrigin.x);
622
                paintAdvance.setWidth(paintAdvance.width() + glyphOrigin(glyphIndexIntoComplexTextController + 1).x() - currentGlyphOrigin.x());
621
                paintAdvance.setHeight(paintAdvance.height() + glyphOrigin(glyphIndexIntoComplexTextController + 1).y - currentGlyphOrigin.y);
623
                paintAdvance.setHeight(paintAdvance.height() + glyphOrigin(glyphIndexIntoComplexTextController + 1).y() - currentGlyphOrigin.y());
622
                if (glyphIndexIntoCurrentRun == glyphCount - 1 && currentRunIndex + 1 < runCount) {
624
                if (glyphIndexIntoCurrentRun == glyphCount - 1 && currentRunIndex + 1 < runCount) {
623
                    // Our paint advance points to the end of the run. However, the next run may have an
625
                    // Our paint advance points to the end of the run. However, the next run may have an
624
                    // initial advance, and our paint advance needs to point to the location of the next
626
                    // initial advance, and our paint advance needs to point to the location of the next
625
                    // glyph. So, we need to add in the next run's initial advance.
627
                    // glyph. So, we need to add in the next run's initial advance.
626
                    paintAdvance.setWidth(paintAdvance.width() - glyphOrigin(glyphIndexIntoComplexTextController + 1).x + m_complexTextRuns[currentRunIndex + 1]->initialAdvance().width);
628
                    paintAdvance.setWidth(paintAdvance.width() - glyphOrigin(glyphIndexIntoComplexTextController + 1).x() + m_complexTextRuns[currentRunIndex + 1]->initialAdvance().width());
627
                    paintAdvance.setHeight(paintAdvance.height() - glyphOrigin(glyphIndexIntoComplexTextController + 1).y + m_complexTextRuns[currentRunIndex + 1]->initialAdvance().height);
629
                    paintAdvance.setHeight(paintAdvance.height() - glyphOrigin(glyphIndexIntoComplexTextController + 1).y() + m_complexTextRuns[currentRunIndex + 1]->initialAdvance().height());
628
                }
630
                }
629
                paintAdvance.setHeight(-paintAdvance.height()); // Increasing y points down
631
                paintAdvance.setHeight(-paintAdvance.height()); // Increasing y points down
630
                glyphBuffer->add(m_adjustedGlyphs[glyphIndexIntoComplexTextController], &complexTextRun.font(), paintAdvance, complexTextRun.indexAt(m_glyphInCurrentRun));
632
                glyphBuffer->add(m_adjustedGlyphs[glyphIndexIntoComplexTextController], &complexTextRun.font(), paintAdvance, complexTextRun.indexAt(m_glyphInCurrentRun));
Lines 632-638 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, G a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec8
632
634
633
            unsigned oldCharacterInCurrentGlyph = m_characterInCurrentGlyph;
635
            unsigned oldCharacterInCurrentGlyph = m_characterInCurrentGlyph;
634
            m_characterInCurrentGlyph = std::min(m_currentCharacter - complexTextRun.stringLocation(), glyphEndOffset) - glyphStartOffset;
636
            m_characterInCurrentGlyph = std::min(m_currentCharacter - complexTextRun.stringLocation(), glyphEndOffset) - glyphStartOffset;
635
            m_runWidthSoFar += adjustedBaseAdvance.width * runWidthSoFarFraction(glyphStartOffset, glyphEndOffset, oldCharacterInCurrentGlyph, iterationStyle);
637
            m_runWidthSoFar += adjustedBaseAdvance.width() * runWidthSoFarFraction(glyphStartOffset, glyphEndOffset, oldCharacterInCurrentGlyph, iterationStyle);
636
638
637
            if (glyphEndOffset + complexTextRun.stringLocation() > m_currentCharacter)
639
            if (glyphEndOffset + complexTextRun.stringLocation() > m_currentCharacter)
638
                return;
640
                return;
Lines 681-687 static inline std::pair<bool, bool> expansionLocation(bool ideograph, bool treat a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec9
681
void ComplexTextController::adjustGlyphsAndAdvances()
683
void ComplexTextController::adjustGlyphsAndAdvances()
682
{
684
{
683
    bool afterExpansion = (m_run.expansionBehavior() & LeadingExpansionMask) == ForbidLeadingExpansion;
685
    bool afterExpansion = (m_run.expansionBehavior() & LeadingExpansionMask) == ForbidLeadingExpansion;
684
    CGFloat widthSinceLastCommit = 0;
686
    float widthSinceLastCommit = 0;
685
    size_t runCount = m_complexTextRuns.size();
687
    size_t runCount = m_complexTextRuns.size();
686
    bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled();
688
    bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled();
687
    bool runForcesLeadingExpansion = (m_run.expansionBehavior() & LeadingExpansionMask) == ForceLeadingExpansion;
689
    bool runForcesLeadingExpansion = (m_run.expansionBehavior() & LeadingExpansionMask) == ForceLeadingExpansion;
Lines 699-715 void ComplexTextController::adjustGlyphsAndAdvances() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec10
699
            m_isLTROnly = false;
701
            m_isLTROnly = false;
700
702
701
        const CGGlyph* glyphs = complexTextRun.glyphs();
703
        const CGGlyph* glyphs = complexTextRun.glyphs();
702
        const CGSize* advances = complexTextRun.baseAdvances();
704
        const FloatSize* advances = complexTextRun.baseAdvances();
703
705
704
        bool lastRun = runIndex + 1 == runCount;
706
        bool lastRun = runIndex + 1 == runCount;
705
        float spaceWidth = font.spaceWidth() - font.syntheticBoldOffset();
707
        float spaceWidth = font.spaceWidth() - font.syntheticBoldOffset();
706
        const UChar* cp = complexTextRun.characters();
708
        const UChar* cp = complexTextRun.characters();
707
        CGPoint glyphOrigin = CGPointZero;
709
        FloatPoint glyphOrigin;
708
        CFIndex lastCharacterIndex = m_run.ltr() ? std::numeric_limits<CFIndex>::min() : std::numeric_limits<CFIndex>::max();
710
        unsigned lastCharacterIndex = m_run.ltr() ? std::numeric_limits<unsigned>::min() : std::numeric_limits<unsigned>::max();
709
        bool isMonotonic = true;
711
        bool isMonotonic = true;
710
712
711
        for (unsigned i = 0; i < glyphCount; i++) {
713
        for (unsigned i = 0; i < glyphCount; i++) {
712
            CFIndex characterIndex = complexTextRun.indexAt(i);
714
            unsigned characterIndex = complexTextRun.indexAt(i);
713
            if (m_run.ltr()) {
715
            if (m_run.ltr()) {
714
                if (characterIndex < lastCharacterIndex)
716
                if (characterIndex < lastCharacterIndex)
715
                    isMonotonic = false;
717
                    isMonotonic = false;
Lines 729-763 void ComplexTextController::adjustGlyphsAndAdvances() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec11
729
731
730
            bool treatAsSpace = FontCascade::treatAsSpace(ch);
732
            bool treatAsSpace = FontCascade::treatAsSpace(ch);
731
            CGGlyph glyph = treatAsSpace ? font.spaceGlyph() : glyphs[i];
733
            CGGlyph glyph = treatAsSpace ? font.spaceGlyph() : glyphs[i];
732
            CGSize advance = treatAsSpace ? CGSizeMake(spaceWidth, advances[i].height) : advances[i];
734
            FloatSize advance = treatAsSpace ? FloatSize(spaceWidth, advances[i].height()) : advances[i];
733
735
734
            if (ch == '\t' && m_run.allowTabs())
736
            if (ch == '\t' && m_run.allowTabs())
735
                advance.width = m_font.tabWidth(font, m_run.tabSize(), m_run.xPos() + m_totalWidth + widthSinceLastCommit);
737
                advance.setWidth(m_font.tabWidth(font, m_run.tabSize(), m_run.xPos() + m_totalWidth + widthSinceLastCommit));
736
            else if (FontCascade::treatAsZeroWidthSpace(ch) && !treatAsSpace) {
738
            else if (FontCascade::treatAsZeroWidthSpace(ch) && !treatAsSpace) {
737
                advance.width = 0;
739
                advance.setWidth(0);
738
                glyph = font.spaceGlyph();
740
                glyph = font.spaceGlyph();
739
            }
741
            }
740
742
741
            if (!i) {
743
            if (!i) {
742
                advance.width += complexTextRun.initialAdvance().width;
744
                advance.expand(complexTextRun.initialAdvance().width(), complexTextRun.initialAdvance().height());
743
                advance.height += complexTextRun.initialAdvance().height;
745
                if (auto* origins = complexTextRun.glyphOrigins())
744
                if (auto* origins = complexTextRun.glyphOrigins()) {
746
                    advance.expand(-origins[0].x(), -origins[0].y());
745
                    advance.width -= origins[0].x;
746
                    advance.height -= origins[0].y;
747
                }
748
            }
747
            }
749
748
750
            advance.width += font.syntheticBoldOffset();
749
            advance.expand(font.syntheticBoldOffset(), 0);
751
750
752
            if (hasExtraSpacing) {
751
            if (hasExtraSpacing) {
753
                // If we're a glyph with an advance, add in letter-spacing.
752
                // If we're a glyph with an advance, add in letter-spacing.
754
                // That way we weed out zero width lurkers.  This behavior matches the fast text code path.
753
                // That way we weed out zero width lurkers. This behavior matches the fast text code path.
755
                if (advance.width)
754
                if (advance.width())
756
                    advance.width += m_font.letterSpacing();
755
                    advance.expand(m_font.letterSpacing(), 0);
757
756
758
                unsigned characterIndexInRun = characterIndex + complexTextRun.stringLocation();
757
                unsigned characterIndexInRun = characterIndex + complexTextRun.stringLocation();
759
                bool isFirstCharacter = !(characterIndex + complexTextRun.stringLocation());
758
                bool isFirstCharacter = !(characterIndex + complexTextRun.stringLocation());
760
                bool isLastCharacter = static_cast<unsigned>(characterIndexInRun + 1) == m_run.length() || (U16_IS_LEAD(ch) && static_cast<unsigned>(characterIndexInRun + 2) == m_run.length() && U16_IS_TRAIL(*(cp + characterIndex + 1)));
759
                bool isLastCharacter = characterIndexInRun + 1 == m_run.length() || (U16_IS_LEAD(ch) && characterIndexInRun + 2 == m_run.length() && U16_IS_TRAIL(*(cp + characterIndex + 1)));
761
760
762
                bool forceLeadingExpansion = false; // On the left, regardless of m_run.ltr()
761
                bool forceLeadingExpansion = false; // On the left, regardless of m_run.ltr()
763
                bool forceTrailingExpansion = false; // On the right, regardless of m_run.ltr()
762
                bool forceTrailingExpansion = false; // On the right, regardless of m_run.ltr()
Lines 779-791 void ComplexTextController::adjustGlyphsAndAdvances() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec12
779
                        bool expandLeft, expandRight;
778
                        bool expandLeft, expandRight;
780
                        std::tie(expandLeft, expandRight) = expansionLocation(ideograph, treatAsSpace, m_run.ltr(), afterExpansion, forbidLeadingExpansion, forbidTrailingExpansion, forceLeadingExpansion, forceTrailingExpansion);
779
                        std::tie(expandLeft, expandRight) = expansionLocation(ideograph, treatAsSpace, m_run.ltr(), afterExpansion, forbidLeadingExpansion, forbidTrailingExpansion, forceLeadingExpansion, forceTrailingExpansion);
781
                        m_expansion -= m_expansionPerOpportunity;
780
                        m_expansion -= m_expansionPerOpportunity;
782
                        advance.width += m_expansionPerOpportunity;
781
                        advance.expand(m_expansionPerOpportunity, 0);
783
                        if (expandLeft) {
782
                        if (expandLeft) {
784
                            // Increase previous width
783
                            // Increase previous width
785
                            if (m_adjustedBaseAdvances.isEmpty())
784
                            if (m_adjustedBaseAdvances.isEmpty())
786
                                complexTextRun.growInitialAdvanceHorizontally(m_expansionPerOpportunity);
785
                                complexTextRun.growInitialAdvanceHorizontally(m_expansionPerOpportunity);
787
                            else
786
                            else
788
                                m_adjustedBaseAdvances.last().width += m_expansionPerOpportunity;
787
                                m_adjustedBaseAdvances.last().expand(m_expansionPerOpportunity, 0);
789
                        }
788
                        }
790
                        if (expandRight)
789
                        if (expandRight)
791
                            afterExpansion = true;
790
                            afterExpansion = true;
Lines 794-805 void ComplexTextController::adjustGlyphsAndAdvances() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec13
794
793
795
                    // Account for word-spacing.
794
                    // Account for word-spacing.
796
                    if (treatAsSpace && (ch != '\t' || !m_run.allowTabs()) && (characterIndex > 0 || runIndex > 0) && m_font.wordSpacing())
795
                    if (treatAsSpace && (ch != '\t' || !m_run.allowTabs()) && (characterIndex > 0 || runIndex > 0) && m_font.wordSpacing())
797
                        advance.width += m_font.wordSpacing();
796
                        advance.expand(m_font.wordSpacing(), 0);
798
                } else
797
                } else
799
                    afterExpansion = false;
798
                    afterExpansion = false;
800
            }
799
            }
801
800
802
            widthSinceLastCommit += advance.width; 
801
            widthSinceLastCommit += advance.width();
803
802
804
            // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space.
803
            // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space.
805
            if (m_forTextEmphasis && (!FontCascade::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK)))
804
            if (m_forTextEmphasis && (!FontCascade::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK)))
Lines 815-827 void ComplexTextController::adjustGlyphsAndAdvances() a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp_sec14
815
            m_adjustedGlyphs.append(glyph);
814
            m_adjustedGlyphs.append(glyph);
816
            
815
            
817
            FloatRect glyphBounds = font.boundsForGlyph(glyph);
816
            FloatRect glyphBounds = font.boundsForGlyph(glyph);
818
            glyphBounds.move(glyphOrigin.x, glyphOrigin.y);
817
            glyphBounds.move(glyphOrigin.x(), glyphOrigin.y());
819
            m_minGlyphBoundingBoxX = std::min(m_minGlyphBoundingBoxX, glyphBounds.x());
818
            m_minGlyphBoundingBoxX = std::min(m_minGlyphBoundingBoxX, glyphBounds.x());
820
            m_maxGlyphBoundingBoxX = std::max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
819
            m_maxGlyphBoundingBoxX = std::max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
821
            m_minGlyphBoundingBoxY = std::min(m_minGlyphBoundingBoxY, glyphBounds.y());
820
            m_minGlyphBoundingBoxY = std::min(m_minGlyphBoundingBoxY, glyphBounds.y());
822
            m_maxGlyphBoundingBoxY = std::max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
821
            m_maxGlyphBoundingBoxY = std::max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
823
            glyphOrigin.x += advance.width;
822
            glyphOrigin.move(advance);
824
            glyphOrigin.y += advance.height;
825
            
823
            
826
            lastCharacterIndex = characterIndex;
824
            lastCharacterIndex = characterIndex;
827
        }
825
        }
- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h -44 / +35 lines
Lines 22-30 a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec1
22
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
23
 */
24
24
25
#ifndef ComplexTextController_h
25
#pragma once
26
#define ComplexTextController_h
27
26
27
#include "FloatPoint.h"
28
#include "GlyphBuffer.h"
28
#include "GlyphBuffer.h"
29
#include <wtf/HashSet.h>
29
#include <wtf/HashSet.h>
30
#include <wtf/RefCounted.h>
30
#include <wtf/RefCounted.h>
Lines 39-48 typedef unsigned short CGGlyph; a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec2
39
typedef const struct __CTRun * CTRunRef;
39
typedef const struct __CTRun * CTRunRef;
40
typedef const struct __CTLine * CTLineRef;
40
typedef const struct __CTLine * CTLineRef;
41
41
42
namespace WTF {
43
template<> struct VectorTraits<CGPoint> : SimpleClassVectorTraits { };
44
}
45
46
namespace WebCore {
42
namespace WebCore {
47
43
48
class FontCascade;
44
class FontCascade;
Lines 78-108 public: a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec3
78
74
79
    class ComplexTextRun : public RefCounted<ComplexTextRun> {
75
    class ComplexTextRun : public RefCounted<ComplexTextRun> {
80
    public:
76
    public:
81
        static Ref<ComplexTextRun> create(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange)
77
        static Ref<ComplexTextRun> create(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd)
82
        {
78
        {
83
            return adoptRef(*new ComplexTextRun(ctRun, font, characters, stringLocation, stringLength, runRange));
79
            return adoptRef(*new ComplexTextRun(ctRun, font, characters, stringLocation, stringLength, indexBegin, indexEnd));
84
        }
80
        }
85
81
86
        static Ref<ComplexTextRun> create(const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
82
        static Ref<ComplexTextRun> create(const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr)
87
        {
83
        {
88
            return adoptRef(*new ComplexTextRun(font, characters, stringLocation, stringLength, ltr));
84
            return adoptRef(*new ComplexTextRun(font, characters, stringLocation, stringLength, indexBegin, indexEnd, ltr));
89
        }
85
        }
90
86
91
        static Ref<ComplexTextRun> createForTesting(const Vector<CGSize>& advances, const Vector<CGPoint>& origins, const Vector<CGGlyph>& glyphs, const Vector<CFIndex>& stringIndices, CGSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange, bool ltr)
87
        static Ref<ComplexTextRun> create(const Vector<FloatSize>& advances, const Vector<FloatPoint>& origins, const Vector<Glyph>& glyphs, const Vector<unsigned>& stringIndices, FloatSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr)
92
        {
88
        {
93
            return adoptRef(*new ComplexTextRun(advances, origins, glyphs, stringIndices, initialAdvance, font, characters, stringLocation, stringLength, runRange, ltr));
89
            return adoptRef(*new ComplexTextRun(advances, origins, glyphs, stringIndices, initialAdvance, font, characters, stringLocation, stringLength, indexBegin, indexEnd, ltr));
94
        }
90
        }
95
91
96
        unsigned glyphCount() const { return m_glyphCount; }
92
        unsigned glyphCount() const { return m_glyphCount; }
97
        const Font& font() const { return m_font; }
93
        const Font& font() const { return m_font; }
98
        const UChar* characters() const { return m_characters; }
94
        const UChar* characters() const { return m_characters; }
99
        unsigned stringLocation() const { return m_stringLocation; }
95
        unsigned stringLocation() const { return m_stringLocation; }
100
        size_t stringLength() const { return m_stringLength; }
96
        unsigned stringLength() const { return m_stringLength; }
101
        ALWAYS_INLINE CFIndex indexAt(size_t i) const;
97
        ALWAYS_INLINE unsigned indexAt(unsigned) const;
102
        CFIndex indexBegin() const { return m_indexBegin; }
98
        unsigned indexBegin() const { return m_indexBegin; }
103
        CFIndex indexEnd() const { return m_indexEnd; }
99
        unsigned indexEnd() const { return m_indexEnd; }
104
        CFIndex endOffsetAt(size_t i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; }
100
        unsigned endOffsetAt(unsigned i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; }
105
        const CGGlyph* glyphs() const { return m_glyphs; }
101
        const CGGlyph* glyphs() const { return m_glyphs.data(); }
106
102
107
        /*
103
        /*
108
         * This is the format of the information CoreText gives us about each run:
104
         * This is the format of the information CoreText gives us about each run:
Lines 131-163 public: a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec4
131
         *                X--------------------------------------------------X--------------------------X--------------------------X
127
         *                X--------------------------------------------------X--------------------------X--------------------------X
132
         * (text position ^)                (layout advance)                       (layout advance)           (layout advance)
128
         * (text position ^)                (layout advance)                       (layout advance)           (layout advance)
133
         */
129
         */
134
        void growInitialAdvanceHorizontally(CGFloat delta) { m_initialAdvance.width += delta; }
130
        void growInitialAdvanceHorizontally(float delta) { m_initialAdvance.expand(delta, 0); }
135
        CGSize initialAdvance() const { return m_initialAdvance; }
131
        FloatSize initialAdvance() const { return m_initialAdvance; }
136
        const CGSize* baseAdvances() const { return m_baseAdvances; }
132
        const FloatSize* baseAdvances() const { return m_baseAdvances.data(); }
137
        const CGPoint* glyphOrigins() const { return m_glyphOrigins.size() == glyphCount() ? m_glyphOrigins.data() : nullptr; }
133
        const FloatPoint* glyphOrigins() const { return m_glyphOrigins.size() == glyphCount() ? m_glyphOrigins.data() : nullptr; }
138
        bool isLTR() const { return m_isLTR; }
134
        bool isLTR() const { return m_isLTR; }
139
        bool isMonotonic() const { return m_isMonotonic; }
135
        bool isMonotonic() const { return m_isMonotonic; }
140
        void setIsNonMonotonic();
136
        void setIsNonMonotonic();
141
137
142
    private:
138
    private:
143
        ComplexTextRun(CTRunRef, const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange);
139
        ComplexTextRun(CTRunRef, const Font&, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd);
144
        ComplexTextRun(const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr);
140
        ComplexTextRun(const Font&, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr);
145
        WEBCORE_EXPORT ComplexTextRun(const Vector<CGSize>& advances, const Vector<CGPoint>& origins, const Vector<CGGlyph>& glyphs, const Vector<CFIndex>& stringIndices, CGSize initialAdvance, const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange, bool ltr);
141
        WEBCORE_EXPORT ComplexTextRun(const Vector<FloatSize>& advances, const Vector<FloatPoint>& origins, const Vector<Glyph>& glyphs, const Vector<unsigned>& stringIndices, FloatSize initialAdvance, const Font&, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr);
146
142
147
        Vector<CGSize, 64> m_baseAdvancesVector;
143
        Vector<FloatSize, 64> m_baseAdvances;
148
        Vector<CGPoint, 64> m_glyphOrigins;
144
        Vector<FloatPoint, 64> m_glyphOrigins;
149
        Vector<CGGlyph, 64> m_glyphsVector;
145
        Vector<CGGlyph, 64> m_glyphs;
150
        Vector<CFIndex, 64> m_glyphEndOffsets;
146
        Vector<unsigned, 64> m_glyphEndOffsets;
151
        Vector<CFIndex, 64> m_coreTextIndicesVector;
147
        Vector<unsigned, 64> m_coreTextIndices;
152
        CGSize m_initialAdvance;
148
        FloatSize m_initialAdvance;
153
        const Font& m_font;
149
        const Font& m_font;
154
        const UChar* m_characters;
150
        const UChar* m_characters;
155
        size_t m_stringLength;
151
        unsigned m_stringLength;
156
        const CFIndex* m_coreTextIndices;
152
        unsigned m_indexBegin;
157
        const CGGlyph* m_glyphs;
153
        unsigned m_indexEnd;
158
        const CGSize* m_baseAdvances;
159
        CFIndex m_indexBegin;
160
        CFIndex m_indexEnd;
161
        unsigned m_glyphCount;
154
        unsigned m_glyphCount;
162
        unsigned m_stringLocation;
155
        unsigned m_stringLocation;
163
        bool m_isLTR;
156
        bool m_isLTR;
Lines 180-189 private: a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec5
180
173
181
    float runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle) const;
174
    float runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle) const;
182
175
183
    CGPoint glyphOrigin(unsigned index) const { return index < m_glyphOrigins.size() ? m_glyphOrigins[index] : CGPointZero; }
176
    FloatPoint glyphOrigin(unsigned index) const { return index < m_glyphOrigins.size() ? m_glyphOrigins[index] : FloatPoint(); }
184
177
185
    Vector<CGSize, 256> m_adjustedBaseAdvances;
178
    Vector<FloatSize, 256> m_adjustedBaseAdvances;
186
    Vector<CGPoint, 256> m_glyphOrigins;
179
    Vector<FloatPoint, 256> m_glyphOrigins;
187
    Vector<CGGlyph, 256> m_adjustedGlyphs;
180
    Vector<CGGlyph, 256> m_adjustedGlyphs;
188
181
189
    Vector<UChar, 256> m_smallCapsBuffer;
182
    Vector<UChar, 256> m_smallCapsBuffer;
Lines 210-216 private: a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec6
210
203
211
    const FontCascade& m_font;
204
    const FontCascade& m_font;
212
    const TextRun& m_run;
205
    const TextRun& m_run;
213
 
206
214
    unsigned m_currentCharacter { 0 };
207
    unsigned m_currentCharacter { 0 };
215
    unsigned m_end { 0 };
208
    unsigned m_end { 0 };
216
209
Lines 234-238 private: a/Source/WebCore/platform/graphics/mac/ComplexTextController.h_sec7
234
};
227
};
235
228
236
} // namespace WebCore
229
} // namespace WebCore
237
238
#endif // ComplexTextController_h
- a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm -53 / +63 lines
Lines 42-51 a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm_sec1
42
42
43
#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 90000)
43
#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 90000)
44
SOFT_LINK_FRAMEWORK(CoreText);
44
SOFT_LINK_FRAMEWORK(CoreText);
45
SOFT_LINK(CoreText, CTRunGetBaseAdvancesAndOrigins, void, (CTRunRef run, CFRange range, CGSize baseAdvances[], CGPoint origins[]), (run, range, baseAdvances, origins))
45
SOFT_LINK(CoreText, CTRunGetBaseAdvancesAndOrigins, void, (CTRunRef run, CFRange range, FloatSize baseAdvances[], FloatPoint origins[]), (run, range, baseAdvances, origins))
46
#endif
46
#endif
47
47
48
49
// Note: CTFontDescriptorRefs can live forever in caches inside CoreText, so this object can too.
48
// Note: CTFontDescriptorRefs can live forever in caches inside CoreText, so this object can too.
50
@interface WebCascadeList : NSArray {
49
@interface WebCascadeList : NSArray {
51
    @private
50
    @private
Lines 106-202 @end a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm_sec2
106
105
107
namespace WebCore {
106
namespace WebCore {
108
107
109
ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange)
108
ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd)
110
    : m_initialAdvance(CTRunGetInitialAdvance(ctRun))
109
    : m_initialAdvance(CTRunGetInitialAdvance(ctRun))
111
    , m_font(font)
110
    , m_font(font)
112
    , m_characters(characters)
111
    , m_characters(characters)
113
    , m_stringLength(stringLength)
112
    , m_stringLength(stringLength)
114
    , m_coreTextIndices(CTRunGetStringIndicesPtr(ctRun))
113
    , m_indexBegin(indexBegin)
115
    , m_glyphs(CTRunGetGlyphsPtr(ctRun))
114
    , m_indexEnd(indexEnd)
116
    , m_indexBegin(runRange.location)
117
    , m_indexEnd(runRange.location + runRange.length)
118
    , m_glyphCount(CTRunGetGlyphCount(ctRun))
115
    , m_glyphCount(CTRunGetGlyphCount(ctRun))
119
    , m_stringLocation(stringLocation)
116
    , m_stringLocation(stringLocation)
120
    , m_isLTR(!(CTRunGetStatus(ctRun) & kCTRunStatusRightToLeft))
117
    , m_isLTR(!(CTRunGetStatus(ctRun) & kCTRunStatusRightToLeft))
121
{
118
{
122
    if (!m_coreTextIndices) {
119
    const CFIndex* coreTextIndicesPtr = CTRunGetStringIndicesPtr(ctRun);
123
        m_coreTextIndicesVector.grow(m_glyphCount);
120
    Vector<CFIndex> coreTextIndices;
124
        CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), m_coreTextIndicesVector.data());
121
    if (!coreTextIndicesPtr) {
125
        m_coreTextIndices = m_coreTextIndicesVector.data();
122
        coreTextIndices.grow(m_glyphCount);
123
        CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), coreTextIndices.data());
124
        coreTextIndicesPtr = coreTextIndices.data();
126
    }
125
    }
127
126
    m_coreTextIndices.reserveInitialCapacity(m_glyphCount);
128
    if (!m_glyphs) {
127
    for (unsigned i = 0; i < m_glyphCount; ++i)
129
        m_glyphsVector.grow(m_glyphCount);
128
        m_coreTextIndices.uncheckedAppend(coreTextIndicesPtr[i]);
130
        CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), m_glyphsVector.data());
129
131
        m_glyphs = m_glyphsVector.data();
130
    const CGGlyph* glyphsPtr = CTRunGetGlyphsPtr(ctRun);
131
    Vector<CGGlyph> glyphs;
132
    if (!glyphsPtr) {
133
        glyphs.grow(m_glyphCount);
134
        CTRunGetGlyphs(ctRun, CFRangeMake(0, 0), glyphs.data());
135
        glyphsPtr = glyphs.data();
132
    }
136
    }
137
    m_glyphs.reserveInitialCapacity(m_glyphCount);
138
    for (unsigned i = 0; i < m_glyphCount; ++i)
139
        m_glyphs.uncheckedAppend(glyphsPtr[i]);
133
140
134
#if USE_LAYOUT_SPECIFIC_ADVANCES
141
#if USE_LAYOUT_SPECIFIC_ADVANCES
135
    if (CTRunGetStatus(ctRun) & kCTRunStatusHasOrigins) {
142
    if (CTRunGetStatus(ctRun) & kCTRunStatusHasOrigins) {
136
        m_baseAdvancesVector.grow(m_glyphCount);
143
        Vector<CGSize> baseAdvances(m_glyphCount);
137
        m_glyphOrigins.grow(m_glyphCount);
144
        Vector<CGPoint> glyphOrigins(m_glyphCount);
138
        CTRunGetBaseAdvancesAndOrigins(ctRun, CFRangeMake(0, 0), m_baseAdvancesVector.data(), m_glyphOrigins.data());
145
        CTRunGetBaseAdvancesAndOrigins(ctRun, CFRangeMake(0, 0), baseAdvances.data(), glyphOrigins.data());
139
        m_baseAdvances = m_baseAdvancesVector.data();
146
        m_baseAdvances.reserveInitialCapacity(m_glyphCount);
147
        m_glyphOrigins.reserveInitialCapacity(m_glyphCount);
148
        for (unsigned i = 0; i < m_glyphCount; ++i) {
149
            m_baseAdvances.uncheckedAppend(baseAdvances[i]);
150
            m_glyphOrigins.uncheckedAppend(glyphOrigins[i]);
151
        }
140
    } else
152
    } else
141
#endif
153
#endif
142
    {
154
    {
143
        m_baseAdvances = CTRunGetAdvancesPtr(ctRun);
155
        const CGSize* baseAdvances = CTRunGetAdvancesPtr(ctRun);
144
        if (!m_baseAdvances) {
156
        Vector<CGSize> baseAdvancesVector;
145
            m_baseAdvancesVector.grow(m_glyphCount);
157
        if (!baseAdvances) {
146
            CTRunGetAdvances(ctRun, CFRangeMake(0, 0), m_baseAdvancesVector.data());
158
            baseAdvancesVector.grow(m_glyphCount);
147
            m_baseAdvances = m_baseAdvancesVector.data();
159
            CTRunGetAdvances(ctRun, CFRangeMake(0, 0), baseAdvancesVector.data());
160
            baseAdvances = baseAdvancesVector.data();
148
        }
161
        }
162
        m_baseAdvances.reserveInitialCapacity(m_glyphCount);
163
        for (unsigned i = 0; i < m_glyphCount; ++i)
164
            m_baseAdvances.uncheckedAppend(baseAdvances[i]);
149
    }
165
    }
150
}
166
}
151
167
152
// Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on
168
// Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on
153
// glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path.
169
// glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path.
154
ComplexTextController::ComplexTextRun::ComplexTextRun(const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr)
170
ComplexTextController::ComplexTextRun::ComplexTextRun(const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr)
155
    : m_initialAdvance(CGSizeZero)
171
    : m_font(font)
156
    , m_font(font)
157
    , m_characters(characters)
172
    , m_characters(characters)
158
    , m_stringLength(stringLength)
173
    , m_stringLength(stringLength)
159
    , m_indexBegin(0)
174
    , m_indexBegin(indexBegin)
160
    , m_indexEnd(stringLength)
175
    , m_indexEnd(indexEnd)
161
    , m_stringLocation(stringLocation)
176
    , m_stringLocation(stringLocation)
162
    , m_isLTR(ltr)
177
    , m_isLTR(ltr)
163
{
178
{
164
    m_coreTextIndicesVector.reserveInitialCapacity(m_stringLength);
179
    auto runLengthInCodeUnits = m_indexEnd - m_indexBegin;
165
    unsigned r = 0;
180
    m_coreTextIndices.reserveInitialCapacity(runLengthInCodeUnits);
166
    while (r < m_stringLength) {
181
    unsigned r = m_indexBegin;
167
        m_coreTextIndicesVector.uncheckedAppend(r);
182
    while (r < m_indexEnd) {
183
        m_coreTextIndices.uncheckedAppend(r);
168
        UChar32 character;
184
        UChar32 character;
169
        U16_NEXT(m_characters, r, m_stringLength, character);
185
        U16_NEXT(m_characters, r, m_stringLength, character);
170
    }
186
    }
171
    m_glyphCount = m_coreTextIndicesVector.size();
187
    m_glyphCount = m_coreTextIndices.size();
172
    if (!ltr) {
188
    if (!ltr) {
173
        for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end)
189
        for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end)
174
            std::swap(m_coreTextIndicesVector[r], m_coreTextIndicesVector[end]);
190
            std::swap(m_coreTextIndices[r], m_coreTextIndices[end]);
175
    }
191
    }
176
    m_coreTextIndices = m_coreTextIndicesVector.data();
177
192
178
    // Synthesize a run of missing glyphs.
193
    // Synthesize a run of missing glyphs.
179
    m_glyphsVector.fill(0, m_glyphCount);
194
    m_glyphs.fill(0, m_glyphCount);
180
    m_glyphs = m_glyphsVector.data();
195
    m_baseAdvances.fill(FloatSize(m_font.widthForGlyph(0), 0), m_glyphCount);
181
    m_baseAdvancesVector.fill(CGSizeMake(m_font.widthForGlyph(0), 0), m_glyphCount);
182
    m_baseAdvances = m_baseAdvancesVector.data();
183
}
196
}
184
197
185
198
186
ComplexTextController::ComplexTextRun::ComplexTextRun(const Vector<CGSize>& advances, const Vector<CGPoint>& origins, const Vector<CGGlyph>& glyphs, const Vector<CFIndex>& stringIndices, CGSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange, bool ltr)
199
ComplexTextController::ComplexTextRun::ComplexTextRun(const Vector<FloatSize>& advances, const Vector<FloatPoint>& origins, const Vector<Glyph>& glyphs, const Vector<unsigned>& stringIndices, FloatSize initialAdvance, const Font& font, const UChar* characters, unsigned stringLocation, unsigned stringLength, unsigned indexBegin, unsigned indexEnd, bool ltr)
187
    : m_baseAdvancesVector(advances)
200
    : m_baseAdvances(advances)
188
    , m_glyphOrigins(origins)
201
    , m_glyphOrigins(origins)
189
    , m_glyphsVector(glyphs)
202
    , m_glyphs(glyphs)
190
    , m_coreTextIndicesVector(stringIndices)
203
    , m_coreTextIndices(stringIndices)
191
    , m_initialAdvance(initialAdvance)
204
    , m_initialAdvance(initialAdvance)
192
    , m_font(font)
205
    , m_font(font)
193
    , m_characters(characters)
206
    , m_characters(characters)
194
    , m_stringLength(stringLength)
207
    , m_stringLength(stringLength)
195
    , m_coreTextIndices(m_coreTextIndicesVector.data())
208
    , m_indexBegin(indexBegin)
196
    , m_glyphs(m_glyphsVector.data())
209
    , m_indexEnd(indexEnd)
197
    , m_baseAdvances(m_baseAdvancesVector.data())
198
    , m_indexBegin(runRange.location)
199
    , m_indexEnd(runRange.location + runRange.length)
200
    , m_glyphCount(glyphs.size())
210
    , m_glyphCount(glyphs.size())
201
    , m_stringLocation(stringLocation)
211
    , m_stringLocation(stringLocation)
202
    , m_isLTR(ltr)
212
    , m_isLTR(ltr)
Lines 229-235 void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm_sec3
229
{
239
{
230
    if (!font) {
240
    if (!font) {
231
        // Create a run of missing glyphs from the primary font.
241
        // Create a run of missing glyphs from the primary font.
232
        m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, m_run.ltr()));
242
        m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, 0, length, m_run.ltr()));
233
        return;
243
        return;
234
    }
244
    }
235
245
Lines 313-319 void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm_sec4
313
                    // NSFontRenderingMode.
323
                    // NSFontRenderingMode.
314
                    RetainPtr<CFStringRef> fontName = adoptCF(CTFontCopyPostScriptName(runCTFont));
324
                    RetainPtr<CFStringRef> fontName = adoptCF(CTFontCopyPostScriptName(runCTFont));
315
                    if (CFEqual(fontName.get(), CFSTR("LastResort"))) {
325
                    if (CFEqual(fontName.get(), CFSTR("LastResort"))) {
316
                        m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation + runRange.location, runRange.length, m_run.ltr()));
326
                        m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, runRange.location, runRange.location + runRange.length, m_run.ltr()));
317
                        continue;
327
                        continue;
318
                    }
328
                    }
319
                    auto& fontCache = FontCache::singleton();
329
                    auto& fontCache = FontCache::singleton();
Lines 332-338 void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, a/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm_sec5
332
        if (m_fallbackFonts && runFont != &m_font.primaryFont())
342
        if (m_fallbackFonts && runFont != &m_font.primaryFont())
333
            m_fallbackFonts->add(font);
343
            m_fallbackFonts->add(font);
334
344
335
        m_complexTextRuns.append(ComplexTextRun::create(ctRun, *runFont, cp, stringLocation, length, runRange));
345
        m_complexTextRuns.append(ComplexTextRun::create(ctRun, *runFont, cp, stringLocation, length, runRange.location, runRange.location + runRange.length));
336
    }
346
    }
337
}
347
}
338
348
- a/LayoutTests/ChangeLog +11 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2017-02-06  Myles C. Maxfield  <mmaxfield@apple.com>
2
3
        Migrate ComplexTextController to use platform-independent types
4
        https://bugs.webkit.org/show_bug.cgi?id=167833
5
6
        Rebaseline tiny rounding result.
7
8
        Reviewed by NOBODY (OOPS!).
9
10
        * platform/mac/fast/text/complex-text-opacity-expected.txt:
11
1
2017-02-06  Ryan Haddad  <ryanhaddad@apple.com>
12
2017-02-06  Ryan Haddad  <ryanhaddad@apple.com>
2
13
3
        Unreviewed, rolling out r211722.
14
        Unreviewed, rolling out r211722.
- a/LayoutTests/platform/mac/fast/text/complex-text-opacity-expected.txt -2 / +2 lines
Lines 24-31 layer at (0,0) size 800x600 a/LayoutTests/platform/mac/fast/text/complex-text-opacity-expected.txt_sec1
24
          text run at (139,4) width 7: " "
24
          text run at (139,4) width 7: " "
25
        RenderText {#text} at (188,4) size 7x29
25
        RenderText {#text} at (188,4) size 7x29
26
          text run at (188,4) width 7: " "
26
          text run at (188,4) width 7: " "
27
        RenderText {#text} at (237,4) size 7x29
27
        RenderText {#text} at (236,4) size 8x29
28
          text run at (237,4) width 7: " "
28
          text run at (236,4) width 8: " "
29
        RenderText {#text} at (285,4) size 7x29
29
        RenderText {#text} at (285,4) size 7x29
30
          text run at (285,4) width 7: " "
30
          text run at (285,4) width 7: " "
31
        RenderText {#text} at (334,4) size 7x29
31
        RenderText {#text} at (334,4) size 7x29

Return to Bug 167833