#ifndef TextAutosizer_h
#define TextAutosizer_h
#include "HTMLNames.h"
#include "platform/text/WritingMode.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
class Document;
class RenderBlock;
class RenderObject;
class RenderText;
struct TextAutosizingWindowInfo;
struct TextAutosizingClusterInfo {
explicit TextAutosizingClusterInfo(RenderBlock* root)
: root(root)
, blockContainingAllText(0)
, maxAllowedDifferenceFromTextWidth(150)
{
}
RenderBlock* root;
const RenderBlock* blockContainingAllText;
float maxAllowedDifferenceFromTextWidth;
Vector<TextAutosizingClusterInfo> narrowDescendants;
};
class TextAutosizer FINAL {
WTF_MAKE_NONCOPYABLE(TextAutosizer);
public:
static PassOwnPtr<TextAutosizer> create(Document* document) { return adoptPtr(new TextAutosizer(document)); }
bool processSubtree(RenderObject* layoutRoot);
void recalculateMultipliers();
static float computeAutosizedFontSize(float specifiedSize, float multiplier);
private:
friend class FastTextAutosizer;
enum TraversalDirection {
FirstToLast,
LastToFirst
};
explicit TextAutosizer(Document*);
bool isApplicable() const;
float clusterMultiplier(WritingMode, const TextAutosizingWindowInfo&, float textWidth) const;
void processClusterInternal(TextAutosizingClusterInfo&, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&, float multiplier);
void processCluster(TextAutosizingClusterInfo&, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&);
void processCompositeCluster(Vector<TextAutosizingClusterInfo>&, const TextAutosizingWindowInfo&);
void processContainer(float multiplier, RenderBlock* container, TextAutosizingClusterInfo&, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&);
void setMultiplier(RenderObject*, float);
void setMultiplierForList(RenderObject* renderer, float multiplier);
unsigned getCachedHash(const RenderObject* renderer, bool putInCacheIfAbsent);
static bool isAutosizingContainer(const RenderObject*);
static bool isNarrowDescendant(const RenderBlock*, TextAutosizingClusterInfo& parentClusterInfo);
static bool isWiderDescendant(const RenderBlock*, const TextAutosizingClusterInfo& parentClusterInfo);
static bool isIndependentDescendant(const RenderBlock*);
static bool isAutosizingCluster(const RenderBlock*, TextAutosizingClusterInfo& parentClusterInfo);
static bool containerShouldBeAutosized(const RenderBlock* container);
static bool containerContainsOneOfTags(const RenderBlock* cluster, const Vector<QualifiedName>& tags);
static bool containerIsRowOfLinks(const RenderObject* container);
static bool contentHeightIsConstrained(const RenderBlock* container);
static bool compositeClusterShouldBeAutosized(Vector<TextAutosizingClusterInfo>&, float blockWidth);
static void measureDescendantTextWidth(const RenderBlock* container, TextAutosizingClusterInfo&, float minTextWidth, float& textWidth);
unsigned computeCompositeClusterHash(Vector<TextAutosizingClusterInfo>&);
float computeMultiplier(Vector<TextAutosizingClusterInfo>&, const TextAutosizingWindowInfo&, float textWidth);
static RenderObject* nextInPreOrderSkippingDescendantsOfContainers(const RenderObject*, const RenderObject* stayWithin);
static const RenderBlock* findDeepestBlockContainingAllText(const RenderBlock* cluster);
static const RenderObject* findFirstTextLeafNotInCluster(const RenderObject*, size_t& depth, TraversalDirection);
static void getNarrowDescendantsGroupedByWidth(const TextAutosizingClusterInfo& parentClusterInfo, Vector<Vector<TextAutosizingClusterInfo> >&);
void addNonAutosizedCluster(unsigned key, TextAutosizingClusterInfo& value);
void secondPassProcessStaleNonAutosizedClusters();
void processStaleContainer(float multiplier, RenderBlock* cluster, TextAutosizingClusterInfo&);
Document* m_document;
HashMap<const RenderObject*, unsigned> m_hashCache;
HashMap<unsigned, float> m_hashToMultiplier;
Vector<unsigned> m_hashesToAutosizeSecondPass;
HashMap<unsigned, OwnPtr<Vector<TextAutosizingClusterInfo> > > m_nonAutosizedClusters;
bool m_previouslyAutosized;
};
}
#endif