Changeset 136047 in webkit


Ignore:
Timestamp:
Nov 28, 2012 1:02:30 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Text Autosizing: Clusters should use width of LCA of their text nodes
https://bugs.webkit.org/show_bug.cgi?id=102562

Patch by Anton Vayvod <avayvod@chromium.org> on 2012-11-28
Reviewed by Kenneth Rohde Christiansen.

Source/WebCore:

Many pages set a max-width on their content. So especially for the
RenderView, instead of just taking the width of |cluster| we find
the lowest common ancestor of the first and last descendant text node of
the cluster (i.e. the deepest wrapper block that contains all the text),
and use its width instead.

Tests: fast/text-autosizing/cluster-with-narrow-lca-and-cluster.html

fast/text-autosizing/cluster-with-narrow-lca.html
fast/text-autosizing/cluster-with-wide-lca.html
fast/text-autosizing/list-item-out-of-flow.html
fast/text-autosizing/wide-in-narrow-overflow-scroll.html

  • rendering/TextAutosizer.cpp:

(WebCore::TextAutosizer::processCluster): use text nodes LCA instead of cluster for width calculation
(WebCore::TextAutosizer::isAutosizingContainer): list items that are out of parent list element's flow are valid containers (that therefore become clusters in isAutosizingCluster)
(WebCore::TextAutosizer::findDeepestBlockContainingAllText): searches for LCA of text nodes ignoring descendant clusters
(WebCore::TextAutosizer::findFirstTextLeafNotInCluster): searches for the first or the last (depending on specified direction) text leaf node in-order ignoring any descendant clusters

  • rendering/TextAutosizer.h: new private methods declarations and an enum for tree traversal direction.

LayoutTests:

Many pages set a max-width on their content. So especially for the
RenderView, instead of just taking the width of |cluster| we find
the lowest common ancestor of the first and last descendant text node of
the cluster (i.e. the deepest wrapper block that contains all the text),
and use its width instead.
Had to update a couple of existing tests since the actual width for font
size multiplier calculation has been changed by the patch.

  • fast/text-autosizing/cluster-wide-in-narrow-expected.html:
  • fast/text-autosizing/cluster-wide-in-narrow.html:
  • fast/text-autosizing/cluster-with-narrow-lca-and-cluster-expected.html: Added.
  • fast/text-autosizing/cluster-with-narrow-lca-and-cluster.html: Added.
  • fast/text-autosizing/cluster-with-narrow-lca-expected.html: Added.
  • fast/text-autosizing/cluster-with-narrow-lca.html: Added.
  • fast/text-autosizing/cluster-with-wide-lca-expected.html: Added.
  • fast/text-autosizing/cluster-with-wide-lca.html: Added.
  • fast/text-autosizing/em-margin-border-padding-expected.html:
  • fast/text-autosizing/em-margin-border-padding.html:
  • fast/text-autosizing/list-item-out-of-flow-expected.html: Added.
  • fast/text-autosizing/list-item-out-of-flow.html: Added.
  • fast/text-autosizing/wide-child-expected.html:
  • fast/text-autosizing/wide-child.html:
  • fast/text-autosizing/wide-in-narrow-overflow-scroll-expected.html: Added.
  • fast/text-autosizing/wide-in-narrow-overflow-scroll.html: Added.
