OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. |
3 * | 3 * |
4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
8 * | 8 * |
9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 170 |
171 Path path = textPath->layoutPath(); | 171 Path path = textPath->layoutPath(); |
172 if (path.isEmpty()) | 172 if (path.isEmpty()) |
173 return; | 173 return; |
174 m_textPathCalculator = new Path::PositionCalculator(path); | 174 m_textPathCalculator = new Path::PositionCalculator(path); |
175 m_textPathStartOffset = textPath->startOffset(); | 175 m_textPathStartOffset = textPath->startOffset(); |
176 m_textPathLength = path.length(); | 176 m_textPathLength = path.length(); |
177 if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1) | 177 if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1) |
178 m_textPathStartOffset *= m_textPathLength; | 178 m_textPathStartOffset *= m_textPathLength; |
179 | 179 |
180 float totalLength = 0; | 180 SVGTextPathChunkBuilder textPathChunkLayoutBuilder; |
181 unsigned totalCharacters = 0; | 181 textPathChunkLayoutBuilder.processTextChunks(lineLayout.m_lineLayoutBoxes); |
182 | 182 |
183 SVGTextChunkBuilder textPathChunkLayoutBuilder; | 183 m_textPathStartOffset += textPathChunkLayoutBuilder.totalTextAnchorShift(); |
184 textPathChunkLayoutBuilder.buildTextChunks(lineLayout.m_lineLayoutBoxes); | |
185 const Vector<SVGTextChunk>& textChunks = textPathChunkLayoutBuilder.textChun
ks(); | |
186 | |
187 unsigned size = textChunks.size(); | |
188 for (unsigned i = 0; i < size; ++i) { | |
189 const SVGTextChunk& chunk = textChunks.at(i); | |
190 | |
191 float length = 0; | |
192 unsigned characters = 0; | |
193 chunk.calculateLength(length, characters); | |
194 | |
195 // Handle text-anchor as additional start offset for text paths. | |
196 m_textPathStartOffset += chunk.calculateTextAnchorShift(length); | |
197 | |
198 totalLength += length; | |
199 totalCharacters += characters; | |
200 } | |
201 | |
202 m_textPathCurrentOffset = m_textPathStartOffset; | 184 m_textPathCurrentOffset = m_textPathStartOffset; |
203 | 185 |
204 // Eventually handle textLength adjustments. | 186 // Eventually handle textLength adjustments. |
205 SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown; | 187 SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown; |
206 float desiredTextLength = 0; | 188 float desiredTextLength = 0; |
207 | 189 |
208 if (SVGTextContentElement* textContentElement = SVGTextContentElement::eleme
ntFromLayoutObject(textPath)) { | 190 if (SVGTextContentElement* textContentElement = SVGTextContentElement::eleme
ntFromLayoutObject(textPath)) { |
209 SVGLengthContext lengthContext(textContentElement); | 191 SVGLengthContext lengthContext(textContentElement); |
210 lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumV
alue(); | 192 lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumV
alue(); |
211 if (textContentElement->textLengthIsSpecifiedByUser()) | 193 if (textContentElement->textLengthIsSpecifiedByUser()) |
212 desiredTextLength = textContentElement->textLength()->currentValue()
->value(lengthContext); | 194 desiredTextLength = textContentElement->textLength()->currentValue()
->value(lengthContext); |
213 else | 195 else |
214 desiredTextLength = 0; | 196 desiredTextLength = 0; |
215 } | 197 } |
216 | 198 |
217 if (!desiredTextLength) | 199 if (!desiredTextLength) |
218 return; | 200 return; |
219 | 201 |
| 202 float totalLength = textPathChunkLayoutBuilder.totalLength(); |
220 if (lengthAdjust == SVGLengthAdjustSpacing) | 203 if (lengthAdjust == SVGLengthAdjustSpacing) |
221 m_textPathSpacing = (desiredTextLength - totalLength) / totalCharacters; | 204 m_textPathSpacing = (desiredTextLength - totalLength) / textPathChunkLay
outBuilder.totalCharacters(); |
222 else | 205 else |
223 m_textPathScaling = desiredTextLength / totalLength; | 206 m_textPathScaling = desiredTextLength / totalLength; |
224 } | 207 } |
225 | 208 |
226 void SVGTextLayoutEngine::endTextPathLayout() | 209 void SVGTextLayoutEngine::endTextPathLayout() |
227 { | 210 { |
228 m_inPathLayout = false; | 211 m_inPathLayout = false; |
229 delete m_textPathCalculator; | 212 delete m_textPathCalculator; |
230 m_textPathCalculator = 0; | 213 m_textPathCalculator = 0; |
231 m_textPathLength = 0; | 214 m_textPathLength = 0; |
(...skipping 24 matching lines...) Expand all Loading... |
256 } | 239 } |
257 | 240 |
258 m_lineLayoutBoxes.append(textBox); | 241 m_lineLayoutBoxes.append(textBox); |
259 } | 242 } |
260 | 243 |
261 void SVGTextLayoutEngine::finishLayout() | 244 void SVGTextLayoutEngine::finishLayout() |
262 { | 245 { |
263 // After all text fragments are stored in their correpsonding SVGInlineTextB
oxes, we can layout individual text chunks. | 246 // After all text fragments are stored in their correpsonding SVGInlineTextB
oxes, we can layout individual text chunks. |
264 // Chunk layouting is only performed for line layout boxes, not for path lay
out, where it has already been done. | 247 // Chunk layouting is only performed for line layout boxes, not for path lay
out, where it has already been done. |
265 SVGTextChunkBuilder chunkLayoutBuilder; | 248 SVGTextChunkBuilder chunkLayoutBuilder; |
266 chunkLayoutBuilder.layoutTextChunks(m_lineLayoutBoxes); | 249 chunkLayoutBuilder.processTextChunks(m_lineLayoutBoxes); |
267 | 250 |
268 // Finalize transform matrices, after the chunk layout corrections have been
applied, and all fragment x/y positions are finalized. | 251 // Finalize transform matrices, after the chunk layout corrections have been
applied, and all fragment x/y positions are finalized. |
269 if (!m_lineLayoutBoxes.isEmpty()) { | 252 if (!m_lineLayoutBoxes.isEmpty()) { |
270 chunkLayoutBuilder.finalizeTransformMatrices(m_lineLayoutBoxes); | 253 chunkLayoutBuilder.finalizeTransformMatrices(m_lineLayoutBoxes); |
271 m_lineLayoutBoxes.clear(); | 254 m_lineLayoutBoxes.clear(); |
272 } | 255 } |
273 | 256 |
274 if (!m_pathLayoutBoxes.isEmpty()) { | 257 if (!m_pathLayoutBoxes.isEmpty()) { |
275 chunkLayoutBuilder.finalizeTransformMatrices(m_pathLayoutBoxes); | 258 chunkLayoutBuilder.finalizeTransformMatrices(m_pathLayoutBoxes); |
276 m_pathLayoutBoxes.clear(); | 259 m_pathLayoutBoxes.clear(); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 } | 560 } |
578 | 561 |
579 if (!didStartTextFragment) | 562 if (!didStartTextFragment) |
580 return; | 563 return; |
581 | 564 |
582 // Close last open fragment, if needed. | 565 // Close last open fragment, if needed. |
583 recordTextFragment(textBox, visualMetricsValues); | 566 recordTextFragment(textBox, visualMetricsValues); |
584 } | 567 } |
585 | 568 |
586 } | 569 } |
OLD | NEW |