Changeset 205396 in webkit
- Timestamp:
- Sep 2, 2016 10:52:44 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 13 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r205392 r205396 1 2016-09-02 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [Cocoa] Distinguish between paint advances and base advances 4 https://bugs.webkit.org/show_bug.cgi?id=160892 5 6 Reviewed by Simon Fraser. 7 8 Update tests. There are some expected (small) changes in metrics due to this patch. 9 10 * platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.png: Copied from LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png. 11 * platform/mac-elcapitan/css2.1/t051202-c26-psudo-nest-00-c-expected.txt: Copied from LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt. 12 * platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.png: Copied from LayoutTests/platform/mac/css2.1/t1508-c527-font-00-b-expected.png. 13 * platform/mac-elcapitan/css2.1/t1508-c527-font-00-b-expected.txt: Added. 14 * platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.png: Copied from LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png. 15 * platform/mac-elcapitan/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt: Copied from LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt. 16 * platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.png: 17 * platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt: 18 * platform/mac/css2.1/t1508-c527-font-00-b-expected.png: 19 * platform/mac/css2.1/t1508-c527-font-00-b-expected.txt: Added. 20 * platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.png: 21 * platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt: 22 1 23 2016-09-02 Zalan Bujtas <zalan@apple.com> 2 24 -
trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt
r205382 r205396 57 57 RenderText {#text} at (130,15) size 111x18 58 58 text run at (130,15) width 111: "two characters" 59 RenderText {#text} at (240,15) size 45 2x1860 text run at (240,15) width 12 1: " in this paragraph "61 text run at (3 60,15) width 332: "(a double-quote mark and a capital 'T') should be "62 RenderInline {STRONG} at (0,0) size 89x1863 RenderText {#text} at (69 1,15) size 89x1864 text run at (69 1,15) width 45: "200% "65 text run at (73 5,15) width 45: "bigger"59 RenderText {#text} at (240,15) size 451x18 60 text run at (240,15) width 120: " in this paragraph " 61 text run at (359,15) width 332: "(a double-quote mark and a capital 'T') should be " 62 RenderInline {STRONG} at (0,0) size 90x18 63 RenderText {#text} at (690,15) size 90x18 64 text run at (690,15) width 45: "200% " 65 text run at (734,15) width 46: "bigger" 66 66 RenderText {#text} at (0,37) size 223x18 67 67 text run at (0,37) width 223: "than the rest of the paragraph, and " -
trunk/LayoutTests/platform/mac/fast/inline/absolute-positioned-inline-in-centred-block-expected.txt
r205382 r205396 7 7 layer at (250,562) size 303x28 8 8 RenderBlock (positioned) {FONT} at (250,562) size 303x28 9 RenderText {#text} at (0,0) size 30 3x2810 text run at (0,0) width 30 3: "Hello World, And Stuff!"9 RenderText {#text} at (0,0) size 302x28 10 text run at (0,0) width 302: "Hello World, And Stuff!" -
trunk/Source/WebCore/ChangeLog
r205392 r205396 1 2016-09-02 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [Cocoa] Distinguish between paint advances and base advances 4 https://bugs.webkit.org/show_bug.cgi?id=160892 5 6 Reviewed by Simon Fraser. 7 8 This patch introduces the concept of a layout (or "base") advance which is distinct 9 from a painting advance. In extremely complicated scripts such as Urdu, it is common 10 for a glyph advance to be negative in the horizontal direction, and have large advances 11 in the vertical direction. In particular, in cursive scripts, the glyph placement is 12 only indirectly related to where the actual characters lie. Conceptually, these glyph 13 locations are correct for painting, but are not correct when performing width 14 measurements. 15 16 In many text engines, glyph shaping actually can be split into two phases: adjusting 17 advances, and then placing glyphs relative to those advances. The secondary glyph 18 placement step is much more context-sensitive than the first step. In addition, when 19 multiple glyphs combine to form a character, it is common for one glyph to own the 20 full base advance for the character, and for the other glyphs in the character to 21 have zero base advances. (Then, in the glyph placement phase, the other glyphs get 22 placed all around.) 23 24 Because of the context-insensitivity of the base advances, it is valuable to use 25 these for text measurement. Then, when we want to paint, we should add in the extra 26 origins. This dramatically improves the layout of complex fonts like Noto Nastaliq. 27 28 This patch migrates WebKit to use this two-phase shaping. 29 30 No new tests just yet, because I have to create a font which exercises the 31 advanced glyph placement support. 32 33 * platform/graphics/GlyphBuffer.h: 34 (WebCore::GlyphBufferAdvance::setHeight): 35 (WebCore::GlyphBufferAdvance::setWidth): Deleted. 36 * platform/graphics/TextRun.h: 37 (WebCore::TextRun::TextRun): 38 (WebCore::TextRun::shouldDisableLayoutSpecificAdvances): 39 (WebCore::TextRun::setShouldDisableLayoutSpecificAdvances): 40 (WebCore::TextRun::spacingDisabled): Deleted. 41 (WebCore::TextRun::setCharacterScanForCodePath): Deleted. 42 * platform/graphics/cocoa/FontCascadeCocoa.mm: 43 (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText): 44 * platform/graphics/mac/ComplexTextController.cpp: 45 (WebCore::ComplexTextController::ComplexTextController): 46 (WebCore::ComplexTextController::offsetForPosition): 47 (WebCore::ComplexTextController::collectComplexTextRuns): 48 (WebCore::ComplexTextController::ComplexTextRun::setIsNonMonotonic): 49 (WebCore::ComplexTextController::runWidthSoFarFraction): 50 (WebCore::ComplexTextController::advance): 51 (WebCore::ComplexTextController::adjustGlyphsAndAdvances): 52 * platform/graphics/mac/ComplexTextController.h: 53 (WebCore::ComplexTextController::ComplexTextRun::create): 54 (WebCore::ComplexTextController::ComplexTextRun::baseAdvances): 55 (WebCore::ComplexTextController::ComplexTextRun::glyphOrigins): 56 (WebCore::ComplexTextController::useLayoutSpecificAdvances): 57 (WebCore::ComplexTextController::finalRoundingWidth): Deleted. 58 (WebCore::ComplexTextController::ComplexTextRun::advances): Deleted. 59 * platform/graphics/mac/ComplexTextControllerCoreText.mm: 60 (SOFT_LINK): 61 (WebCore::ComplexTextController::ComplexTextRun::ComplexTextRun): 62 (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): 63 * platform/spi/cocoa/CoreTextSPI.h: 64 1 65 2016-09-02 Zalan Bujtas <zalan@apple.com> 2 66 -
trunk/Source/WebCore/platform/graphics/GlyphBuffer.h
r205382 r205396 68 68 69 69 void setWidth(CGFloat width) { this->CGSize::width = width; } 70 void setHeight(CGFloat height) { this->CGSize::height = height; } 70 71 CGFloat width() const { return this->CGSize::width; } 71 72 CGFloat height() const { return this->CGSize::height; } -
trunk/Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm
r205382 r205396 515 515 516 516 if (run.rtl()) { 517 initialAdvance = controller.totalWidth() + controller.finalRoundingWidth()- afterWidth + controller.leadingExpansion();517 initialAdvance = controller.totalWidth() - afterWidth + controller.leadingExpansion(); 518 518 glyphBuffer.reverse(0, glyphBuffer.size()); 519 519 } else -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
r205382 r205396 108 108 109 109 ComplexTextController::ComplexTextController(const FontCascade& font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const Font*>* fallbackFonts, bool forTextEmphasis) 110 : m_font(font) 110 : m_fallbackFonts(fallbackFonts) 111 , m_font(font) 111 112 , m_run(run) 112 , m_isLTROnly(true) 113 , m_end(run.length()) 114 , m_expansion(run.expansion()) 113 115 , m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection) 114 116 , m_forTextEmphasis(forTextEmphasis) 115 , m_currentCharacter(0)116 , m_end(run.length())117 , m_totalWidth(0)118 , m_runWidthSoFar(0)119 , m_numGlyphsSoFar(0)120 , m_currentRun(0)121 , m_glyphInCurrentRun(0)122 , m_characterInCurrentGlyph(0)123 , m_finalRoundingWidth(0)124 , m_expansion(run.expansion())125 , m_leadingExpansion(0)126 , m_fallbackFonts(fallbackFonts)127 , m_minGlyphBoundingBoxX(std::numeric_limits<float>::max())128 , m_maxGlyphBoundingBoxX(std::numeric_limits<float>::min())129 , m_minGlyphBoundingBoxY(std::numeric_limits<float>::max())130 , m_maxGlyphBoundingBoxY(std::numeric_limits<float>::min())131 , m_lastRoundingGlyph(0)132 117 { 133 118 if (!m_expansion) … … 159 144 } 160 145 161 intComplexTextController::offsetForPosition(float h, bool includePartialGlyphs)146 unsigned ComplexTextController::offsetForPosition(float h, bool includePartialGlyphs) 162 147 { 163 148 if (h >= m_totalWidth) … … 177 162 for (unsigned j = 0; j < complexTextRun.glyphCount(); ++j) { 178 163 size_t index = offsetIntoAdjustedGlyphs + j; 179 CGFloat adjustedAdvance = m_adjusted Advances[index].width;164 CGFloat adjustedAdvance = m_adjustedBaseAdvances[index].width; 180 165 if (!index) 181 166 adjustedAdvance += complexTextRun.initialAdvance().width; … … 189 174 190 175 // FIXME: Instead of dividing the glyph's advance equally between the characters, this 191 // could use the glyph's "ligature carets". However, there is no Core Text API to get the 192 // ligature carets. 176 // could use the glyph's "ligature carets". This is available in CoreText via CTFontGetLigatureCaretPositions(). 193 177 CFIndex hitIndex = hitGlyphStart + (hitGlyphEnd - hitGlyphStart) * (m_run.ltr() ? x / adjustedAdvance : 1 - x / adjustedAdvance); 194 178 int stringLength = complexTextRun.stringLength(); … … 218 202 int firstGlyphBeforeCluster = j - 1; 219 203 while (firstGlyphBeforeCluster >= 0 && complexTextRun.indexAt(firstGlyphBeforeCluster) >= clusterStart && complexTextRun.indexAt(firstGlyphBeforeCluster) < clusterEnd) { 220 CGFloat width = m_adjusted Advances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width;204 CGFloat width = m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width; 221 205 clusterWidth += width; 222 206 x += width; … … 225 209 unsigned firstGlyphAfterCluster = j + 1; 226 210 while (firstGlyphAfterCluster < complexTextRun.glyphCount() && complexTextRun.indexAt(firstGlyphAfterCluster) >= clusterStart && complexTextRun.indexAt(firstGlyphAfterCluster) < clusterEnd) { 227 clusterWidth += m_adjusted Advances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width;211 clusterWidth += m_adjustedBaseAdvances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width; 228 212 firstGlyphAfterCluster++; 229 213 } … … 326 310 if (m_run.is8Bit()) { 327 311 String stringFor8BitRun = String::make16BitFrom8BitSource(m_run.characters8(), m_run.length()); 328 cp = stringFor8BitRun.characters16();329 m_stringsFor8BitRuns.append(stringFor8BitRun);312 m_stringsFor8BitRuns.append(WTFMove(stringFor8BitRun)); 313 cp = m_stringsFor8BitRuns.last().characters16(); 330 314 } else 331 315 cp = m_run.characters16(); … … 429 413 } 430 414 415 ASSERT(m_end >= indexOfFontTransition); 431 416 unsigned itemLength = m_end - indexOfFontTransition; 432 417 if (itemLength) { … … 464 449 465 450 m_glyphEndOffsets.grow(m_glyphCount); 466 for ( size_ti = 0; i < m_glyphCount; ++i) {451 for (unsigned i = 0; i < m_glyphCount; ++i) { 467 452 CFIndex nextMappedIndex = m_indexEnd; 468 453 for (size_t j = indexAt(i) + 1; j < m_stringLength; ++j) { … … 531 516 } 532 517 518 float ComplexTextController::runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle iterationStyle) const 519 { 520 // FIXME: Instead of dividing the glyph's advance equally between the characters, this 521 // could use the glyph's "ligature carets". This is available in CoreText via CTFontGetLigatureCaretPositions(). 522 if (glyphStartOffset == glyphEndOffset) { 523 // When there are multiple glyphs per character we need to advance by the full width of the glyph. 524 ASSERT(m_characterInCurrentGlyph == oldCharacterInCurrentGlyph); 525 return 1; 526 } 527 528 if (iterationStyle == ByWholeGlyphs) { 529 if (!oldCharacterInCurrentGlyph) 530 return 1; 531 return 0; 532 } 533 534 return static_cast<float>(m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset); 535 } 536 533 537 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle, HashSet<const Font*>* fallbackFonts) 534 538 { 535 if ( static_cast<int>(offset)> m_end)539 if (offset > m_end) 536 540 offset = m_end; 537 541 … … 563 567 // account the text direction. 564 568 if (glyphBuffer && !leftmostGlyph) { 565 glyphBuffer->setInitialAdvance(complexTextRun.initialAdvance()); 569 CGSize initialAdvance = complexTextRun.initialAdvance(); 570 #if USE_LAYOUT_SPECIFIC_ADVANCES 571 unsigned index = ltr ? 0 : m_glyphOrigins.size() - 1; 572 initialAdvance.width += m_glyphOrigins[index].x; 573 initialAdvance.height += m_glyphOrigins[index].y; 574 #endif 575 glyphBuffer->setInitialAdvance(initialAdvance); 576 566 577 glyphBuffer->setLeadingExpansion(m_leadingExpansion); 567 578 } … … 578 589 glyphEndOffset = complexTextRun.endOffsetAt(g); 579 590 580 CGSize adjusted Advance = m_adjustedAdvances[k];591 CGSize adjustedBaseAdvance = m_adjustedBaseAdvances[k]; 581 592 582 593 if (glyphStartOffset + complexTextRun.stringLocation() >= m_currentCharacter) 583 594 return; 584 595 585 if (glyphBuffer && !m_characterInCurrentGlyph) 586 glyphBuffer->add(m_adjustedGlyphs[k], &complexTextRun.font(), adjustedAdvance, complexTextRun.indexAt(m_glyphInCurrentRun)); 596 if (glyphBuffer && !m_characterInCurrentGlyph) { 597 GlyphBufferAdvance paintAdvance = adjustedBaseAdvance; 598 #if USE_LAYOUT_SPECIFIC_ADVANCES 599 if (k + 1 < m_adjustedBaseAdvances.size()) { 600 paintAdvance.setWidth(paintAdvance.width() + m_glyphOrigins[k + 1].x - m_glyphOrigins[k].x); 601 paintAdvance.setHeight(paintAdvance.height() - m_glyphOrigins[k + 1].y + m_glyphOrigins[k].y); 602 } 603 #endif 604 glyphBuffer->add(m_adjustedGlyphs[k], &complexTextRun.font(), paintAdvance, complexTextRun.indexAt(m_glyphInCurrentRun)); 605 } 587 606 588 607 unsigned oldCharacterInCurrentGlyph = m_characterInCurrentGlyph; 589 608 m_characterInCurrentGlyph = std::min(m_currentCharacter - complexTextRun.stringLocation(), glyphEndOffset) - glyphStartOffset; 590 // FIXME: Instead of dividing the glyph's advance equally between the characters, this 591 // could use the glyph's "ligature carets". However, there is no Core Text API to get the 592 // ligature carets. 593 if (glyphStartOffset == glyphEndOffset) { 594 // When there are multiple glyphs per character we need to advance by the full width of the glyph. 595 ASSERT(m_characterInCurrentGlyph == oldCharacterInCurrentGlyph); 596 m_runWidthSoFar += adjustedAdvance.width; 597 } else if (iterationStyle == ByWholeGlyphs) { 598 if (!oldCharacterInCurrentGlyph) 599 m_runWidthSoFar += adjustedAdvance.width; 600 } else 601 m_runWidthSoFar += adjustedAdvance.width * (m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset); 609 m_runWidthSoFar += adjustedBaseAdvance.width * runWidthSoFarFraction(glyphStartOffset, glyphEndOffset, oldCharacterInCurrentGlyph, iterationStyle); 602 610 603 611 if (glyphEndOffset + complexTextRun.stringLocation() > m_currentCharacter) … … 618 626 m_glyphInCurrentRun = 0; 619 627 } 620 if (!m_run.ltr() && m_numGlyphsSoFar == m_adjustedAdvances.size())621 m_runWidthSoFar += m_finalRoundingWidth;622 628 } 623 629 … … 657 663 bool runForbidsLeadingExpansion = (m_run.expansionBehavior() & LeadingExpansionMask) == ForbidLeadingExpansion; 658 664 bool runForbidsTrailingExpansion = (m_run.expansionBehavior() & TrailingExpansionMask) == ForbidTrailingExpansion; 665 659 666 // We are iterating in glyph order, not string order. Compare this to WidthIterator::advanceInternal() 660 667 for (size_t r = 0; r < runCount; ++r) { … … 665 672 // Represent the initial advance for a text run by adjusting the advance 666 673 // of the last glyph of the previous text run in the glyph buffer. 667 if (r && m_adjusted Advances.size()) {668 CGSize previousAdvance = m_adjusted Advances.last();674 if (r && m_adjustedBaseAdvances.size()) { 675 CGSize previousAdvance = m_adjustedBaseAdvances.last(); 669 676 previousAdvance.width += complexTextRun.initialAdvance().width; 670 677 previousAdvance.height -= complexTextRun.initialAdvance().height; 671 m_adjusted Advances[m_adjustedAdvances.size() - 1] = previousAdvance;678 m_adjustedBaseAdvances[m_adjustedBaseAdvances.size() - 1] = previousAdvance; 672 679 } 673 680 widthSinceLastCommit += complexTextRun.initialAdvance().width; … … 677 684 678 685 const CGGlyph* glyphs = complexTextRun.glyphs(); 679 const CGSize* advances = complexTextRun. advances();686 const CGSize* advances = complexTextRun.baseAdvances(); 680 687 681 688 bool lastRun = r + 1 == runCount; … … 751 758 m_expansion -= m_expansionPerOpportunity; 752 759 m_totalWidth += m_expansionPerOpportunity; 753 if (m_adjusted Advances.isEmpty())760 if (m_adjustedBaseAdvances.isEmpty()) 754 761 m_leadingExpansion = m_expansionPerOpportunity; 755 762 else 756 m_adjusted Advances.last().width += m_expansionPerOpportunity;763 m_adjustedBaseAdvances.last().width += m_expansionPerOpportunity; 757 764 } 758 765 if (expandRight) { … … 778 785 779 786 advance.height *= -1; 780 m_adjustedAdvances.append(advance); 787 m_adjustedBaseAdvances.append(advance); 788 #if USE_LAYOUT_SPECIFIC_ADVANCES 789 m_glyphOrigins.append(complexTextRun.glyphOrigins()[i]); 790 #endif 781 791 m_adjustedGlyphs.append(glyph); 782 792 -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h
r205382 r205396 33 33 #include <wtf/text/WTFString.h> 34 34 35 #define USE_LAYOUT_SPECIFIC_ADVANCES ((PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000)) 36 35 37 typedef unsigned short CGGlyph; 36 38 … … 57 59 58 60 // Compute the character offset for a given x coordinate. 59 intoffsetForPosition(float x, bool includePartialGlyphs);61 unsigned offsetForPosition(float x, bool includePartialGlyphs); 60 62 61 63 // Returns the width of everything we've consumed so far. … … 63 65 64 66 float totalWidth() const { return m_totalWidth; } 65 66 float finalRoundingWidth() const { return m_finalRoundingWidth; }67 67 68 68 float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; } … … 96 96 CFIndex endOffsetAt(size_t i) const { ASSERT(!m_isMonotonic); return m_glyphEndOffsets[i]; } 97 97 const CGGlyph* glyphs() const { return m_glyphs; } 98 99 /* 100 * X (Paint glyph position) X (Paint glyph position) X (Paint glyph position) 101 * 7 7 7 102 * / / / 103 * / (Glyph origin) / (Glyph origin) / (Glyph origin) 104 * / / / 105 * / / / 106 * X-----------------------X--------------------------X--------------------------X---->... 107 * (text position ^) (initial advance) (base advance) (base advance) 108 */ 98 109 CGSize initialAdvance() const { return m_initialAdvance; } 99 const CGSize* advances() const { return m_advances; } 110 const CGSize* baseAdvances() const { return m_baseAdvances; } 111 const CGPoint* glyphOrigins() const { return m_glyphOrigins.data(); } 100 112 bool isLTR() const { return m_isLTR; } 101 113 bool isMonotonic() const { return m_isMonotonic; } … … 106 118 ComplexTextRun(const Font&, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr); 107 119 108 unsigned m_glyphCount; 120 Vector<CGSize, 64> m_baseAdvancesVector; 121 Vector<CGPoint, 64> m_glyphOrigins; 122 Vector<CGGlyph, 64> m_glyphsVector; 123 Vector<CFIndex, 64> m_glyphEndOffsets; 124 Vector<CFIndex, 64> m_coreTextIndicesVector; 125 CGSize m_initialAdvance; 109 126 const Font& m_font; 110 127 const UChar* m_characters; 111 unsigned m_stringLocation;112 128 size_t m_stringLength; 113 Vector<CFIndex, 64> m_coreTextIndicesVector;114 129 const CFIndex* m_coreTextIndices; 130 const CGGlyph* m_glyphs; 131 const CGSize* m_baseAdvances; 115 132 CFIndex m_indexBegin; 116 133 CFIndex m_indexEnd; 117 Vector<CFIndex, 64> m_glyphEndOffsets; 118 Vector<CGGlyph, 64> m_glyphsVector; 119 const CGGlyph* m_glyphs; 120 CGSize m_initialAdvance; 121 Vector<CGSize, 64> m_advancesVector; 122 const CGSize* m_advances; 134 unsigned m_glyphCount; 135 unsigned m_stringLocation; 123 136 bool m_isLTR; 124 137 bool m_isMonotonic; … … 136 149 unsigned incrementCurrentRun(unsigned& leftmostGlyph); 137 150 138 // The initial capacity of these vectors was selected as being the smallest power of two greater than 139 // the average (3.5) plus one standard deviation (7.5) of nonzero sizes used on Arabic Wikipedia. 140 Vector<unsigned, 16> m_runIndices; 141 Vector<unsigned, 16> m_glyphCountFromStartToIndex; 142 143 const FontCascade& m_font; 144 const TextRun& m_run; 145 bool m_isLTROnly; 146 bool m_mayUseNaturalWritingDirection; 147 bool m_forTextEmphasis; 148 149 Vector<String> m_stringsFor8BitRuns; 151 float runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle) const; 152 153 Vector<CGSize, 256> m_adjustedBaseAdvances; 154 Vector<CGPoint, 256> m_glyphOrigins; 155 Vector<CGGlyph, 256> m_adjustedGlyphs; 156 150 157 Vector<UChar, 256> m_smallCapsBuffer; 151 158 … … 157 164 // its Line. ComplexTextRun::glyphs() and ComplexTextRun::advances() refer to glyphs relative to the ComplexTextRun. 158 165 // The length of the entire TextRun is m_run.length() 166 Vector<RefPtr<ComplexTextRun>, 16> m_complexTextRuns; 167 168 // The initial capacity of these vectors was selected as being the smallest power of two greater than 169 // the average (3.5) plus one standard deviation (7.5) of nonzero sizes used on Arabic Wikipedia. 170 Vector<unsigned, 16> m_runIndices; 171 Vector<unsigned, 16> m_glyphCountFromStartToIndex; 172 159 173 Vector<RetainPtr<CTLineRef>> m_coreTextLines; 160 Vector<RefPtr<ComplexTextRun>, 16> m_complexTextRuns; 161 Vector<CGSize, 256> m_adjustedAdvances; 162 Vector<CGGlyph, 256> m_adjustedGlyphs; 174 175 Vector<String> m_stringsFor8BitRuns; 176 177 HashSet<const Font*>* m_fallbackFonts { nullptr }; 178 179 const FontCascade& m_font; 180 const TextRun& m_run; 163 181 164 unsigned m_currentCharacter; 165 int m_end; 166 167 CGFloat m_totalWidth; 168 169 float m_runWidthSoFar; 170 unsigned m_numGlyphsSoFar; 171 size_t m_currentRun; 172 unsigned m_glyphInCurrentRun; 173 unsigned m_characterInCurrentGlyph; 174 float m_finalRoundingWidth; 175 float m_expansion; 176 float m_expansionPerOpportunity; 177 float m_leadingExpansion; 178 179 HashSet<const Font*>* m_fallbackFonts; 180 181 float m_minGlyphBoundingBoxX; 182 float m_maxGlyphBoundingBoxX; 183 float m_minGlyphBoundingBoxY; 184 float m_maxGlyphBoundingBoxY; 185 186 unsigned m_lastRoundingGlyph; 182 unsigned m_currentCharacter { 0 }; 183 unsigned m_end { 0 }; 184 185 float m_totalWidth { 0 }; 186 float m_runWidthSoFar { 0 }; 187 unsigned m_numGlyphsSoFar { 0 }; 188 unsigned m_currentRun { 0 }; 189 unsigned m_glyphInCurrentRun { 0 }; 190 unsigned m_characterInCurrentGlyph { 0 }; 191 float m_expansion { 0 }; 192 float m_expansionPerOpportunity { 0 }; 193 float m_leadingExpansion { 0 }; 194 195 float m_minGlyphBoundingBoxX { std::numeric_limits<float>::max() }; 196 float m_maxGlyphBoundingBoxX { std::numeric_limits<float>::min() }; 197 float m_minGlyphBoundingBoxY { std::numeric_limits<float>::max() }; 198 float m_maxGlyphBoundingBoxY { std::numeric_limits<float>::min() }; 199 200 bool m_isLTROnly { true }; 201 bool m_mayUseNaturalWritingDirection { false }; 202 bool m_forTextEmphasis { false }; 187 203 }; 188 204 -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
r205382 r205396 30 30 #include "FontCache.h" 31 31 #include "FontCascade.h" 32 #include "SoftLinking.h" 32 33 #include "TextRun.h" 33 34 #include "WebCoreSystemInterface.h" … … 39 40 #include <ApplicationServices/ApplicationServices.h> 40 41 #endif 42 43 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 90000) 44 SOFT_LINK_FRAMEWORK(CoreText); 45 SOFT_LINK(CoreText, CTRunGetBaseAdvancesAndOrigins, void, (CTRunRef run, CFRange range, CGSize baseAdvances[], CGPoint origins[]), (run, range, baseAdvances, origins)) 46 #endif 47 41 48 42 49 // Note: CTFontDescriptorRefs can live forever in caches inside CoreText, so this object can too. … … 101 108 102 109 ComplexTextController::ComplexTextRun::ComplexTextRun(CTRunRef ctRun, const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, CFRange runRange) 103 : m_font(font) 110 : m_initialAdvance(CTRunGetInitialAdvance(ctRun)) 111 , m_font(font) 104 112 , m_characters(characters) 105 , m_stringLocation(stringLocation)106 113 , m_stringLength(stringLength) 107 114 , m_indexBegin(runRange.location) 108 115 , m_indexEnd(runRange.location + runRange.length) 109 , m_ initialAdvance(CTRunGetInitialAdvance(ctRun))116 , m_stringLocation(stringLocation) 110 117 , m_isLTR(!(CTRunGetStatus(ctRun) & kCTRunStatusRightToLeft)) 111 118 , m_isMonotonic(true) … … 126 133 } 127 134 128 m_advances = CTRunGetAdvancesPtr(ctRun); 129 if (!m_advances) { 130 m_advancesVector.grow(m_glyphCount); 131 CTRunGetAdvances(ctRun, CFRangeMake(0, 0), m_advancesVector.data()); 132 m_advances = m_advancesVector.data(); 133 } 135 #if USE_LAYOUT_SPECIFIC_ADVANCES 136 m_baseAdvancesVector.grow(m_glyphCount); 137 m_glyphOrigins.grow(m_glyphCount); 138 CTRunGetBaseAdvancesAndOrigins(ctRun, CFRangeMake(0, 0), m_baseAdvancesVector.data(), m_glyphOrigins.data()); 139 m_baseAdvances = m_baseAdvancesVector.data(); 140 #else 141 m_baseAdvances = CTRunGetAdvancesPtr(ctRun); 142 if (!m_baseAdvances) { 143 m_baseAdvancesVector.grow(m_glyphCount); 144 CTRunGetAdvances(ctRun, CFRangeMake(0, 0), m_baseAdvancesVector.data()); 145 m_baseAdvances = m_baseAdvancesVector.data(); 146 } 147 #endif 134 148 } 135 149 … … 137 151 // glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path. 138 152 ComplexTextController::ComplexTextRun::ComplexTextRun(const Font& font, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr) 139 : m_font(font) 153 : m_initialAdvance(CGSizeZero) 154 , m_font(font) 140 155 , m_characters(characters) 141 , m_stringLocation(stringLocation)142 156 , m_stringLength(stringLength) 143 157 , m_indexBegin(0) 144 158 , m_indexEnd(stringLength) 145 , m_ initialAdvance(CGSizeZero)159 , m_stringLocation(stringLocation) 146 160 , m_isLTR(ltr) 147 161 , m_isMonotonic(true) … … 151 165 while (r < m_stringLength) { 152 166 m_coreTextIndicesVector.uncheckedAppend(r); 153 if (U_IS_LEAD(m_characters[r]) && r + 1 < m_stringLength && U_IS_TRAIL(m_characters[r + 1])) 154 r += 2; 155 else 156 r++; 167 UChar32 character; 168 U16_NEXT(m_characters, r, m_stringLength, character); 157 169 } 158 170 m_glyphCount = m_coreTextIndicesVector.size(); … … 166 178 m_glyphsVector.fill(0, m_glyphCount); 167 179 m_glyphs = m_glyphsVector.data(); 168 m_ advancesVector.fill(CGSizeMake(m_font.widthForGlyph(0), 0), m_glyphCount);169 m_ advances = m_advancesVector.data();180 m_baseAdvancesVector.fill(CGSizeMake(m_font.widthForGlyph(0), 0), m_glyphCount); 181 m_baseAdvances = m_baseAdvancesVector.data(); 170 182 } 171 183 -
trunk/Source/WebCore/platform/spi/cocoa/CoreTextSPI.h
r205382 r205396 69 69 CGSize CTRunGetInitialAdvance(CTRunRef run); 70 70 CTLineRef CTLineCreateWithUniCharProvider(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon); 71 void CTRunGetBaseAdvancesAndOrigins(CTRunRef, CFRange, CGSize baseAdvances[], CGPoint origins[]); 71 72 CTTypesetterRef CTTypesetterCreateWithUniCharProviderAndOptions(CTUniCharProviderCallback provide, CTUniCharDisposeCallback dispose, void* refCon, CFDictionaryRef options); 72 73 bool CTFontGetVerticalGlyphsForCharacters(CTFontRef, const UniChar characters[], CGGlyph glyphs[], CFIndex count);
Note: See TracChangeset
for help on using the changeset viewer.