Changeset 205373 in webkit
- Timestamp:
- Sep 2, 2016 2:43:45 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 13 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r205372 r205373 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 Chris Dumez <cdumez@apple.com> 2 24 -
trunk/LayoutTests/platform/mac/css2.1/t051202-c26-psudo-nest-00-c-expected.txt
r177774 r205373 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
r180441 r205373 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
r205372 r205373 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 Chris Dumez <cdumez@apple.com> 2 66 -
trunk/Source/WebCore/platform/graphics/GlyphBuffer.h
r204400 r205373 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
r204858 r205373 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
r205282 r205373 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 } … … 324 308 const UChar* cp; 325 309 310 Vector<String> stringsFor8BitRuns; 326 311 if (m_run.is8Bit()) { 327 312 String stringFor8BitRun = String::make16BitFrom8BitSource(m_run.characters8(), m_run.length()); 328 cp = stringFor8BitRun.characters16();329 m_stringsFor8BitRuns.append(stringFor8BitRun);313 stringsFor8BitRuns.append(WTFMove(stringFor8BitRun)); 314 cp = stringsFor8BitRuns.last().characters16(); 330 315 } else 331 316 cp = m_run.characters16(); … … 429 414 } 430 415 416 ASSERT(m_end >= indexOfFontTransition); 431 417 unsigned itemLength = m_end - indexOfFontTransition; 432 418 if (itemLength) { … … 464 450 465 451 m_glyphEndOffsets.grow(m_glyphCount); 466 for ( size_ti = 0; i < m_glyphCount; ++i) {452 for (unsigned i = 0; i < m_glyphCount; ++i) { 467 453 CFIndex nextMappedIndex = m_indexEnd; 468 454 for (size_t j = indexAt(i) + 1; j < m_stringLength; ++j) { … … 531 517 } 532 518 519 float ComplexTextController::runWidthSoFarFraction(unsigned glyphStartOffset, unsigned glyphEndOffset, unsigned oldCharacterInCurrentGlyph, GlyphIterationStyle iterationStyle) const 520 { 521 // FIXME: Instead of dividing the glyph's advance equally between the characters, this 522 // could use the glyph's "ligature carets". This is available in CoreText via CTFontGetLigatureCaretPositions(). 523 if (glyphStartOffset == glyphEndOffset) { 524 // When there are multiple glyphs per character we need to advance by the full width of the glyph. 525 ASSERT(m_characterInCurrentGlyph == oldCharacterInCurrentGlyph); 526 return 1; 527 } 528 529 if (iterationStyle == ByWholeGlyphs) { 530 if (!oldCharacterInCurrentGlyph) 531 return 1; 532 return 0; 533 } 534 535 return static_cast<float>(m_characterInCurrentGlyph - oldCharacterInCurrentGlyph) / (glyphEndOffset - glyphStartOffset); 536 } 537 533 538 void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer, GlyphIterationStyle iterationStyle, HashSet<const Font*>* fallbackFonts) 534 539 { 535 if ( static_cast<int>(offset)> m_end)540 if (offset > m_end) 536 541 offset = m_end; 537 542 … … 563 568 // account the text direction. 564 569 if (glyphBuffer && !leftmostGlyph) { 565 glyphBuffer->setInitialAdvance(complexTextRun.initialAdvance()); 570 CGSize initialAdvance = complexTextRun.initialAdvance(); 571 #if USE_LAYOUT_SPECIFIC_ADVANCES 572 unsigned index = ltr ? 0 : m_glyphOrigins.size() - 1; 573 initialAdvance.width += m_glyphOrigins[index].x; 574 initialAdvance.height += m_glyphOrigins[index].y; 575 #endif 576 glyphBuffer->setInitialAdvance(initialAdvance); 577 566 578 glyphBuffer->setLeadingExpansion(m_leadingExpansion); 567 579 } … … 578 590 glyphEndOffset = complexTextRun.endOffsetAt(g); 579 591 580 CGSize adjusted Advance = m_adjustedAdvances[k];592 CGSize adjustedBaseAdvance = m_adjustedBaseAdvances[k]; 581 593 582 594 if (glyphStartOffset + complexTextRun.stringLocation() >= m_currentCharacter) 583 595 return; 584 596 585 if (glyphBuffer && !m_characterInCurrentGlyph) 586 glyphBuffer->add(m_adjustedGlyphs[k], &complexTextRun.font(), adjustedAdvance, complexTextRun.indexAt(m_glyphInCurrentRun)); 597 if (glyphBuffer && !m_characterInCurrentGlyph) { 598 GlyphBufferAdvance paintAdvance = adjustedBaseAdvance; 599 #if USE_LAYOUT_SPECIFIC_ADVANCES 600 if (k + 1 < m_adjustedBaseAdvances.size()) { 601 paintAdvance.setWidth(paintAdvance.width() + m_glyphOrigins[k + 1].x - m_glyphOrigins[k].x); 602 paintAdvance.setHeight(paintAdvance.height() - m_glyphOrigins[k + 1].y + m_glyphOrigins[k].y); 603 } 604 #endif 605 glyphBuffer->add(m_adjustedGlyphs[k], &complexTextRun.font(), paintAdvance, complexTextRun.indexAt(m_glyphInCurrentRun)); 606 } 587 607 588 608 unsigned oldCharacterInCurrentGlyph = m_characterInCurrentGlyph; 589 609 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); 610 m_runWidthSoFar += adjustedBaseAdvance.width * runWidthSoFarFraction(glyphStartOffset, glyphEndOffset, oldCharacterInCurrentGlyph, iterationStyle); 602 611 603 612 if (glyphEndOffset + complexTextRun.stringLocation() > m_currentCharacter) … … 618 627 m_glyphInCurrentRun = 0; 619 628 } 620 if (!m_run.ltr() && m_numGlyphsSoFar == m_adjustedAdvances.size())621 m_runWidthSoFar += m_finalRoundingWidth;622 629 } 623 630 … … 657 664 bool runForbidsLeadingExpansion = (m_run.expansionBehavior() & LeadingExpansionMask) == ForbidLeadingExpansion; 658 665 bool runForbidsTrailingExpansion = (m_run.expansionBehavior() & TrailingExpansionMask) == ForbidTrailingExpansion; 666 659 667 // We are iterating in glyph order, not string order. Compare this to WidthIterator::advanceInternal() 660 668 for (size_t r = 0; r < runCount; ++r) { … … 665 673 // Represent the initial advance for a text run by adjusting the advance 666 674 // 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();675 if (r && m_adjustedBaseAdvances.size()) { 676 CGSize previousAdvance = m_adjustedBaseAdvances.last(); 669 677 previousAdvance.width += complexTextRun.initialAdvance().width; 670 678 previousAdvance.height -= complexTextRun.initialAdvance().height; 671 m_adjusted Advances[m_adjustedAdvances.size() - 1] = previousAdvance;679 m_adjustedBaseAdvances[m_adjustedBaseAdvances.size() - 1] = previousAdvance; 672 680 } 673 681 widthSinceLastCommit += complexTextRun.initialAdvance().width; … … 677 685 678 686 const CGGlyph* glyphs = complexTextRun.glyphs(); 679 const CGSize* advances = complexTextRun. advances();687 const CGSize* advances = complexTextRun.baseAdvances(); 680 688 681 689 bool lastRun = r + 1 == runCount; … … 751 759 m_expansion -= m_expansionPerOpportunity; 752 760 m_totalWidth += m_expansionPerOpportunity; 753 if (m_adjusted Advances.isEmpty())761 if (m_adjustedBaseAdvances.isEmpty()) 754 762 m_leadingExpansion = m_expansionPerOpportunity; 755 763 else 756 m_adjusted Advances.last().width += m_expansionPerOpportunity;764 m_adjustedBaseAdvances.last().width += m_expansionPerOpportunity; 757 765 } 758 766 if (expandRight) { … … 778 786 779 787 advance.height *= -1; 780 m_adjustedAdvances.append(advance); 788 m_adjustedBaseAdvances.append(advance); 789 #if USE_LAYOUT_SPECIFIC_ADVANCES 790 m_glyphOrigins.append(complexTextRun.glyphOrigins()[i]); 791 #endif 781 792 m_adjustedGlyphs.append(glyph); 782 793 -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextController.h
r204466 r205373 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 HashSet<const Font*>* m_fallbackFonts { nullptr }; 176 177 const FontCascade& m_font; 178 const TextRun& m_run; 163 179 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; 180 unsigned m_currentCharacter { 0 }; 181 unsigned m_end { 0 }; 182 183 float m_totalWidth { 0 }; 184 float m_runWidthSoFar { 0 }; 185 unsigned m_numGlyphsSoFar { 0 }; 186 unsigned m_currentRun { 0 }; 187 unsigned m_glyphInCurrentRun { 0 }; 188 unsigned m_characterInCurrentGlyph { 0 }; 189 float m_expansion { 0 }; 190 float m_expansionPerOpportunity { 0 }; 191 float m_leadingExpansion { 0 }; 192 193 float m_minGlyphBoundingBoxX { std::numeric_limits<float>::max() }; 194 float m_maxGlyphBoundingBoxX { std::numeric_limits<float>::min() }; 195 float m_minGlyphBoundingBoxY { std::numeric_limits<float>::max() }; 196 float m_maxGlyphBoundingBoxY { std::numeric_limits<float>::min() }; 197 198 bool m_isLTROnly { true }; 199 bool m_mayUseNaturalWritingDirection { false }; 200 bool m_forTextEmphasis { false }; 187 201 }; 188 202 -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
r203330 r205373 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
r205282 r205373 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.