class Document;
class RenderBlock;
+class RenderListItem;
+class RenderListMarker;
// Single-pass text autosizer (work in progress). Works in two stages:
// (1) record information about page elements during style recalc
void record(const RenderBlock*);
void destroy(const RenderBlock*);
+ void inflateListItem(RenderListItem*, RenderListMarker*);
- void beginLayout(RenderBlock*);
- void endLayout(RenderBlock*);
+ class LayoutScope {
+ public:
+ explicit LayoutScope(Document& document, RenderBlock* block)
+ : m_block(0)
+ {
+ m_textAutosizer = document.fastTextAutosizer();
+ if (m_textAutosizer) {
+ if (!m_textAutosizer->enabled()) {
+ m_textAutosizer = 0;
+ return;
+ }
+ m_block = block;
+ m_textAutosizer->beginLayout(m_block);
+ }
+ }
+
+ ~LayoutScope()
+ {
+ if (m_textAutosizer)
+ m_textAutosizer->endLayout(m_block);
+ }
+ private:
+ FastTextAutosizer* m_textAutosizer;
+ RenderBlock* m_block;
+ };
private:
+ typedef HashSet<const RenderBlock*> BlockSet;
+
+ // A supercluster represents autosizing information about a set of two or
+ // more blocks that all have the same fingerprint. Clusters whose roots
+ // belong to a supercluster will share a common multiplier and
+ // text-length-based autosizing status.
+ struct Supercluster {
+ explicit Supercluster(const BlockSet* roots)
+ : m_roots(roots)
+ , m_multiplier(0)
+ , m_anyClusterHasEnoughText(false)
+ {
+ }
+
+ const BlockSet* const m_roots;
+ float m_multiplier;
+ bool m_anyClusterHasEnoughText;
+ };
+
struct Cluster {
- explicit Cluster(const RenderBlock* root, bool autosize, Cluster* parent)
+ explicit Cluster(const RenderBlock* root, bool autosize, Cluster* parent, Supercluster* supercluster = 0)
: m_root(root)
+ , m_deepestBlockContainingAllText(0)
, m_parent(parent)
, m_autosize(autosize)
, m_multiplier(0)
, m_textLength(-1)
+ , m_supercluster(supercluster)
{
}
- const RenderBlock* m_root;
+ const RenderBlock* const m_root;
+ // The deepest block containing all text is computed lazily (see:
+ // deepestBlockContainingAllText). A value of 0 indicates the value has not been computed yet.
+ const RenderBlock* m_deepestBlockContainingAllText;
Cluster* m_parent;
bool m_autosize;
// The multiplier is computed lazily (see: clusterMultiplier) because it must be calculated
// Text length is computed lazily (see: textLength). This is an approximation and characters
// are assumed to be 1em wide. Negative values indicate the length has not been computed.
int m_textLength;
+ // A set of blocks that are similar to this block.
+ Supercluster* m_supercluster;
};
enum TextLeafSearch {
Last
};
- typedef HashSet<const RenderBlock*> BlockSet;
- typedef HashMap<const RenderBlock*, OwnPtr<Cluster> > ClusterMap;
- typedef Vector<Cluster*> ClusterStack;
+ typedef HashMap<AtomicString, OwnPtr<Supercluster> > SuperclusterMap;
+ typedef Vector<OwnPtr<Cluster> > ClusterStack;
// Fingerprints are computed during style recalc, for (some subset of)
// blocks that will become cluster roots.
explicit FastTextAutosizer(const Document*);
+ void beginLayout(RenderBlock*);
+ void endLayout(RenderBlock*);
void inflate(RenderBlock*);
bool enabled();
- void prepareRenderViewInfo(RenderView*);
+ void prepareRenderViewInfo();
bool isFingerprintingCandidate(const RenderBlock*);
bool clusterHasEnoughTextToAutosize(Cluster*);
+ bool clusterWouldHaveEnoughTextToAutosize(const RenderBlock*);
float textLength(Cluster*);
AtomicString computeFingerprint(const RenderBlock*);
- Cluster* maybeGetOrCreateCluster(const RenderBlock*);
- Cluster* addSupercluster(AtomicString, const RenderBlock*);
+ Cluster* maybeCreateCluster(const RenderBlock*);
+ Supercluster* getSupercluster(const RenderBlock*);
const RenderBlock* deepestCommonAncestor(BlockSet&);
float clusterMultiplier(Cluster*);
+ float superclusterMultiplier(Supercluster*);
+ float multiplierFromBlock(const RenderBlock*);
void applyMultiplier(RenderObject*, float);
+ bool mightBeWiderOrNarrowerDescendant(const RenderBlock*);
+ bool isWiderDescendant(Cluster*);
+ bool isNarrowerDescendant(Cluster*);
+ bool isLayoutRoot(const RenderBlock*) const;
Cluster* currentCluster() const;
RenderObject* nextChildSkippingChildrenOfBlocks(const RenderObject*, const RenderObject*);
- const RenderBlock* findDeepestBlockContainingAllText(const RenderBlock*);
- // Returns the first text leaf that is in the current cluster and not in a descendent cluster.
+
+ const RenderBlock* deepestBlockContainingAllText(Cluster*);
+ const RenderBlock* deepestBlockContainingAllText(const RenderBlock*);
+ // Returns the first text leaf that is in the current cluster. We attempt to not include text
+ // from descendant clusters but because descendant clusters may not exist, this is only an approximation.
// The TraversalDirection controls whether we return the first or the last text leaf.
const RenderObject* findTextLeaf(const RenderObject*, size_t&, TextLeafSearch);
// Clusters are created and destroyed during layout. The map key is the
// cluster root. Clusters whose roots share the same fingerprint use the
// same multiplier.
- ClusterMap m_clusters;
+ SuperclusterMap m_superclusters;
ClusterStack m_clusterStack;
FingerprintMapper m_fingerprintMapper;
};