]> git.saurik.com Git - iphone-api.git/blob - WebCore/SVGCharacterLayoutInfo.h
Adding the WebCore headers (for Cydget).
[iphone-api.git] / WebCore / SVGCharacterLayoutInfo.h
1 /*
2 * This file is part of the WebKit project.
3 *
4 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
5 *
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.
10 *
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.
15 *
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.
20 *
21 */
22
23 #ifndef SVGCharacterLayoutInfo_h
24 #define SVGCharacterLayoutInfo_h
25
26 #if ENABLE(SVG)
27 #include <wtf/Assertions.h>
28 #include <wtf/HashMap.h>
29 #include <wtf/HashSet.h>
30 #include <wtf/Vector.h>
31
32 #include "TransformationMatrix.h"
33 #include <wtf/RefCounted.h>
34 #include "SVGRenderStyle.h"
35 #include "SVGTextContentElement.h"
36
37 namespace WebCore {
38
39 class InlineBox;
40 class InlineFlowBox;
41 class SVGInlineTextBox;
42 class SVGLengthList;
43 class SVGNumberList;
44 class SVGTextPositioningElement;
45
46 template<class Type>
47 class PositionedVector : public Vector<Type>
48 {
49 public:
50 PositionedVector<Type>()
51 : m_position(0)
52 {
53 }
54
55 unsigned position() const
56 {
57 return m_position;
58 }
59
60 void advance(unsigned position)
61 {
62 m_position += position;
63 ASSERT(m_position < Vector<Type>::size());
64 }
65
66 Type valueAtCurrentPosition() const
67 {
68 ASSERT(m_position < Vector<Type>::size());
69 return Vector<Type>::at(m_position);
70 }
71
72 private:
73 unsigned m_position;
74 };
75
76 class PositionedFloatVector : public PositionedVector<float> { };
77 struct SVGChar;
78
79 struct SVGCharacterLayoutInfo {
80 SVGCharacterLayoutInfo(Vector<SVGChar>&);
81
82 enum StackType { XStack, YStack, DxStack, DyStack, AngleStack, BaselineShiftStack };
83
84 bool xValueAvailable() const;
85 bool yValueAvailable() const;
86 bool dxValueAvailable() const;
87 bool dyValueAvailable() const;
88 bool angleValueAvailable() const;
89 bool baselineShiftValueAvailable() const;
90
91 float xValueNext() const;
92 float yValueNext() const;
93 float dxValueNext() const;
94 float dyValueNext() const;
95 float angleValueNext() const;
96 float baselineShiftValueNext() const;
97
98 void processedChunk(float savedShiftX, float savedShiftY);
99 void processedSingleCharacter();
100
101 bool nextPathLayoutPointAndAngle(float glyphAdvance, float extraAdvance, float newOffset);
102
103 // Used for text-on-path.
104 void addLayoutInformation(InlineFlowBox*, float textAnchorOffset = 0.0f);
105
106 bool inPathLayout() const;
107 void setInPathLayout(bool value);
108
109 // Used for anything else.
110 void addLayoutInformation(SVGTextPositioningElement*);
111
112 // Global position
113 float curx;
114 float cury;
115
116 // Global rotation
117 float angle;
118
119 // Accumulated dx/dy values
120 float dx;
121 float dy;
122
123 // Accumulated baseline-shift values
124 float shiftx;
125 float shifty;
126
127 // Path specific advance values to handle lengthAdjust
128 float pathExtraAdvance;
129 float pathTextLength;
130 float pathChunkLength;
131
132 // Result vector
133 Vector<SVGChar>& svgChars;
134 bool nextDrawnSeperated : 1;
135
136 private:
137 // Used for baseline-shift.
138 void addStackContent(StackType, float);
139
140 // Used for angle.
141 void addStackContent(StackType, SVGNumberList*);
142
143 // Used for x/y/dx/dy.
144 void addStackContent(StackType, SVGLengthList*, const SVGElement*);
145
146 void addStackContent(StackType, const PositionedFloatVector&);
147
148 void xStackWalk();
149 void yStackWalk();
150 void dxStackWalk();
151 void dyStackWalk();
152 void angleStackWalk();
153 void baselineShiftStackWalk();
154
155 private:
156 bool xStackChanged : 1;
157 bool yStackChanged : 1;
158 bool dxStackChanged : 1;
159 bool dyStackChanged : 1;
160 bool angleStackChanged : 1;
161 bool baselineShiftStackChanged : 1;
162
163 // text on path layout
164 bool pathLayout : 1;
165 float currentOffset;
166 float startOffset;
167 float layoutPathLength;
168 Path layoutPath;
169
170 Vector<PositionedFloatVector> xStack;
171 Vector<PositionedFloatVector> yStack;
172 Vector<PositionedFloatVector> dxStack;
173 Vector<PositionedFloatVector> dyStack;
174 Vector<PositionedFloatVector> angleStack;
175 Vector<float> baselineShiftStack;
176 };
177
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); }
181
182 float xScale;
183 float yScale;
184
185 float xShift;
186 float yShift;
187
188 float orientationAngle;
189
190 bool hidden : 1;
191
192 private:
193 SVGCharOnPath()
194 : xScale(1.0f)
195 , yScale(1.0f)
196 , xShift(0.0f)
197 , yShift(0.0f)
198 , orientationAngle(0.0f)
199 , hidden(false)
200 {
201 }
202 };
203
204 struct SVGChar {
205 SVGChar()
206 : x(0.0f)
207 , y(0.0f)
208 , angle(0.0f)
209 , orientationShiftX(0.0f)
210 , orientationShiftY(0.0f)
211 , pathData()
212 , drawnSeperated(false)
213 , newTextChunk(false)
214 {
215 }
216
217 ~SVGChar()
218 {
219 }
220
221 float x;
222 float y;
223 float angle;
224
225 float orientationShiftX;
226 float orientationShiftY;
227
228 RefPtr<SVGCharOnPath> pathData;
229
230 // Determines wheter this char needs to be drawn seperated
231 bool drawnSeperated : 1;
232
233 // Determines wheter this char starts a new chunk
234 bool newTextChunk : 1;
235
236 // Helper methods
237 bool isHidden() const;
238 TransformationMatrix characterTransform() const;
239 };
240
241 struct SVGInlineBoxCharacterRange {
242 SVGInlineBoxCharacterRange()
243 : startOffset(INT_MIN)
244 , endOffset(INT_MIN)
245 , box(0)
246 {
247 }
248
249 bool isOpen() const { return (startOffset == endOffset) && (endOffset == INT_MIN); }
250 bool isClosed() const { return startOffset != INT_MIN && endOffset != INT_MIN; }
251
252 int startOffset;
253 int endOffset;
254
255 InlineBox* box;
256 };
257
258 // Convenience typedef
259 typedef SVGTextContentElement::SVGLengthAdjustType ELengthAdjust;
260
261 struct SVGTextChunk {
262 SVGTextChunk()
263 : anchor(TA_START)
264 , textLength(0.0f)
265 , lengthAdjust(SVGTextContentElement::LENGTHADJUST_SPACING)
266 , ctm()
267 , isVerticalText(false)
268 , isTextPath(false)
269 , start(0)
270 , end(0)
271 { }
272
273 // text-anchor support
274 ETextAnchor anchor;
275
276 // textLength & lengthAdjust support
277 float textLength;
278 ELengthAdjust lengthAdjust;
279 TransformationMatrix ctm;
280
281 // status flags
282 bool isVerticalText : 1;
283 bool isTextPath : 1;
284
285 // main chunk data
286 Vector<SVGChar>::iterator start;
287 Vector<SVGChar>::iterator end;
288
289 Vector<SVGInlineBoxCharacterRange> boxes;
290 };
291
292 struct SVGTextChunkWalkerBase {
293 virtual ~SVGTextChunkWalkerBase() { }
294
295 virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
296 const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end) = 0;
297
298 // Followings methods are only used for painting text chunks
299 virtual void start(InlineBox*) = 0;
300 virtual void end(InlineBox*) = 0;
301
302 virtual bool setupFill(InlineBox*) = 0;
303 virtual bool setupStroke(InlineBox*) = 0;
304 };
305
306 template<typename CallbackClass>
307 struct SVGTextChunkWalker : public SVGTextChunkWalkerBase {
308 public:
309 typedef void (CallbackClass::*SVGTextChunkWalkerCallback)(SVGInlineTextBox* textBox,
310 int startOffset,
311 const TransformationMatrix& chunkCtm,
312 const Vector<SVGChar>::iterator& start,
313 const Vector<SVGChar>::iterator& end);
314
315 // These callbacks are only used for painting!
316 typedef void (CallbackClass::*SVGTextChunkStartCallback)(InlineBox* box);
317 typedef void (CallbackClass::*SVGTextChunkEndCallback)(InlineBox* box);
318
319 typedef bool (CallbackClass::*SVGTextChunkSetupFillCallback)(InlineBox* box);
320 typedef bool (CallbackClass::*SVGTextChunkSetupStrokeCallback)(InlineBox* box);
321
322 SVGTextChunkWalker(CallbackClass* object,
323 SVGTextChunkWalkerCallback walker,
324 SVGTextChunkStartCallback start = 0,
325 SVGTextChunkEndCallback end = 0,
326 SVGTextChunkSetupFillCallback fill = 0,
327 SVGTextChunkSetupStrokeCallback stroke = 0)
328 : m_object(object)
329 , m_walkerCallback(walker)
330 , m_startCallback(start)
331 , m_endCallback(end)
332 , m_setupFillCallback(fill)
333 , m_setupStrokeCallback(stroke)
334 {
335 ASSERT(object);
336 ASSERT(walker);
337 }
338
339 virtual void operator()(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix& chunkCtm,
340 const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)
341 {
342 (*m_object.*m_walkerCallback)(textBox, startOffset, chunkCtm, start, end);
343 }
344
345 // Followings methods are only used for painting text chunks
346 virtual void start(InlineBox* box)
347 {
348 if (m_startCallback)
349 (*m_object.*m_startCallback)(box);
350 else
351 ASSERT_NOT_REACHED();
352 }
353
354 virtual void end(InlineBox* box)
355 {
356 if (m_endCallback)
357 (*m_object.*m_endCallback)(box);
358 else
359 ASSERT_NOT_REACHED();
360 }
361
362 virtual bool setupFill(InlineBox* box)
363 {
364 if (m_setupFillCallback)
365 return (*m_object.*m_setupFillCallback)(box);
366
367 ASSERT_NOT_REACHED();
368 return false;
369 }
370
371 virtual bool setupStroke(InlineBox* box)
372 {
373 if (m_setupStrokeCallback)
374 return (*m_object.*m_setupStrokeCallback)(box);
375
376 ASSERT_NOT_REACHED();
377 return false;
378 }
379
380 private:
381 CallbackClass* m_object;
382 SVGTextChunkWalkerCallback m_walkerCallback;
383 SVGTextChunkStartCallback m_startCallback;
384 SVGTextChunkEndCallback m_endCallback;
385 SVGTextChunkSetupFillCallback m_setupFillCallback;
386 SVGTextChunkSetupStrokeCallback m_setupStrokeCallback;
387 };
388
389 struct SVGTextChunkLayoutInfo {
390 SVGTextChunkLayoutInfo(Vector<SVGTextChunk>& textChunks)
391 : assignChunkProperties(true)
392 , handlingTextPath(false)
393 , svgTextChunks(textChunks)
394 , it(0)
395 {
396 }
397
398 bool assignChunkProperties : 1;
399 bool handlingTextPath : 1;
400
401 Vector<SVGTextChunk>& svgTextChunks;
402 Vector<SVGChar>::iterator it;
403
404 SVGTextChunk chunk;
405 };
406
407 struct SVGTextDecorationInfo {
408 // ETextDecoration is meant to be used here
409 HashMap<int, RenderObject*> fillServerMap;
410 HashMap<int, RenderObject*> strokeServerMap;
411 };
412
413 } // namespace WebCore
414
415 #endif // ENABLE(SVG)
416 #endif // SVGCharacterLayoutInfo_h