return adoptPtr(new FastTextAutosizer(document));
}
+ void updatePageInfoInAllFrames();
+ void updatePageInfo();
void record(const RenderBlock*);
void destroy(const RenderBlock*);
void inflateListItem(RenderListItem*, RenderListMarker*);
RenderBlock* m_block;
};
+ class DeferUpdatePageInfo {
+ public:
+ explicit DeferUpdatePageInfo(Page*);
+ ~DeferUpdatePageInfo();
+ private:
+ RefPtr<LocalFrame> m_mainFrame;
+ };
+
private:
typedef HashSet<const RenderBlock*> BlockSet;
NotEnoughText
};
- enum PageAutosizingStatus {
- PageAutosizingStatusUnknown,
- PageNeedsAutosizing,
- PageDoesNotNeedAutosizing
+ enum RelayoutBehavior {
+ AlreadyInLayout, // The default; appropriate if we are already in layout.
+ LayoutNeeded // Use this if changing a multiplier outside of layout.
+ };
+
+ enum BeginLayoutBehavior {
+ StopLayout,
+ ContinueLayout
+ };
+
+ enum BlockFlag {
+ // A block that is evaluated for becoming a cluster root.
+ POTENTIAL_ROOT = 1 << 0,
+ // A cluster root that establishes an independent multiplier.
+ INDEPENDENT = 1 << 1,
+ // A cluster root with an explicit width. These are likely to be independent.
+ EXPLICIT_WIDTH = 1 << 2,
+ // A cluster that is wider or narrower than its parent. These also create an
+ // independent multiplier, but this state cannot be determined until layout.
+ WIDER_OR_NARROWER = 1 << 3,
+ // A cluster that suppresses autosizing.
+ SUPPRESSING = 1 << 4
};
+ typedef unsigned BlockFlags;
+
// 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
struct Supercluster {
explicit Supercluster(const BlockSet* roots)
: m_roots(roots)
+ , m_hasEnoughTextToAutosize(UnknownAmountOfText)
, m_multiplier(0)
{
}
const BlockSet* const m_roots;
+ HasEnoughTextToAutosize m_hasEnoughTextToAutosize;
float m_multiplier;
};
struct Cluster {
- explicit Cluster(const RenderBlock* root, bool autosize, Cluster* parent, Supercluster* supercluster = 0)
+ explicit Cluster(const RenderBlock* root, BlockFlags flags, Cluster* parent, Supercluster* supercluster = 0)
: m_root(root)
+ , m_flags(flags)
, m_deepestBlockContainingAllText(0)
, m_parent(parent)
- , m_autosize(autosize)
, m_multiplier(0)
, m_hasEnoughTextToAutosize(UnknownAmountOfText)
, m_supercluster(supercluster)
}
const RenderBlock* const m_root;
+ BlockFlags m_flags;
// 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
// after the lowest block containing all text has entered layout (the
// m_blocksThatHaveBegunLayout assertions cover this). Note: the multiplier is still
public:
void add(const RenderObject*, Fingerprint);
void addTentativeClusterRoot(const RenderBlock*, Fingerprint);
- void remove(const RenderObject*);
+ // Returns true if any BlockSet was modified or freed by the removal.
+ bool remove(const RenderObject*);
Fingerprint get(const RenderObject*);
BlockSet& getTentativeClusterRoots(Fingerprint);
private:
#endif
};
+ struct PageInfo {
+ PageInfo()
+ : m_frameWidth(0)
+ , m_layoutWidth(0)
+ , m_baseMultiplier(0)
+ , m_pageNeedsAutosizing(false)
+ , m_hasAutosized(false)
+ , m_settingEnabled(false)
+ {
+ }
+
+ int m_frameWidth; // LocalFrame width in density-independent pixels (DIPs).
+ int m_layoutWidth; // Layout width in CSS pixels.
+ float m_baseMultiplier; // Includes accessibility font scale factor and device scale adjustment.
+ bool m_pageNeedsAutosizing;
+ bool m_hasAutosized;
+ bool m_settingEnabled;
+ };
+
explicit FastTextAutosizer(const Document*);
void beginLayout(RenderBlock*);
void endLayout(RenderBlock*);
void inflateTable(RenderTable*);
void inflate(RenderBlock*);
- bool enabled();
- void updateRenderViewInfo();
+ bool shouldHandleLayout() const;
+ void setAllTextNeedsLayout();
+ void resetMultipliers();
+ BeginLayoutBehavior prepareForLayout(const RenderBlock*);
void prepareClusterStack(const RenderObject*);
- bool isFingerprintingCandidate(const RenderBlock*);
bool clusterHasEnoughTextToAutosize(Cluster*, const RenderBlock* widthProvider = 0);
- bool anyClusterHasEnoughTextToAutosize(const BlockSet* roots, const RenderBlock* widthProvider = 0);
+ bool superclusterHasEnoughTextToAutosize(Supercluster*, const RenderBlock* widthProvider = 0);
bool clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider = 0);
Fingerprint getFingerprint(const RenderObject*);
Fingerprint computeFingerprint(const RenderObject*);
Cluster* maybeCreateCluster(const RenderBlock*);
Supercluster* getSupercluster(const RenderBlock*);
- const RenderBlock* deepestCommonAncestor(BlockSet&);
float clusterMultiplier(Cluster*);
float superclusterMultiplier(Cluster*);
// A cluster's width provider is typically the deepest block containing all text.
// There are exceptions, such as tables and table cells which use the table itself for width.
const RenderBlock* clusterWidthProvider(const RenderBlock*);
+ const RenderBlock* maxClusterWidthProvider(const Supercluster*, const RenderBlock* currentRoot);
// Typically this returns a block's computed width. In the case of tables layout, this
// width is not yet known so the fixed width is used if it's available, or the containing
// block's width otherwise.
float widthFromBlock(const RenderBlock*);
float multiplierFromBlock(const RenderBlock*);
- void applyMultiplier(RenderObject*, float);
+ void applyMultiplier(RenderObject*, float, RelayoutBehavior = AlreadyInLayout);
bool isWiderOrNarrowerDescendant(Cluster*);
- bool isLayoutRoot(const RenderBlock*) const;
-
Cluster* currentCluster() const;
-
- RenderObject* nextChildSkippingChildrenOfBlocks(const RenderObject*, const RenderObject*);
-
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);
+ bool shouldDescendForTableInflation(RenderObject*);
+ BlockFlags classifyBlock(const RenderObject*, BlockFlags mask = UINT_MAX);
+#ifdef AUTOSIZING_DOM_DEBUG_INFO
+ void writeClusterDebugInfo(Cluster*);
+#endif
const Document* m_document;
- int m_frameWidth; // LocalFrame width in density-independent pixels (DIPs).
- int m_layoutWidth; // Layout width in CSS pixels.
- float m_baseMultiplier; // Includes accessibility font scale factor and device scale adjustment.
- PageAutosizingStatus m_pageAutosizingStatus;
- const RenderBlock* m_firstBlock; // First block to receive beginLayout.
+ const RenderBlock* m_firstBlockToBeginLayout;
#ifndef NDEBUG
- bool m_renderViewInfoPrepared;
BlockSet m_blocksThatHaveBegunLayout; // Used to ensure we don't compute properties of a block before beginLayout() is called on it.
#endif
SuperclusterMap m_superclusters;
ClusterStack m_clusterStack;
FingerprintMapper m_fingerprintMapper;
+ Vector<RefPtr<RenderStyle> > m_stylesRetainedDuringLayout;
+ // FIXME: All frames should share the same m_pageInfo instance.
+ PageInfo m_pageInfo;
+ bool m_updatePageInfoDeferred;
};
} // namespace WebCore