Location:
trunk
Files:
7 added
8 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r136045 r136047  
     12012-11-28  Anton Vayvod  <avayvod@chromium.org>
     2
     3        Text Autosizing: Clusters should use width of LCA of their text nodes
     4        https://bugs.webkit.org/show_bug.cgi?id=102562
     5
     6        Reviewed by Kenneth Rohde Christiansen.
     7
     8        Many pages set a max-width on their content. So especially for the
     9        RenderView, instead of just taking the width of |cluster| we find
     10        the lowest common ancestor of the first and last descendant text node of
     11        the cluster (i.e. the deepest wrapper block that contains all the text),
     12        and use its width instead.
     13        Had to update a couple of existing tests since the actual width for font
     14        size multiplier calculation has been changed by the patch.
     15
     16        * fast/text-autosizing/cluster-wide-in-narrow-expected.html:
     17        * fast/text-autosizing/cluster-wide-in-narrow.html:
     18        * fast/text-autosizing/cluster-with-narrow-lca-and-cluster-expected.html: Added.
     19        * fast/text-autosizing/cluster-with-narrow-lca-and-cluster.html: Added.
     20        * fast/text-autosizing/cluster-with-narrow-lca-expected.html: Added.
     21        * fast/text-autosizing/cluster-with-narrow-lca.html: Added.
     22        * fast/text-autosizing/cluster-with-wide-lca-expected.html: Added.
     23        * fast/text-autosizing/cluster-with-wide-lca.html: Added.
     24        * fast/text-autosizing/em-margin-border-padding-expected.html:
     25        * fast/text-autosizing/em-margin-border-padding.html:
     26        * fast/text-autosizing/list-item-out-of-flow-expected.html: Added.
     27        * fast/text-autosizing/list-item-out-of-flow.html: Added.
     28        * fast/text-autosizing/wide-child-expected.html:
     29        * fast/text-autosizing/wide-child.html:
     30        * fast/text-autosizing/wide-in-narrow-overflow-scroll-expected.html: Added.
     31        * fast/text-autosizing/wide-in-narrow-overflow-scroll.html: Added.
     32
    1332012-11-28  Alexandru Chiculita  <achicu@adobe.com>
    234
  • trunk/LayoutTests/fast/text-autosizing/cluster-with-narrow-lca-and-cluster.html

    r136046 r136047  
    66<style>
    77html { font-size: 16px; }
    8 body { width: 800px; margin: 0; overflow-y: hidden; }
     8body { width: 800px; overflow-y: hidden; }
    99</style>
    1010
     
    2121<body>
    2222
    23 <p style="margin: 1em; border: 1em solid blue; padding: 1em">
    24     This text should get autosized to 40px computed font size, but the 1em margins, borders and padding should remain just 16px. While debatable, this generally looks more consistent than having them be scaled.<br>
    25     Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    26 </p>
     23<div style="width: 400px">
     24  <div>
     25    This text should be autosized to just 20px computed font size (16 * 400/320), since the width of the least common ancestor of the cluster's text descendants is used for multiplier calculation.
     26  </div>
     27
     28  <div>
     29    This text should be similarly autosized to 20px.
     30  </div>
     31</div>
     32<div style="float: left; width: 800px">
     33    This text should be autosized to 40px computed font size (16 * 800/320). It should not affect autosizing for text above though since it's another cluster.<br>
     34    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
     35</div>
    2736
    2837</body>
    2938</html>
     39
  • trunk/LayoutTests/fast/text-autosizing/cluster-with-narrow-lca.html

    r136046 r136047  
    66<style>
    77html { font-size: 16px; }
    8 body { width: 800px; margin: 0; overflow-y: hidden; }
     8body { width: 800px; overflow-y: hidden; }
    99</style>
    1010
     
    2121<body>
    2222
    23 <div style="width: 320px">
    24     This text should all be autosized to 40px computed font-size, since although this block is narrow, it has a wide child block, so the cluster will be wide and need autosizing.
    25     <div style="width: 800px">
    26         Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    27     </div>
    28     Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
     23<div style="width: 400px">
     24  <div>
     25    This text should be autosized to just 20px computed font size (16 * 400/320), since the width of the least common ancestor of the cluster's text descendants is used for multiplier calculation.
     26  </div>
     27
     28  <div>
     29    This text should be similarly autosized to 20px.
     30  </div>
    2931</div>
    30 
    3132</body>
    3233</html>
     34
  • trunk/LayoutTests/fast/text-autosizing/em-margin-border-padding-expected.html

    r129195 r136047  
    66<style>
    77html { font-size: 16px; }
    8 body { width: 800px; margin: 0; overflow-y: hidden; }
     8body { width: 896px; margin: 0; overflow-y: hidden; }
    99</style>
    1010
     
    1313
    1414<p style="font-size: 2.5rem; margin: 1rem; border: 1rem solid blue; padding: 1rem">
    15     This text should get autosized to 40px computed font size, but the 1em margins, borders and padding should remain just 16px. While debatable, this generally looks more consistent than having them be scaled.<br>
     15    This text should get autosized to 40px computed font size (16 * 800/320), but the 1em margins, borders and padding should remain just 16px. While debatable, this generally looks more consistent than having them be scaled.<br>
    1616    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    1717</p>
  • trunk/LayoutTests/fast/text-autosizing/em-margin-border-padding.html

    r129195 r136047  
    66<style>
    77html { font-size: 16px; }
    8 body { width: 800px; margin: 0; overflow-y: hidden; }
     8body { width: 896px; margin: 0; overflow-y: hidden; }
    99</style>
    1010
     
    2222
    2323<p style="margin: 1em; border: 1em solid blue; padding: 1em">
    24     This text should get autosized to 40px computed font size, but the 1em margins, borders and padding should remain just 16px. While debatable, this generally looks more consistent than having them be scaled.<br>
     24    This text should get autosized to 40px computed font size (16 * 800/320), but the 1em margins, borders and padding should remain just 16px. While debatable, this generally looks more consistent than having them be scaled.<br>
    2525    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    2626</p>
  • trunk/LayoutTests/fast/text-autosizing/wide-child-expected.html

    r129195 r136047  
    1212<body>
    1313
    14 <div style="width: 320px; font-size: 2.5rem">
    15     This text should all be autosized to 40px computed font-size, since although this block is narrow, it has a wide child block, so the cluster will be wide and need autosizing.
    16     <div style="width: 800px">
     14<div style="width: 320px; font-size: 1rem">
     15        This text should not be autosized, as this div is the lowest common ancestor of the root cluster, and this div is narrow.<br>
     16    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
     17        <div style="width: 800px">
     18        This text should not be autosized since it doesn't affect the width of the parent block which is used to calculate the autosizing multiplier.<br>
     19        FIXME: Ideally this text should be autosized. Will need to be fixed later.<br>
    1720        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    1821    </div>
    19     Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    2022</div>
    2123
  • trunk/LayoutTests/fast/text-autosizing/wide-child.html

    r129195 r136047  
    2222
    2323<div style="width: 320px">
    24     This text should all be autosized to 40px computed font-size, since although this block is narrow, it has a wide child block, so the cluster will be wide and need autosizing.
     24    This text should not be autosized, as this div is the lowest common ancestor of the root cluster, and this div is narrow.<br>
     25    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    2526    <div style="width: 800px">
     27        This text should not be autosized since it doesn't affect the width of the parent block which is used to calculate the autosizing multiplier.<br>
     28        FIXME: Ideally this text should be autosized. Will need to be fixed later.<br>
    2629        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    2730    </div>
    28     Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    2931</div>
    3032
  • trunk/LayoutTests/fast/text-autosizing/wide-in-narrow-overflow-scroll.html

    r136046 r136047  
    2121<body>
    2222
    23 <div style="width: 320px">
    24     This text should all be autosized to 40px computed font-size, since although this block is narrow, it has a wide child block, so the cluster will be wide and need autosizing.
     23<div style="width: 400px">
     24  <div style="overflow-x: scroll">
    2525    <div style="width: 800px">
     26        This text should be autosized to 20px computed font size (16 * 400/320), since this is part of the root cluster, whose text descendants are all contained within the 400px wide grandparent of this div.<br>
    2627        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    2728    </div>
    28     Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
     29  </div>
     30
     31  <div>
     32        This text should be autosized to 20px computed font size (16 * 400/320).<br>
     33        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
     34  </div>
    2935</div>
    3036
    3137</body>
    3238</html>
     39
  • trunk/Source/WebCore/ChangeLog

    r136046 r136047  
     12012-11-28  Anton Vayvod  <avayvod@chromium.org>
     2
     3        Text Autosizing: Clusters should use width of LCA of their text nodes
     4        https://bugs.webkit.org/show_bug.cgi?id=102562
     5
     6        Reviewed by Kenneth Rohde Christiansen.
     7
     8        Many pages set a max-width on their content. So especially for the
     9        RenderView, instead of just taking the width of |cluster| we find
     10        the lowest common ancestor of the first and last descendant text node of
     11        the cluster (i.e. the deepest wrapper block that contains all the text),
     12        and use its width instead.
     13
     14        Tests: fast/text-autosizing/cluster-with-narrow-lca-and-cluster.html
     15               fast/text-autosizing/cluster-with-narrow-lca.html
     16               fast/text-autosizing/cluster-with-wide-lca.html
     17               fast/text-autosizing/list-item-out-of-flow.html
     18               fast/text-autosizing/wide-in-narrow-overflow-scroll.html
     19
     20        * rendering/TextAutosizer.cpp:
     21        (WebCore::TextAutosizer::processCluster): use text nodes LCA instead of cluster for width calculation
     22        (WebCore::TextAutosizer::isAutosizingContainer): list items that are out of parent list element's flow are valid containers (that therefore become clusters in isAutosizingCluster)
     23        (WebCore::TextAutosizer::findDeepestBlockContainingAllText): searches for LCA of text nodes ignoring descendant clusters
     24        (WebCore::TextAutosizer::findFirstTextLeafNotInCluster): searches for the first or the last (depending on specified direction) text leaf node in-order ignoring any descendant clusters
     25        * rendering/TextAutosizer.h: new private methods declarations and an enum for tree traversal direction.
     26
    1272012-11-28  Sadrul Habib Chowdhury  <sadrul@chromium.org>
    228
  • trunk/Source/WebCore/rendering/TextAutosizer.cpp

    r135553 r136047  
    3434#include "StyleInheritedData.h"
    3535
     36#include <algorithm>
     37
    3638namespace WebCore {
    3739
     
    9597    ASSERT(isAutosizingCluster(cluster));
    9698
    97     // FIXME: Many pages set a max-width on their content. So especially for the RenderView,
    98     // instead of just taking the width of |cluster| we should find the lowest common ancestor of
    99     // the first and last descendant text node of the cluster (i.e. the deepest wrapper block that
    100     // contains all the text), and use its width instead.
    101     RenderBlock* lowestCommonAncestor = cluster;
     99    // Many pages set a max-width on their content. So especially for the
     100    // RenderView, instead of just taking the width of |cluster| we find
     101    // the lowest common ancestor of the first and last descendant text node of
     102    // the cluster (i.e. the deepest wrapper block that contains all the text),
     103    // and use its width instead.
     104    const RenderBlock* lowestCommonAncestor = findDeepestBlockContainingAllText(cluster);
    102105    float commonAncestorWidth = lowestCommonAncestor->contentLogicalWidth();
    103106
     
    202205    // enable/disable Text Autosizing.
    203206    // - Must not be inline, as different multipliers on one line looks terrible.
    204     // - Must not be list items, as items in the same list should look consistent.
    205     return renderer->isRenderBlock() && !renderer->isInline() && !renderer->isListItem();
     207    // - Must not be list items, as items in the same list should look consistent (*).
     208    // * except for those list items positioned out of the list's flow.
     209    return renderer->isRenderBlock()
     210        && !renderer->isInline()
     211        && (!renderer->isListItem() || renderer->isOutOfFlowPositioned());
    206212}
    207213
     
    298304}
    299305
     306const RenderBlock* TextAutosizer::findDeepestBlockContainingAllText(const RenderBlock* cluster)
     307{
     308    ASSERT(isAutosizingCluster(cluster));
     309
     310    size_t firstDepth = 0;
     311    const RenderObject* firstTextLeaf = findFirstTextLeafNotInCluster(cluster, firstDepth, FirstToLast);
     312    if (!firstTextLeaf)
     313        return cluster;
     314
     315    size_t lastDepth = 0;
     316    const RenderObject* lastTextLeaf = findFirstTextLeafNotInCluster(cluster, lastDepth, LastToFirst);
     317    ASSERT(lastTextLeaf);
     318
     319    // Equalize the depths if necessary. Only one of the while loops below will get executed.
     320    const RenderObject* firstNode = firstTextLeaf;
     321    const RenderObject* lastNode = lastTextLeaf;
     322    while (firstDepth > lastDepth) {
     323        firstNode = firstNode->parent();
     324        --firstDepth;
     325    }
     326    while (lastDepth > firstDepth) {
     327        lastNode = lastNode->parent();
     328        --lastDepth;
     329    }
     330
     331    // Go up from both nodes until the parent is the same. Both pointers will point to the LCA then.
     332    while (firstNode != lastNode) {
     333        firstNode = firstNode->parent();
     334        lastNode = lastNode->parent();
     335    }
     336
     337    if (firstNode->isRenderBlock())
     338        return toRenderBlock(firstNode);
     339
     340    // containingBlock() should never leave the cluster, since it only skips ancestors when finding the
     341    // container of position:absolute/fixed blocks, and those cannot exist between a cluster and its text
     342    // nodes lowest common ancestor as isAutosizingCluster would have made them into their own independent
     343    // cluster.
     344    RenderBlock* containingBlock = firstNode->containingBlock();
     345    ASSERT(containingBlock->isDescendantOf(cluster));
     346
     347    return containingBlock;
     348}
     349
     350const RenderObject* TextAutosizer::findFirstTextLeafNotInCluster(const RenderObject* parent, size_t& depth, TraversalDirection direction)
     351{
     352    if (parent->isEmpty())
     353        return parent->isText() ? parent : 0;
     354
     355    ++depth;
     356    const RenderObject* child = (direction == FirstToLast) ? parent->firstChild() : parent->lastChild();
     357    while (child) {
     358        if (!isAutosizingContainer(child) || !isAutosizingCluster(toRenderBlock(child))) {
     359            const RenderObject* leaf = findFirstTextLeafNotInCluster(child, depth, direction);
     360            if (leaf)
     361                return leaf;
     362        }
     363        child = (direction == FirstToLast) ? child->nextSibling() : child->previousSibling();
     364    }
     365    --depth;
     366
     367    return 0;
     368}
     369
    300370} // namespace WebCore
    301371
  • trunk/Source/WebCore/rendering/TextAutosizer.h

    r129195 r136047  
    5656
    5757private:
     58    enum TraversalDirection {
     59        FirstToLast,
     60        LastToFirst
     61    };
     62
    5863    explicit TextAutosizer(Document*);
    5964
     
    7277    static RenderObject* nextInPreOrderSkippingDescendantsOfContainers(const RenderObject* current, const RenderObject* stayWithin);
    7378
     79    // Finds the lowest common ancestor of the first and the last descendant
     80    // text node (excluding those belonging to other autosizing clusters).
     81    static const RenderBlock* findDeepestBlockContainingAllText(const RenderBlock* cluster);
     82
     83    // Depending on the traversal direction specified, finds the first or the last leaf text node child that doesn't
     84    // belong to any cluster.
     85    static const RenderObject* findFirstTextLeafNotInCluster(const RenderObject*, size_t& depth, TraversalDirection);
     86
    7487    Document* m_document;
    7588};
Note: See TracChangeset for help on using the changeset viewer.