OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> | 2 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> |
3 * Copyright (C) 2006 Apple Computer Inc. | 3 * Copyright (C) 2006 Apple Computer Inc. |
4 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> | 4 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> |
5 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 5 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
6 * Copyright (C) 2011 Torch Mobile (Beijing) CO. Ltd. All rights reserved. | 6 * Copyright (C) 2011 Torch Mobile (Beijing) CO. Ltd. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "core/rendering/svg/SVGInlineTextBox.h" | 31 #include "core/rendering/svg/SVGInlineTextBox.h" |
32 #include "core/rendering/svg/SVGRenderingContext.h" | 32 #include "core/rendering/svg/SVGRenderingContext.h" |
33 | 33 |
34 namespace WebCore { | 34 namespace WebCore { |
35 | 35 |
36 void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
t, LayoutUnit, LayoutUnit) | 36 void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
t, LayoutUnit, LayoutUnit) |
37 { | 37 { |
38 ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPh
aseSelection); | 38 ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPh
aseSelection); |
39 ASSERT(!paintInfo.context->paintingDisabled()); | 39 ASSERT(!paintInfo.context->paintingDisabled()); |
40 | 40 |
41 RenderObject* boxRenderer = renderer(); | 41 bool isPrinting = renderer().document().printing(); |
42 ASSERT(boxRenderer); | |
43 | |
44 bool isPrinting = renderer()->document().printing(); | |
45 bool hasSelection = !isPrinting && selectionState() != RenderObject::Selecti
onNone; | 42 bool hasSelection = !isPrinting && selectionState() != RenderObject::Selecti
onNone; |
46 | 43 |
47 PaintInfo childPaintInfo(paintInfo); | 44 PaintInfo childPaintInfo(paintInfo); |
48 if (hasSelection) { | 45 if (hasSelection) { |
49 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()
) { | 46 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()
) { |
50 if (child->isSVGInlineTextBox()) | 47 if (child->isSVGInlineTextBox()) |
51 toSVGInlineTextBox(child)->paintSelectionBackground(childPaintIn
fo); | 48 toSVGInlineTextBox(child)->paintSelectionBackground(childPaintIn
fo); |
52 else if (child->isSVGInlineFlowBox()) | 49 else if (child->isSVGInlineFlowBox()) |
53 toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintIn
fo); | 50 toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintIn
fo); |
54 } | 51 } |
55 } | 52 } |
56 | 53 |
57 SVGRenderingContext renderingContext(boxRenderer, paintInfo, SVGRenderingCon
text::SaveGraphicsContext); | 54 SVGRenderingContext renderingContext(&renderer(), paintInfo, SVGRenderingCon
text::SaveGraphicsContext); |
58 if (renderingContext.isRenderingPrepared()) { | 55 if (renderingContext.isRenderingPrepared()) { |
59 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()
) | 56 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()
) |
60 child->paint(paintInfo, paintOffset, 0, 0); | 57 child->paint(paintInfo, paintOffset, 0, 0); |
61 } | 58 } |
62 } | 59 } |
63 | 60 |
64 void SVGRootInlineBox::markDirty(bool dirty) | 61 void SVGRootInlineBox::markDirty(bool dirty) |
65 { | 62 { |
66 if (dirty) | 63 if (dirty) |
67 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()
) | 64 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()
) |
68 child->markDirty(true); | 65 child->markDirty(true); |
69 RootInlineBox::markDirty(dirty); | 66 RootInlineBox::markDirty(dirty); |
70 } | 67 } |
71 | 68 |
72 void SVGRootInlineBox::computePerCharacterLayoutInformation() | 69 void SVGRootInlineBox::computePerCharacterLayoutInformation() |
73 { | 70 { |
74 RenderSVGText* textRoot = toRenderSVGText(block()); | 71 RenderSVGText& textRoot = toRenderSVGText(block()); |
75 ASSERT(textRoot); | |
76 | 72 |
77 Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot->layoutAttribu
tes(); | 73 Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot.layoutAttribut
es(); |
78 if (layoutAttributes.isEmpty()) | 74 if (layoutAttributes.isEmpty()) |
79 return; | 75 return; |
80 | 76 |
81 if (textRoot->needsReordering()) | 77 if (textRoot.needsReordering()) |
82 reorderValueLists(layoutAttributes); | 78 reorderValueLists(layoutAttributes); |
83 | 79 |
84 // Perform SVG text layout phase two (see SVGTextLayoutEngine for details). | 80 // Perform SVG text layout phase two (see SVGTextLayoutEngine for details). |
85 SVGTextLayoutEngine characterLayout(layoutAttributes); | 81 SVGTextLayoutEngine characterLayout(layoutAttributes); |
86 layoutCharactersInTextBoxes(this, characterLayout); | 82 layoutCharactersInTextBoxes(this, characterLayout); |
87 | 83 |
88 // Perform SVG text layout phase three (see SVGTextChunkBuilder for details)
. | 84 // Perform SVG text layout phase three (see SVGTextChunkBuilder for details)
. |
89 characterLayout.finishLayout(); | 85 characterLayout.finishLayout(); |
90 | 86 |
91 // Perform SVG text layout phase four | 87 // Perform SVG text layout phase four |
92 // Position & resize all SVGInlineText/FlowBoxes in the inline box tree, res
ize the root box as well as the RenderSVGText parent block. | 88 // Position & resize all SVGInlineText/FlowBoxes in the inline box tree, res
ize the root box as well as the RenderSVGText parent block. |
93 FloatRect childRect; | 89 FloatRect childRect; |
94 layoutChildBoxes(this, &childRect); | 90 layoutChildBoxes(this, &childRect); |
95 layoutRootBox(childRect); | 91 layoutRootBox(childRect); |
96 } | 92 } |
97 | 93 |
98 void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGText
LayoutEngine& characterLayout) | 94 void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGText
LayoutEngine& characterLayout) |
99 { | 95 { |
100 for (InlineBox* child = start->firstChild(); child; child = child->nextOnLin
e()) { | 96 for (InlineBox* child = start->firstChild(); child; child = child->nextOnLin
e()) { |
101 if (child->isSVGInlineTextBox()) { | 97 if (child->isSVGInlineTextBox()) { |
102 ASSERT(child->renderer()); | 98 ASSERT(child->renderer().isSVGInlineText()); |
103 ASSERT(child->renderer()->isSVGInlineText()); | |
104 characterLayout.layoutInlineTextBox(toSVGInlineTextBox(child)); | 99 characterLayout.layoutInlineTextBox(toSVGInlineTextBox(child)); |
105 } else { | 100 } else { |
106 // Skip generated content. | 101 // Skip generated content. |
107 Node* node = child->renderer()->node(); | 102 Node* node = child->renderer().node(); |
108 if (!node) | 103 if (!node) |
109 continue; | 104 continue; |
110 | 105 |
111 SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child); | 106 SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child); |
112 bool isTextPath = node->hasTagName(SVGNames::textPathTag); | 107 bool isTextPath = node->hasTagName(SVGNames::textPathTag); |
113 if (isTextPath) { | 108 if (isTextPath) { |
114 // Build text chunks for all <textPath> children, using the line
layout algorithm. | 109 // Build text chunks for all <textPath> children, using the line
layout algorithm. |
115 // This is needeed as text-anchor is just an additional startOff
set for text paths. | 110 // This is needeed as text-anchor is just an additional startOff
set for text paths. |
116 SVGTextLayoutEngine lineLayout(characterLayout.layoutAttributes(
)); | 111 SVGTextLayoutEngine lineLayout(characterLayout.layoutAttributes(
)); |
117 layoutCharactersInTextBoxes(flowBox, lineLayout); | 112 layoutCharactersInTextBoxes(flowBox, lineLayout); |
118 | 113 |
119 characterLayout.beginTextPathLayout(child->renderer(), lineLayou
t); | 114 characterLayout.beginTextPathLayout(&child->renderer(), lineLayo
ut); |
120 } | 115 } |
121 | 116 |
122 layoutCharactersInTextBoxes(flowBox, characterLayout); | 117 layoutCharactersInTextBoxes(flowBox, characterLayout); |
123 | 118 |
124 if (isTextPath) | 119 if (isTextPath) |
125 characterLayout.endTextPathLayout(); | 120 characterLayout.endTextPathLayout(); |
126 } | 121 } |
127 } | 122 } |
128 } | 123 } |
129 | 124 |
130 void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
ct) | 125 void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
ct) |
131 { | 126 { |
132 for (InlineBox* child = start->firstChild(); child; child = child->nextOnLin
e()) { | 127 for (InlineBox* child = start->firstChild(); child; child = child->nextOnLin
e()) { |
133 FloatRect boxRect; | 128 FloatRect boxRect; |
134 if (child->isSVGInlineTextBox()) { | 129 if (child->isSVGInlineTextBox()) { |
135 ASSERT(child->renderer()); | 130 ASSERT(child->renderer().isSVGInlineText()); |
136 ASSERT(child->renderer()->isSVGInlineText()); | |
137 | 131 |
138 SVGInlineTextBox* textBox = toSVGInlineTextBox(child); | 132 SVGInlineTextBox* textBox = toSVGInlineTextBox(child); |
139 boxRect = textBox->calculateBoundaries(); | 133 boxRect = textBox->calculateBoundaries(); |
140 textBox->setX(boxRect.x()); | 134 textBox->setX(boxRect.x()); |
141 textBox->setY(boxRect.y()); | 135 textBox->setY(boxRect.y()); |
142 textBox->setLogicalWidth(boxRect.width()); | 136 textBox->setLogicalWidth(boxRect.width()); |
143 textBox->setLogicalHeight(boxRect.height()); | 137 textBox->setLogicalHeight(boxRect.height()); |
144 } else { | 138 } else { |
145 // Skip generated content. | 139 // Skip generated content. |
146 if (!child->renderer()->node()) | 140 if (!child->renderer().node()) |
147 continue; | 141 continue; |
148 | 142 |
149 SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child); | 143 SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child); |
150 layoutChildBoxes(flowBox); | 144 layoutChildBoxes(flowBox); |
151 | 145 |
152 boxRect = flowBox->calculateBoundaries(); | 146 boxRect = flowBox->calculateBoundaries(); |
153 flowBox->setX(boxRect.x()); | 147 flowBox->setX(boxRect.x()); |
154 flowBox->setY(boxRect.y()); | 148 flowBox->setY(boxRect.y()); |
155 flowBox->setLogicalWidth(boxRect.width()); | 149 flowBox->setLogicalWidth(boxRect.width()); |
156 flowBox->setLogicalHeight(boxRect.height()); | 150 flowBox->setLogicalHeight(boxRect.height()); |
157 } | 151 } |
158 if (childRect) | 152 if (childRect) |
159 childRect->unite(boxRect); | 153 childRect->unite(boxRect); |
160 } | 154 } |
161 } | 155 } |
162 | 156 |
163 void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect) | 157 void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect) |
164 { | 158 { |
165 RenderBlockFlow* parentBlock = block(); | 159 RenderBlockFlow& parentBlock = block(); |
166 ASSERT(parentBlock); | |
167 | 160 |
168 // Finally, assign the root block position, now that all content is laid out
. | 161 // Finally, assign the root block position, now that all content is laid out
. |
169 LayoutRect boundingRect = enclosingLayoutRect(childRect); | 162 LayoutRect boundingRect = enclosingLayoutRect(childRect); |
170 parentBlock->setLocation(boundingRect.location()); | 163 parentBlock.setLocation(boundingRect.location()); |
171 parentBlock->setSize(boundingRect.size()); | 164 parentBlock.setSize(boundingRect.size()); |
172 | 165 |
173 // Position all children relative to the parent block. | 166 // Position all children relative to the parent block. |
174 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) { | 167 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) { |
175 // Skip generated content. | 168 // Skip generated content. |
176 if (!child->renderer()->node()) | 169 if (!child->renderer().node()) |
177 continue; | 170 continue; |
178 child->adjustPosition(-childRect.x(), -childRect.y()); | 171 child->adjustPosition(-childRect.x(), -childRect.y()); |
179 } | 172 } |
180 | 173 |
181 // Position ourselves. | 174 // Position ourselves. |
182 setX(0); | 175 setX(0); |
183 setY(0); | 176 setY(0); |
184 setLogicalWidth(childRect.width()); | 177 setLogicalWidth(childRect.width()); |
185 setLogicalHeight(childRect.height()); | 178 setLogicalHeight(childRect.height()); |
186 setLineTopBottomPositions(0, boundingRect.height(), 0, boundingRect.height()
); | 179 setLineTopBottomPositions(0, boundingRect.height(), 0, boundingRect.height()
); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 *last = temp; | 254 *last = temp; |
262 ++first; | 255 ++first; |
263 continue; | 256 continue; |
264 } | 257 } |
265 | 258 |
266 SVGInlineTextBox* firstTextBox = toSVGInlineTextBox(*first); | 259 SVGInlineTextBox* firstTextBox = toSVGInlineTextBox(*first); |
267 SVGInlineTextBox* lastTextBox = toSVGInlineTextBox(*last); | 260 SVGInlineTextBox* lastTextBox = toSVGInlineTextBox(*last); |
268 | 261 |
269 // Reordering is only necessary for BiDi text that is _absolutely_ posit
ioned. | 262 // Reordering is only necessary for BiDi text that is _absolutely_ posit
ioned. |
270 if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len(
)) { | 263 if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len(
)) { |
271 RenderSVGInlineText* firstContext = toRenderSVGInlineText(firstTextB
ox->textRenderer()); | 264 RenderSVGInlineText& firstContext = toRenderSVGInlineText(firstTextB
ox->textRenderer()); |
272 RenderSVGInlineText* lastContext = toRenderSVGInlineText(lastTextBox
->textRenderer()); | 265 RenderSVGInlineText& lastContext = toRenderSVGInlineText(lastTextBox
->textRenderer()); |
273 | 266 |
274 SVGTextLayoutAttributes* firstAttributes = 0; | 267 SVGTextLayoutAttributes* firstAttributes = 0; |
275 SVGTextLayoutAttributes* lastAttributes = 0; | 268 SVGTextLayoutAttributes* lastAttributes = 0; |
276 findFirstAndLastAttributesInVector(attributes, firstContext, lastCon
text, firstAttributes, lastAttributes); | 269 findFirstAndLastAttributesInVector(attributes, &firstContext, &lastC
ontext, firstAttributes, lastAttributes); |
277 swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTe
xtBox->start(), lastTextBox->start()); | 270 swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTe
xtBox->start(), lastTextBox->start()); |
278 } | 271 } |
279 | 272 |
280 InlineBox* temp = *first; | 273 InlineBox* temp = *first; |
281 *first = *last; | 274 *first = *last; |
282 *last = temp; | 275 *last = temp; |
283 | 276 |
284 ++first; | 277 ++first; |
285 } | 278 } |
286 } | 279 } |
287 | 280 |
288 void SVGRootInlineBox::reorderValueLists(Vector<SVGTextLayoutAttributes*>& attri
butes) | 281 void SVGRootInlineBox::reorderValueLists(Vector<SVGTextLayoutAttributes*>& attri
butes) |
289 { | 282 { |
290 Vector<InlineBox*> leafBoxesInLogicalOrder; | 283 Vector<InlineBox*> leafBoxesInLogicalOrder; |
291 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder, reverseInlineBoxRang
eAndValueListsIfNeeded, &attributes); | 284 collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder, reverseInlineBoxRang
eAndValueListsIfNeeded, &attributes); |
292 } | 285 } |
293 | 286 |
294 } // namespace WebCore | 287 } // namespace WebCore |
OLD | NEW |