Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: Source/core/rendering/RenderText.cpp

Issue 104813005: Explicitly set text direction for TextRuns (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org) 2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org) 3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 5 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com) 6 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 left = max(left, leftEdge); 713 left = max(left, leftEdge);
714 left = min(left, rootRight - caretWidth); 714 left = min(left, rootRight - caretWidth);
715 } else { 715 } else {
716 left = min(left, rightEdge - caretWidthRightOfOffset); 716 left = min(left, rightEdge - caretWidthRightOfOffset);
717 left = max(left, rootLeft); 717 left = max(left, rootLeft);
718 } 718 }
719 719
720 return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, h eight) : IntRect(top, left, height, caretWidth); 720 return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, h eight) : IntRect(top, left, height, caretWidth);
721 } 721 }
722 722
723 ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len , float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyp hOverflow) const 723 ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len , float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallb ackFonts, GlyphOverflow* glyphOverflow) const
724 { 724 {
725 if (style()->hasTextCombine() && isCombineText()) { 725 if (style()->hasTextCombine() && isCombineText()) {
726 const RenderCombineText* combineText = toRenderCombineText(this); 726 const RenderCombineText* combineText = toRenderCombineText(this);
727 if (combineText->isCombined()) 727 if (combineText->isCombined())
728 return combineText->combinedTextWidth(f); 728 return combineText->combinedTextWidth(f);
729 } 729 }
730 730
731 if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) { 731 if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) {
732 float monospaceCharacterWidth = f.spaceWidth(); 732 float monospaceCharacterWidth = f.spaceWidth();
733 float w = 0; 733 float w = 0;
(...skipping 19 matching lines...) Expand all
753 } else { 753 } else {
754 w += monospaceCharacterWidth; 754 w += monospaceCharacterWidth;
755 isSpace = false; 755 isSpace = false;
756 } 756 }
757 if (isSpace && i > start) 757 if (isSpace && i > start)
758 w += f.wordSpacing(); 758 w += f.wordSpacing();
759 } 759 }
760 return w; 760 return w;
761 } 761 }
762 762
763 TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>(this ), f, this, start, len, style()); 763 TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>(this ), f, this, start, len, style(), textDirection);
764 run.setCharactersLength(textLength() - start); 764 run.setCharactersLength(textLength() - start);
765 ASSERT(run.charactersLength() >= run.length()); 765 ASSERT(run.charactersLength() >= run.length());
766 766
767 run.setCharacterScanForCodePath(!canUseSimpleFontCodePath()); 767 run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
768 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 768 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
769 run.setXPos(xPos); 769 run.setXPos(xPos);
770 return f.width(run, fallbackFonts, glyphOverflow); 770 return f.width(run, fallbackFonts, glyphOverflow);
771 } 771 }
772 772
773 void RenderText::trimmedPrefWidths(float leadWidth, 773 void RenderText::trimmedPrefWidths(float leadWidth,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 const Font& f = style()->font(); // FIXME: This ignores first-line. 832 const Font& f = style()->font(); // FIXME: This ignores first-line.
833 bool firstLine = true; 833 bool firstLine = true;
834 firstLineMaxWidth = maxWidth; 834 firstLineMaxWidth = maxWidth;
835 lastLineMaxWidth = maxWidth; 835 lastLineMaxWidth = maxWidth;
836 for (int i = 0; i < len; i++) { 836 for (int i = 0; i < len; i++) {
837 int linelen = 0; 837 int linelen = 0;
838 while (i + linelen < len && text[i + linelen] != '\n') 838 while (i + linelen < len && text[i + linelen] != '\n')
839 linelen++; 839 linelen++;
840 840
841 if (linelen) { 841 if (linelen) {
842 lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + las tLineMaxWidth, 0, 0); 842 lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + las tLineMaxWidth, LTR, 0, 0);
843 if (firstLine) { 843 if (firstLine) {
844 firstLine = false; 844 firstLine = false;
845 leadWidth = 0; 845 leadWidth = 0;
846 firstLineMaxWidth = lastLineMaxWidth; 846 firstLineMaxWidth = lastLineMaxWidth;
847 } 847 }
848 i += linelen; 848 i += linelen;
849 } else if (firstLine) { 849 } else if (firstLine) {
850 firstLineMaxWidth = 0; 850 firstLineMaxWidth = 0;
851 firstLine = false; 851 firstLine = false;
852 leadWidth = 0; 852 leadWidth = 0;
(...skipping 21 matching lines...) Expand all
874 if (preferredLogicalWidthsDirty()) 874 if (preferredLogicalWidthsDirty())
875 const_cast<RenderText*>(this)->computePreferredLogicalWidths(0); 875 const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
876 876
877 return m_maxWidth; 877 return m_maxWidth;
878 } 878 }
879 879
880 void RenderText::computePreferredLogicalWidths(float leadWidth) 880 void RenderText::computePreferredLogicalWidths(float leadWidth)
881 { 881 {
882 HashSet<const SimpleFontData*> fallbackFonts; 882 HashSet<const SimpleFontData*> fallbackFonts;
883 GlyphOverflow glyphOverflow; 883 GlyphOverflow glyphOverflow;
884 computePreferredLogicalWidths(leadWidth, fallbackFonts, glyphOverflow); 884 computePreferredLogicalWidths(leadWidth, LTR, fallbackFonts, glyphOverflow);
885 if (fallbackFonts.isEmpty() && !glyphOverflow.left && !glyphOverflow.right & & !glyphOverflow.top && !glyphOverflow.bottom) 885 if (fallbackFonts.isEmpty() && !glyphOverflow.left && !glyphOverflow.right & & !glyphOverflow.top && !glyphOverflow.bottom)
886 m_knownToHaveNoOverflowAndNoFallbackFonts = true; 886 m_knownToHaveNoOverflowAndNoFallbackFonts = true;
887 } 887 }
888 888
889 static inline float hyphenWidth(RenderText* renderer, const Font& font) 889 static inline float hyphenWidth(RenderText* renderer, const Font& font)
890 { 890 {
891 RenderStyle* style = renderer->style(); 891 RenderStyle* style = renderer->style();
892 return font.width(RenderBlockFlow::constructTextRun(renderer, font, style->h yphenString().string(), style)); 892 return font.width(RenderBlockFlow::constructTextRun(renderer, font, style->h yphenString().string(), style));
893 } 893 }
894 894
895 void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si mpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow) 895 void RenderText::computePreferredLogicalWidths(float leadWidth, TextDirection te xtDirection, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyph Overflow)
896 { 896 {
897 ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflow AndNoFallbackFonts); 897 ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflow AndNoFallbackFonts);
898 898
899 m_minWidth = 0; 899 m_minWidth = 0;
900 m_maxWidth = 0; 900 m_maxWidth = 0;
901 m_firstLineMinWidth = 0; 901 m_firstLineMinWidth = 0;
902 m_lastLineLineMinWidth = 0; 902 m_lastLineLineMinWidth = 0;
903 903
904 if (isBR()) 904 if (isBR())
905 return; 905 return;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 972
973 if (ignoringSpaces && !isSpace) 973 if (ignoringSpaces && !isSpace)
974 ignoringSpaces = false; 974 ignoringSpaces = false;
975 975
976 // Ignore spaces and soft hyphens 976 // Ignore spaces and soft hyphens
977 if (ignoringSpaces) { 977 if (ignoringSpaces) {
978 ASSERT(lastWordBoundary == i); 978 ASSERT(lastWordBoundary == i);
979 lastWordBoundary++; 979 lastWordBoundary++;
980 continue; 980 continue;
981 } else if (c == softHyphen) { 981 } else if (c == softHyphen) {
982 currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoun dary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); 982 currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoun dary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow);
983 if (firstGlyphLeftOverflow < 0) 983 if (firstGlyphLeftOverflow < 0)
984 firstGlyphLeftOverflow = glyphOverflow.left; 984 firstGlyphLeftOverflow = glyphOverflow.left;
985 lastWordBoundary = i + 1; 985 lastWordBoundary = i + 1;
986 continue; 986 continue;
987 } 987 }
988 988
989 bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable) ; 989 bool hasBreak = breakAll || isBreakable(breakIterator, i, nextBreakable) ;
990 bool betweenWords = true; 990 bool betweenWords = true;
991 int j = i; 991 int j = i;
992 while (c != '\n' && c != ' ' && c != '\t' && (c != softHyphen)) { 992 while (c != '\n' && c != ' ' && c != '\t' && (c != softHyphen)) {
993 j++; 993 j++;
994 if (j == len) 994 if (j == len)
995 break; 995 break;
996 c = uncheckedCharacterAt(j); 996 c = uncheckedCharacterAt(j);
997 if (isBreakable(breakIterator, j, nextBreakable) && characterAt(j - 1) != softHyphen) 997 if (isBreakable(breakIterator, j, nextBreakable) && characterAt(j - 1) != softHyphen)
998 break; 998 break;
999 if (breakAll) { 999 if (breakAll) {
1000 betweenWords = false; 1000 betweenWords = false;
1001 break; 1001 break;
1002 } 1002 }
1003 } 1003 }
1004 1004
1005 int wordLen = j - i; 1005 int wordLen = j - i;
1006 if (wordLen) { 1006 if (wordLen) {
1007 bool isSpace = (j < len) && c == ' '; 1007 bool isSpace = (j < len) && c == ' ';
1008 float w; 1008 float w;
1009 if (wordTrailingSpaceWidth && isSpace) 1009 if (wordTrailingSpaceWidth && isSpace)
1010 w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth; 1010 w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth;
1011 else { 1011 else {
1012 w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fal lbackFonts, &glyphOverflow); 1012 w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, text Direction, &fallbackFonts, &glyphOverflow);
1013 if (c == softHyphen) 1013 if (c == softHyphen)
1014 currMinWidth += hyphenWidth(this, f); 1014 currMinWidth += hyphenWidth(this, f);
1015 } 1015 }
1016 1016
1017 maxWordWidth = max(maxWordWidth, w); 1017 maxWordWidth = max(maxWordWidth, w);
1018 1018
1019 if (firstGlyphLeftOverflow < 0) 1019 if (firstGlyphLeftOverflow < 0)
1020 firstGlyphLeftOverflow = glyphOverflow.left; 1020 firstGlyphLeftOverflow = glyphOverflow.left;
1021 currMinWidth += w; 1021 currMinWidth += w;
1022 if (betweenWords) { 1022 if (betweenWords) {
1023 if (lastWordBoundary == i) 1023 if (lastWordBoundary == i)
1024 currMaxWidth += w; 1024 currMaxWidth += w;
1025 else 1025 else
1026 currMaxWidth += widthFromCache(f, lastWordBoundary, j - last WordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow); 1026 currMaxWidth += widthFromCache(f, lastWordBoundary, j - last WordBoundary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOve rflow);
1027 lastWordBoundary = j; 1027 lastWordBoundary = j;
1028 } 1028 }
1029 1029
1030 bool isCollapsibleWhiteSpace = (j < len) && styleToUse->isCollapsibl eWhiteSpace(c); 1030 bool isCollapsibleWhiteSpace = (j < len) && styleToUse->isCollapsibl eWhiteSpace(c);
1031 if (j < len && styleToUse->autoWrap()) 1031 if (j < len && styleToUse->autoWrap())
1032 m_hasBreakableChar = true; 1032 m_hasBreakableChar = true;
1033 1033
1034 // Add in wordSpacing to our currMaxWidth, but not if this is the la st word on a line or the 1034 // Add in wordSpacing to our currMaxWidth, but not if this is the la st word on a line or the
1035 // last word in the run. 1035 // last word in the run.
1036 if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !contains OnlyWhitespace(j, len-j)) 1036 if (wordSpacing && (isSpace || isCollapsibleWhiteSpace) && !contains OnlyWhitespace(j, len-j))
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 m_lastTextBox = s->prevTextBox(); 1438 m_lastTextBox = s->prevTextBox();
1439 else 1439 else
1440 s->nextTextBox()->setPreviousTextBox(s->prevTextBox()); 1440 s->nextTextBox()->setPreviousTextBox(s->prevTextBox());
1441 s->destroy(); 1441 s->destroy();
1442 return; 1442 return;
1443 } 1443 }
1444 1444
1445 m_containsReversedText |= !s->isLeftToRightDirection(); 1445 m_containsReversedText |= !s->isLeftToRightDirection();
1446 } 1446 }
1447 1447
1448 float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) co nst 1448 float RenderText::width(unsigned from, unsigned len, float xPos, TextDirection t extDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, Gly phOverflow* glyphOverflow) const
1449 { 1449 {
1450 if (from >= textLength()) 1450 if (from >= textLength())
1451 return 0; 1451 return 0;
1452 1452
1453 if (from + len > textLength()) 1453 if (from + len > textLength())
1454 len = textLength() - from; 1454 len = textLength() - from;
1455 1455
1456 return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyph Overflow); 1456 return width(from, len, style(firstLine)->font(), xPos, textDirection, fallb ackFonts, glyphOverflow);
1457 } 1457 }
1458 1458
1459 float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) con st 1459 float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, Glyp hOverflow* glyphOverflow) const
1460 { 1460 {
1461 ASSERT(from + len <= textLength()); 1461 ASSERT(from + len <= textLength());
1462 if (!textLength()) 1462 if (!textLength())
1463 return 0; 1463 return 0;
1464 1464
1465 float w; 1465 float w;
1466 if (&f == &style()->font()) { 1466 if (&f == &style()->font()) {
1467 if (!style()->preserveNewline() && !from && len == textLength() && (!gly phOverflow || !glyphOverflow->computeBounds)) { 1467 if (!style()->preserveNewline() && !from && len == textLength() && (!gly phOverflow || !glyphOverflow->computeBounds)) {
1468 if (fallbackFonts) { 1468 if (fallbackFonts) {
1469 ASSERT(glyphOverflow); 1469 ASSERT(glyphOverflow);
1470 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAnd NoFallbackFonts) { 1470 if (preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAnd NoFallbackFonts) {
1471 const_cast<RenderText*>(this)->computePreferredLogicalWidths (0, *fallbackFonts, *glyphOverflow); 1471 const_cast<RenderText*>(this)->computePreferredLogicalWidths (0, textDirection, *fallbackFonts, *glyphOverflow);
1472 if (fallbackFonts->isEmpty() && !glyphOverflow->left && !gly phOverflow->right && !glyphOverflow->top && !glyphOverflow->bottom) 1472 if (fallbackFonts->isEmpty() && !glyphOverflow->left && !gly phOverflow->right && !glyphOverflow->top && !glyphOverflow->bottom)
1473 m_knownToHaveNoOverflowAndNoFallbackFonts = true; 1473 m_knownToHaveNoOverflowAndNoFallbackFonts = true;
1474 } 1474 }
1475 w = m_maxWidth; 1475 w = m_maxWidth;
1476 } else 1476 } else
1477 w = maxLogicalWidth(); 1477 w = maxLogicalWidth();
1478 } else 1478 } else {
1479 w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow) ; 1479 w = widthFromCache(f, from, len, xPos, textDirection, fallbackFonts, glyphOverflow);
1480 }
1480 } else { 1481 } else {
1481 TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>( this), f, this, from, len, style()); 1482 TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>( this), f, this, from, len, style(), textDirection);
1482 run.setCharactersLength(textLength() - from); 1483 run.setCharactersLength(textLength() - from);
1483 ASSERT(run.charactersLength() >= run.length()); 1484 ASSERT(run.charactersLength() >= run.length());
1484 1485
1485 run.setCharacterScanForCodePath(!canUseSimpleFontCodePath()); 1486 run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
1486 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize()); 1487 run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
1487 run.setXPos(xPos); 1488 run.setXPos(xPos);
1488 w = f.width(run, fallbackFonts, glyphOverflow); 1489 w = f.width(run, fallbackFonts, glyphOverflow);
1489 } 1490 }
1490 1491
1491 return w; 1492 return w;
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 } 1842 }
1842 secureTextTimer->restartWithNewText(lastTypedCharacterOffset); 1843 secureTextTimer->restartWithNewText(lastTypedCharacterOffset);
1843 } 1844 }
1844 1845
1845 PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox() 1846 PassRefPtr<AbstractInlineTextBox> RenderText::firstAbstractInlineTextBox()
1846 { 1847 {
1847 return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox); 1848 return AbstractInlineTextBox::getOrCreate(this, m_firstTextBox);
1848 } 1849 }
1849 1850
1850 } // namespace WebCore 1851 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698