2 * This file is part of the WebKit project.
4 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 #ifndef SVGCharacterLayoutInfo_h
24 #define SVGCharacterLayoutInfo_h
27 #include <wtf/Assertions.h>
28 #include <wtf/HashMap.h>
29 #include <wtf/HashSet.h>
30 #include <wtf/Vector.h>
32 #include "TransformationMatrix.h"
33 #include <wtf/RefCounted.h>
34 #include "SVGRenderStyle.h"
35 #include "SVGTextContentElement.h"
41 class SVGInlineTextBox
;
44 class SVGTextPositioningElement
;
47 class PositionedVector
: public Vector
<Type
>
50 PositionedVector
<Type
>()
55 unsigned position() const
60 void advance(unsigned position
)
62 m_position
+= position
;
63 ASSERT(m_position
< Vector
<Type
>::size());
66 Type
valueAtCurrentPosition() const
68 ASSERT(m_position
< Vector
<Type
>::size());
69 return Vector
<Type
>::at(m_position
);
76 class PositionedFloatVector
: public PositionedVector
<float> { };
79 struct SVGCharacterLayoutInfo
{
80 SVGCharacterLayoutInfo(Vector
<SVGChar
>&);
82 enum StackType
{ XStack
, YStack
, DxStack
, DyStack
, AngleStack
, BaselineShiftStack
};
84 bool xValueAvailable() const;
85 bool yValueAvailable() const;
86 bool dxValueAvailable() const;
87 bool dyValueAvailable() const;
88 bool angleValueAvailable() const;
89 bool baselineShiftValueAvailable() const;
91 float xValueNext() const;
92 float yValueNext() const;
93 float dxValueNext() const;
94 float dyValueNext() const;
95 float angleValueNext() const;
96 float baselineShiftValueNext() const;
98 void processedChunk(float savedShiftX
, float savedShiftY
);
99 void processedSingleCharacter();
101 bool nextPathLayoutPointAndAngle(float glyphAdvance
, float extraAdvance
, float newOffset
);
103 // Used for text-on-path.
104 void addLayoutInformation(InlineFlowBox
*, float textAnchorOffset
= 0.0f
);
106 bool inPathLayout() const;
107 void setInPathLayout(bool value
);
109 // Used for anything else.
110 void addLayoutInformation(SVGTextPositioningElement
*);
119 // Accumulated dx/dy values
123 // Accumulated baseline-shift values
127 // Path specific advance values to handle lengthAdjust
128 float pathExtraAdvance
;
129 float pathTextLength
;
130 float pathChunkLength
;
133 Vector
<SVGChar
>& svgChars
;
134 bool nextDrawnSeperated
: 1;
137 // Used for baseline-shift.
138 void addStackContent(StackType
, float);
141 void addStackContent(StackType
, SVGNumberList
*);
143 // Used for x/y/dx/dy.
144 void addStackContent(StackType
, SVGLengthList
*, const SVGElement
*);
146 void addStackContent(StackType
, const PositionedFloatVector
&);
152 void angleStackWalk();
153 void baselineShiftStackWalk();
156 bool xStackChanged
: 1;
157 bool yStackChanged
: 1;
158 bool dxStackChanged
: 1;
159 bool dyStackChanged
: 1;
160 bool angleStackChanged
: 1;
161 bool baselineShiftStackChanged
: 1;
163 // text on path layout
167 float layoutPathLength
;
170 Vector
<PositionedFloatVector
> xStack
;
171 Vector
<PositionedFloatVector
> yStack
;
172 Vector
<PositionedFloatVector
> dxStack
;
173 Vector
<PositionedFloatVector
> dyStack
;
174 Vector
<PositionedFloatVector
> angleStack
;
175 Vector
<float> baselineShiftStack
;
178 // Holds extra data, when the character is laid out on a path
179 struct SVGCharOnPath
: RefCounted
<SVGCharOnPath
> {
180 static PassRefPtr
<SVGCharOnPath
> create() { return adoptRef(new SVGCharOnPath
); }
188 float orientationAngle
;
198 , orientationAngle(0.0f
)
209 , orientationShiftX(0.0f
)
210 , orientationShiftY(0.0f
)
212 , drawnSeperated(false)
213 , newTextChunk(false)
225 float orientationShiftX
;
226 float orientationShiftY
;
228 RefPtr
<SVGCharOnPath
> pathData
;
230 // Determines wheter this char needs to be drawn seperated
231 bool drawnSeperated
: 1;
233 // Determines wheter this char starts a new chunk
234 bool newTextChunk
: 1;
237 bool isHidden() const;
238 TransformationMatrix
characterTransform() const;
241 struct SVGInlineBoxCharacterRange
{
242 SVGInlineBoxCharacterRange()
243 : startOffset(INT_MIN
)
249 bool isOpen() const { return (startOffset
== endOffset
) && (endOffset
== INT_MIN
); }
250 bool isClosed() const { return startOffset
!= INT_MIN
&& endOffset
!= INT_MIN
; }
258 // Convenience typedef
259 typedef SVGTextContentElement::SVGLengthAdjustType ELengthAdjust
;
261 struct SVGTextChunk
{
265 , lengthAdjust(SVGTextContentElement::LENGTHADJUST_SPACING
)
267 , isVerticalText(false)
273 // text-anchor support
276 // textLength & lengthAdjust support
278 ELengthAdjust lengthAdjust
;
279 TransformationMatrix ctm
;
282 bool isVerticalText
: 1;
286 Vector
<SVGChar
>::iterator start
;
287 Vector
<SVGChar
>::iterator end
;
289 Vector
<SVGInlineBoxCharacterRange
> boxes
;
292 struct SVGTextChunkWalkerBase
{
293 virtual ~SVGTextChunkWalkerBase() { }
295 virtual void operator()(SVGInlineTextBox
* textBox
, int startOffset
, const TransformationMatrix
& chunkCtm
,
296 const Vector
<SVGChar
>::iterator
& start
, const Vector
<SVGChar
>::iterator
& end
) = 0;
298 // Followings methods are only used for painting text chunks
299 virtual void start(InlineBox
*) = 0;
300 virtual void end(InlineBox
*) = 0;
302 virtual bool setupFill(InlineBox
*) = 0;
303 virtual bool setupStroke(InlineBox
*) = 0;
306 template<typename CallbackClass
>
307 struct SVGTextChunkWalker
: public SVGTextChunkWalkerBase
{
309 typedef void (CallbackClass::*SVGTextChunkWalkerCallback
)(SVGInlineTextBox
* textBox
,
311 const TransformationMatrix
& chunkCtm
,
312 const Vector
<SVGChar
>::iterator
& start
,
313 const Vector
<SVGChar
>::iterator
& end
);
315 // These callbacks are only used for painting!
316 typedef void (CallbackClass::*SVGTextChunkStartCallback
)(InlineBox
* box
);
317 typedef void (CallbackClass::*SVGTextChunkEndCallback
)(InlineBox
* box
);
319 typedef bool (CallbackClass::*SVGTextChunkSetupFillCallback
)(InlineBox
* box
);
320 typedef bool (CallbackClass::*SVGTextChunkSetupStrokeCallback
)(InlineBox
* box
);
322 SVGTextChunkWalker(CallbackClass
* object
,
323 SVGTextChunkWalkerCallback walker
,
324 SVGTextChunkStartCallback start
= 0,
325 SVGTextChunkEndCallback end
= 0,
326 SVGTextChunkSetupFillCallback fill
= 0,
327 SVGTextChunkSetupStrokeCallback stroke
= 0)
329 , m_walkerCallback(walker
)
330 , m_startCallback(start
)
332 , m_setupFillCallback(fill
)
333 , m_setupStrokeCallback(stroke
)
339 virtual void operator()(SVGInlineTextBox
* textBox
, int startOffset
, const TransformationMatrix
& chunkCtm
,
340 const Vector
<SVGChar
>::iterator
& start
, const Vector
<SVGChar
>::iterator
& end
)
342 (*m_object
.*m_walkerCallback
)(textBox
, startOffset
, chunkCtm
, start
, end
);
345 // Followings methods are only used for painting text chunks
346 virtual void start(InlineBox
* box
)
349 (*m_object
.*m_startCallback
)(box
);
351 ASSERT_NOT_REACHED();
354 virtual void end(InlineBox
* box
)
357 (*m_object
.*m_endCallback
)(box
);
359 ASSERT_NOT_REACHED();
362 virtual bool setupFill(InlineBox
* box
)
364 if (m_setupFillCallback
)
365 return (*m_object
.*m_setupFillCallback
)(box
);
367 ASSERT_NOT_REACHED();
371 virtual bool setupStroke(InlineBox
* box
)
373 if (m_setupStrokeCallback
)
374 return (*m_object
.*m_setupStrokeCallback
)(box
);
376 ASSERT_NOT_REACHED();
381 CallbackClass
* m_object
;
382 SVGTextChunkWalkerCallback m_walkerCallback
;
383 SVGTextChunkStartCallback m_startCallback
;
384 SVGTextChunkEndCallback m_endCallback
;
385 SVGTextChunkSetupFillCallback m_setupFillCallback
;
386 SVGTextChunkSetupStrokeCallback m_setupStrokeCallback
;
389 struct SVGTextChunkLayoutInfo
{
390 SVGTextChunkLayoutInfo(Vector
<SVGTextChunk
>& textChunks
)
391 : assignChunkProperties(true)
392 , handlingTextPath(false)
393 , svgTextChunks(textChunks
)
398 bool assignChunkProperties
: 1;
399 bool handlingTextPath
: 1;
401 Vector
<SVGTextChunk
>& svgTextChunks
;
402 Vector
<SVGChar
>::iterator it
;
407 struct SVGTextDecorationInfo
{
408 // ETextDecoration is meant to be used here
409 HashMap
<int, RenderObject
*> fillServerMap
;
410 HashMap
<int, RenderObject
*> strokeServerMap
;
413 } // namespace WebCore
415 #endif // ENABLE(SVG)
416 #endif // SVGCharacterLayoutInfo_h