SVGTextChunkLayoutInfo.h [plain text]
#ifndef SVGTextChunkLayoutInfo_h
#define SVGTextChunkLayoutInfo_h
#if ENABLE(SVG)
#include "AffineTransform.h"
#include "SVGTextContentElement.h"
#include <wtf/Assertions.h>
#include <wtf/Vector.h>
namespace WebCore {
class InlineBox;
class SVGInlineTextBox;
struct SVGInlineBoxCharacterRange {
SVGInlineBoxCharacterRange()
: startOffset(INT_MIN)
, endOffset(INT_MIN)
, box(0)
{
}
bool isOpen() const { return (startOffset == endOffset) && (endOffset == INT_MIN); }
bool isClosed() const { return startOffset != INT_MIN && endOffset != INT_MIN; }
int startOffset;
int endOffset;
InlineBox* box;
};
struct SVGChar;
typedef SVGTextContentElement::SVGLengthAdjustType ELengthAdjust;
struct SVGTextChunk {
SVGTextChunk()
: anchor(TA_START)
, textLength(0.0f)
, lengthAdjust(SVGTextContentElement::LENGTHADJUST_SPACING)
, ctm()
, isVerticalText(false)
, isTextPath(false)
, start(0)
, end(0)
{ }
ETextAnchor anchor;
float textLength;
ELengthAdjust lengthAdjust;
AffineTransform ctm;
bool isVerticalText : 1;
bool isTextPath : 1;
Vector<SVGChar>::iterator start;
Vector<SVGChar>::iterator end;
Vector<SVGInlineBoxCharacterRange> boxes;
};
struct SVGTextChunkWalkerBase {
virtual ~SVGTextChunkWalkerBase() { }
virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end) = 0;
virtual void start(InlineBox*) = 0;
virtual void end(InlineBox*) = 0;
};
template<typename CallbackClass>
struct SVGTextChunkWalker : public SVGTextChunkWalkerBase {
public:
typedef void (CallbackClass::*SVGTextChunkWalkerCallback)(SVGInlineTextBox* textBox,
int startOffset,
const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start,
const Vector<SVGChar>::iterator& end);
typedef void (CallbackClass::*SVGTextChunkStartCallback)(InlineBox* box);
typedef void (CallbackClass::*SVGTextChunkEndCallback)(InlineBox* box);
SVGTextChunkWalker(CallbackClass* object,
SVGTextChunkWalkerCallback walker,
SVGTextChunkStartCallback start = 0,
SVGTextChunkEndCallback end = 0)
: m_object(object)
, m_walkerCallback(walker)
, m_startCallback(start)
, m_endCallback(end)
{
ASSERT(object);
ASSERT(walker);
}
virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const AffineTransform& chunkCtm,
const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
{
(*m_object.*m_walkerCallback)(textBox, startOffset, chunkCtm, start, end);
}
virtual void start(InlineBox* box)
{
if (m_startCallback)
(*m_object.*m_startCallback)(box);
else
ASSERT_NOT_REACHED();
}
virtual void end(InlineBox* box)
{
if (m_endCallback)
(*m_object.*m_endCallback)(box);
else
ASSERT_NOT_REACHED();
}
private:
CallbackClass* m_object;
SVGTextChunkWalkerCallback m_walkerCallback;
SVGTextChunkStartCallback m_startCallback;
SVGTextChunkEndCallback m_endCallback;
};
struct SVGTextChunkLayoutInfo {
SVGTextChunkLayoutInfo(Vector<SVGTextChunk>& textChunks)
: assignChunkProperties(true)
, handlingTextPath(false)
, svgTextChunks(textChunks)
, it(0)
{
}
bool assignChunkProperties : 1;
bool handlingTextPath : 1;
Vector<SVGTextChunk>& svgTextChunks;
Vector<SVGChar>::iterator it;
SVGTextChunk chunk;
};
}
#endif // ENABLE(SVG)
#endif // SVGTextChunkLayoutInfo_h