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

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

Issue 684213002: Return correct length for firstLetterLength. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2007 David Smith (catfish.man@gmail.com) 4 * (C) 2007 David Smith (catfish.man@gmail.com)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
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 3616 matching lines...) Expand 10 before | Expand all | Expand 10 after
3627 if (genChild->isText()) 3627 if (genChild->isText())
3628 genChild->setStyle(pseudoStyle); 3628 genChild->setStyle(pseudoStyle);
3629 } 3629 }
3630 } 3630 }
3631 3631
3632 static inline unsigned firstLetterLength(const String& text) 3632 static inline unsigned firstLetterLength(const String& text)
3633 { 3633 {
3634 unsigned length = 0; 3634 unsigned length = 0;
3635 unsigned textLength = text.length(); 3635 unsigned textLength = text.length();
3636 3636
3637 if (textLength == 0)
3638 return length;
3639
3637 // Account for leading spaces first. 3640 // Account for leading spaces first.
3638 while (length < textLength && isSpaceForFirstLetter(text[length])) 3641 while (length < textLength && isSpaceForFirstLetter(text[length]))
3639 length++; 3642 length++;
3640 3643
3641 // Now account for leading punctuation. 3644 // Now account for leading punctuation.
3642 while (length < textLength && isPunctuationForFirstLetter(text[length])) 3645 while (length < textLength && isPunctuationForFirstLetter(text[length]))
3643 length++; 3646 length++;
3644 3647
3645 // Bail if we didn't find a letter before the end of the text or before a sp ace. 3648 // Bail if we didn't find a letter before the end of the text or before a sp ace.
3646 if (isSpaceForFirstLetter(text[length]) || (textLength && length == textLeng th)) 3649 if (isSpaceForFirstLetter(text[length]) || length == textLength)
3647 return 0; 3650 return 0;
3648 3651
3649 // Account the next character for first letter. 3652 // Account the next character for first letter.
3650 length++; 3653 length++;
3651 3654
3652 // Keep looking allowed punctuation for the :first-letter. 3655 // Keep looking allowed punctuation for the :first-letter.
3653 for (unsigned scanLength = length; scanLength < textLength; ++scanLength) { 3656 for (unsigned scanLength = length; scanLength < textLength; ++scanLength) {
3654 UChar c = text[scanLength]; 3657 UChar c = text[scanLength];
3655 3658
3656 if (!isPunctuationForFirstLetter(c)) 3659 if (!isPunctuationForFirstLetter(c))
3657 break; 3660 break;
3658 3661
3659 length = scanLength + 1; 3662 length = scanLength + 1;
3660 } 3663 }
3661
3662 // FIXME: If textLength is 0, length may still be 1!
3663 return length; 3664 return length;
3664 } 3665 }
3665 3666
3666 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend erText& currentChild, unsigned length) 3667 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend erText& currentChild, unsigned length)
3667 { 3668 {
3668 ASSERT(length); 3669 ASSERT(length);
3669 3670
3670 RenderObject* firstLetterContainer = currentChild.parent(); 3671 RenderObject* firstLetterContainer = currentChild.parent();
3671 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container); 3672 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container);
3672 RenderBoxModelObject* firstLetter = 0; 3673 RenderBoxModelObject* firstLetter = 0;
(...skipping 30 matching lines...) Expand all
3703 3704
3704 // construct text fragment for the first letter 3705 // construct text fragment for the first letter
3705 RenderTextFragment* letter = 3706 RenderTextFragment* letter =
3706 new RenderTextFragment(remainingText->node() ? remainingText->node() : & remainingText->document(), oldText.impl(), 0, length); 3707 new RenderTextFragment(remainingText->node() ? remainingText->node() : & remainingText->document(), oldText.impl(), 0, length);
3707 letter->setStyle(pseudoStyle); 3708 letter->setStyle(pseudoStyle);
3708 firstLetter->addChild(letter); 3709 firstLetter->addChild(letter);
3709 3710
3710 currentChild.destroy(); 3711 currentChild.destroy();
3711 } 3712 }
3712 3713
3714 // Once we see any of these renderers we can stop looking for first-letter as
3715 // they signal the end of the first line of text.
3716 bool RenderBlock::isInvalidFirstLetterRenderer(RenderObject* obj) const
3717 {
3718 return (obj->isBR() || (obj->isText() && toRenderText(obj)->isWordBreak()));
3719 }
3720
3713 void RenderBlock::updateFirstLetter() 3721 void RenderBlock::updateFirstLetter()
3714 { 3722 {
3715 if (!document().styleEngine()->usesFirstLetterRules()) 3723 if (!document().styleEngine()->usesFirstLetterRules())
3716 return; 3724 return;
3717 // Don't recur 3725 // Don't recur
3718 if (style()->styleType() == FIRST_LETTER) 3726 if (style()->styleType() == FIRST_LETTER)
3719 return; 3727 return;
3720 3728
3721 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find 3729 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
3722 // an efficient way to check for that situation though before implementing a nything. 3730 // an efficient way to check for that situation though before implementing a nything.
3723 RenderObject* firstLetterBlock = findFirstLetterBlock(this); 3731 RenderObject* firstLetterBlock = findFirstLetterBlock(this);
3724 if (!firstLetterBlock) 3732 if (!firstLetterBlock)
3725 return; 3733 return;
3726 3734
3727 // Drill into inlines looking for our first text child. 3735 // Drill into inlines looking for our first text child.
3728 RenderObject* currChild = firstLetterBlock->slowFirstChild(); 3736 RenderObject* currChild = firstLetterBlock->slowFirstChild();
3729 unsigned length = 0; 3737 unsigned length = 0;
3730 while (currChild) { 3738 while (currChild) {
3731 if (currChild->isText()) { 3739 if (currChild->isText()) {
3732 // FIXME: If there is leading punctuation in a different RenderText than 3740 // FIXME: If there is leading punctuation in a different RenderText than
3733 // the first letter, we'll not apply the correct style to it. 3741 // the first letter, we'll not apply the correct style to it.
3734 length = firstLetterLength(toRenderText(currChild)->originalText()); 3742 length = firstLetterLength(toRenderText(currChild)->originalText());
3735 if (length) 3743 if (length || isInvalidFirstLetterRenderer(currChild))
3736 break; 3744 break;
3737 currChild = currChild->nextSibling(); 3745 currChild = currChild->nextSibling();
3738 } else if (currChild->isListMarker()) { 3746 } else if (currChild->isListMarker()) {
3739 currChild = currChild->nextSibling(); 3747 currChild = currChild->nextSibling();
3740 } else if (currChild->isFloatingOrOutOfFlowPositioned()) { 3748 } else if (currChild->isFloatingOrOutOfFlowPositioned()) {
3741 if (currChild->style()->styleType() == FIRST_LETTER) { 3749 if (currChild->style()->styleType() == FIRST_LETTER) {
3742 currChild = currChild->slowFirstChild(); 3750 currChild = currChild->slowFirstChild();
3743 break; 3751 break;
3744 } 3752 }
3745 currChild = currChild->nextSibling(); 3753 currChild = currChild->nextSibling();
(...skipping 13 matching lines...) Expand all
3759 3767
3760 // If the child already has style, then it has already been created, so we j ust want 3768 // If the child already has style, then it has already been created, so we j ust want
3761 // to update it. 3769 // to update it.
3762 if (currChild->parent()->style()->styleType() == FIRST_LETTER) { 3770 if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
3763 updateFirstLetterStyle(firstLetterBlock, currChild); 3771 updateFirstLetterStyle(firstLetterBlock, currChild);
3764 return; 3772 return;
3765 } 3773 }
3766 3774
3767 // FIXME: This black-list of disallowed RenderText subclasses is fragile. 3775 // FIXME: This black-list of disallowed RenderText subclasses is fragile.
3768 // Should counter be on this list? What about RenderTextFragment? 3776 // Should counter be on this list? What about RenderTextFragment?
3769 if (!currChild->isText() || currChild->isBR() || toRenderText(currChild)->is WordBreak()) 3777 if (!currChild->isText() || isInvalidFirstLetterRenderer(currChild))
3770 return; 3778 return;
3771 3779
3772 createFirstLetterRenderer(firstLetterBlock, toRenderText(*currChild), length ); 3780 createFirstLetterRenderer(firstLetterBlock, toRenderText(*currChild), length );
3773 } 3781 }
3774 3782
3775 // Helper methods for obtaining the last line, computing line counts and heights for line counts 3783 // Helper methods for obtaining the last line, computing line counts and heights for line counts
3776 // (crawling into blocks). 3784 // (crawling into blocks).
3777 static bool shouldCheckLines(RenderObject* obj) 3785 static bool shouldCheckLines(RenderObject* obj)
3778 { 3786 {
3779 return !obj->isFloatingOrOutOfFlowPositioned() 3787 return !obj->isFloatingOrOutOfFlowPositioned()
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
4361 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const 4369 void RenderBlock::showLineTreeAndMark(const InlineBox* markedBox1, const char* m arkedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const Render Object* obj) const
4362 { 4370 {
4363 showRenderObject(); 4371 showRenderObject();
4364 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box()) 4372 for (const RootInlineBox* root = firstRootBox(); root; root = root->nextRoot Box())
4365 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1); 4373 root->showLineTreeAndMark(markedBox1, markedLabel1, markedBox2, markedLa bel2, obj, 1);
4366 } 4374 }
4367 4375
4368 #endif 4376 #endif
4369 4377
4370 } // namespace blink 4378 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698