Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / TextAutosizer.h
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef TextAutosizer_h
27 #define TextAutosizer_h
28
29 #include "core/HTMLNames.h"
30 #include "platform/text/WritingMode.h"
31 #include "wtf/HashMap.h"
32 #include "wtf/Noncopyable.h"
33 #include "wtf/OwnPtr.h"
34 #include "wtf/PassOwnPtr.h"
35
36 namespace WebCore {
37
38 class Document;
39 class RenderBlock;
40 class RenderObject;
41 struct TextAutosizingWindowInfo;
42
43 // Represents cluster related data. Instances should not persist between calls to processSubtree.
44 struct TextAutosizingClusterInfo {
45     explicit TextAutosizingClusterInfo(RenderBlock* root)
46         : root(root)
47         , blockContainingAllText(0)
48         , maxAllowedDifferenceFromTextWidth(150)
49     {
50     }
51
52     RenderBlock* root;
53     const RenderBlock* blockContainingAllText;
54
55     // Upper limit on the difference between the width of the cluster's block containing all
56     // text and that of a narrow child before the child becomes a separate cluster.
57     float maxAllowedDifferenceFromTextWidth;
58
59     // Descendants of the cluster that are narrower than the block containing all text and must be
60     // processed together.
61     Vector<TextAutosizingClusterInfo> narrowDescendants;
62 };
63
64 class TextAutosizer FINAL {
65     WTF_MAKE_NONCOPYABLE(TextAutosizer);
66
67 public:
68     static PassOwnPtr<TextAutosizer> create(Document* document) { return adoptPtr(new TextAutosizer(document)); }
69
70     bool processSubtree(RenderObject* layoutRoot);
71     void recalculateMultipliers();
72
73     static float computeAutosizedFontSize(float specifiedSize, float multiplier);
74
75 private:
76     friend class FastTextAutosizer;
77
78     enum TraversalDirection {
79         FirstToLast,
80         LastToFirst
81     };
82
83     explicit TextAutosizer(Document*);
84
85     bool isApplicable() const;
86     float clusterMultiplier(WritingMode, const TextAutosizingWindowInfo&, float textWidth) const;
87
88     void processClusterInternal(TextAutosizingClusterInfo&, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&, float multiplier);
89     void processCluster(TextAutosizingClusterInfo&, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&);
90     void processCompositeCluster(Vector<TextAutosizingClusterInfo>&, const TextAutosizingWindowInfo&);
91     void processContainer(float multiplier, RenderBlock* container, TextAutosizingClusterInfo&, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&);
92
93     void setMultiplier(RenderObject*, float);
94     void setMultiplierForList(RenderObject* renderer, float multiplier);
95
96     unsigned getCachedHash(const RenderObject* renderer, bool putInCacheIfAbsent);
97
98     static bool isAutosizingContainer(const RenderObject*);
99     static bool isNarrowDescendant(const RenderBlock*, TextAutosizingClusterInfo& parentClusterInfo);
100     static bool isWiderDescendant(const RenderBlock*, const TextAutosizingClusterInfo& parentClusterInfo);
101     static bool isIndependentDescendant(const RenderBlock*);
102     static bool isAutosizingCluster(const RenderBlock*, TextAutosizingClusterInfo& parentClusterInfo);
103
104     static bool containerShouldBeAutosized(const RenderBlock* container);
105     static bool containerContainsOneOfTags(const RenderBlock* cluster, const Vector<QualifiedName>& tags);
106     static bool containerIsRowOfLinks(const RenderObject* container);
107     static bool contentHeightIsConstrained(const RenderBlock* container);
108     static bool compositeClusterShouldBeAutosized(Vector<TextAutosizingClusterInfo>&, float blockWidth);
109     static void measureDescendantTextWidth(const RenderBlock* container, TextAutosizingClusterInfo&, float minTextWidth, float& textWidth);
110     unsigned computeCompositeClusterHash(Vector<TextAutosizingClusterInfo>&);
111     float computeMultiplier(Vector<TextAutosizingClusterInfo>&, const TextAutosizingWindowInfo&, float textWidth);
112
113     // Use to traverse the tree of descendants, excluding descendants of containers (but returning the containers themselves).
114     static RenderObject* nextInPreOrderSkippingDescendantsOfContainers(const RenderObject*, const RenderObject* stayWithin);
115
116     static const RenderBlock* findDeepestBlockContainingAllText(const RenderBlock* cluster);
117
118     // Depending on the traversal direction specified, finds the first or the last leaf text node child that doesn't
119     // belong to any cluster.
120     static const RenderObject* findFirstTextLeafNotInCluster(const RenderObject*, size_t& depth, TraversalDirection);
121
122     // Returns groups of narrow descendants of a given autosizing cluster. The groups are combined
123     // by the difference between the width of the descendant and the width of the parent cluster's
124     // |blockContainingAllText|.
125     static void getNarrowDescendantsGroupedByWidth(const TextAutosizingClusterInfo& parentClusterInfo, Vector<Vector<TextAutosizingClusterInfo> >&);
126
127     void addNonAutosizedCluster(unsigned key, TextAutosizingClusterInfo& value);
128     void secondPassProcessStaleNonAutosizedClusters();
129     void processStaleContainer(float multiplier, RenderBlock* cluster, TextAutosizingClusterInfo&);
130
131     Document* m_document;
132
133     HashMap<const RenderObject*, unsigned> m_hashCache;
134
135     // Mapping from all autosized (i.e. multiplier > 1) cluster hashes to their respective multipliers.
136     HashMap<unsigned, float> m_hashToMultiplier;
137     Vector<unsigned> m_hashesToAutosizeSecondPass;
138
139     // Mapping from a cluster hash to the corresponding cluster infos which have not been autosized yet.
140     HashMap<unsigned, OwnPtr<Vector<TextAutosizingClusterInfo> > > m_nonAutosizedClusters;
141
142     bool m_previouslyAutosized;
143 };
144
145 } // namespace WebCore
146
147 #endif // TextAutosizer_h