Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: Source/core/layout/svg/SVGTextChunkBuilder.cpp

Issue 1155293005: Perform SVG text chunk processing on-the-fly (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 2 * Copyright (C) Research In Motion Limited 2010. 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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details. 12 * Library General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU Library General Public License 14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to 15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA. 17 * Boston, MA 02110-1301, USA.
18 */ 18 */
19 19
20 #include "config.h" 20 #include "config.h"
21 #include "core/layout/svg/SVGTextChunkBuilder.h" 21 #include "core/layout/svg/SVGTextChunkBuilder.h"
22 22
23 #include "core/layout/svg/LayoutSVGInlineText.h" 23 #include "core/layout/svg/LayoutSVGInlineText.h"
24 #include "core/layout/svg/SVGTextChunk.h"
24 #include "core/layout/svg/line/SVGInlineTextBox.h" 25 #include "core/layout/svg/line/SVGInlineTextBox.h"
25 #include "core/svg/SVGLengthContext.h" 26 #include "core/svg/SVGLengthContext.h"
26 #include "core/svg/SVGTextContentElement.h" 27 #include "core/svg/SVGTextContentElement.h"
27 28
28 namespace blink { 29 namespace blink {
29 30
30 SVGTextChunkBuilder::SVGTextChunkBuilder() 31 SVGTextChunkBuilder::SVGTextChunkBuilder()
31 { 32 {
32 } 33 }
33 34
34 void SVGTextChunkBuilder::buildTextChunks(Vector<SVGInlineTextBox*>& lineLayoutB oxes) 35 void SVGTextChunkBuilder::processTextChunks(const Vector<SVGInlineTextBox*>& lin eLayoutBoxes)
35 { 36 {
36 if (lineLayoutBoxes.isEmpty()) 37 if (lineLayoutBoxes.isEmpty())
37 return; 38 return;
38 39
39 bool foundStart = false; 40 bool foundStart = false;
40 unsigned lastChunkStartPosition = 0; 41 unsigned lastChunkStartPosition = 0;
41 unsigned boxPosition = 0; 42 unsigned boxPosition = 0;
42 unsigned boxCount = lineLayoutBoxes.size(); 43 unsigned boxCount = lineLayoutBoxes.size();
43 for (; boxPosition < boxCount; ++boxPosition) { 44 for (; boxPosition < boxCount; ++boxPosition) {
44 SVGInlineTextBox* textBox = lineLayoutBoxes[boxPosition]; 45 SVGInlineTextBox* textBox = lineLayoutBoxes[boxPosition];
45 if (!textBox->startsNewTextChunk()) 46 if (!textBox->startsNewTextChunk())
46 continue; 47 continue;
47 48
48 if (!foundStart) { 49 if (!foundStart) {
49 lastChunkStartPosition = boxPosition;
50 foundStart = true; 50 foundStart = true;
51 } else { 51 } else {
52 ASSERT(boxPosition > lastChunkStartPosition); 52 ASSERT(boxPosition > lastChunkStartPosition);
53 addTextChunk(lineLayoutBoxes, lastChunkStartPosition, boxPosition - lastChunkStartPosition); 53 handleTextChunk(lineLayoutBoxes, lastChunkStartPosition, boxPosition );
54 lastChunkStartPosition = boxPosition;
55 } 54 }
55 lastChunkStartPosition = boxPosition;
56 } 56 }
57 57
58 if (!foundStart) 58 if (!foundStart)
59 return; 59 return;
60 60
61 if (boxPosition - lastChunkStartPosition > 0) 61 if (boxPosition - lastChunkStartPosition > 0)
62 addTextChunk(lineLayoutBoxes, lastChunkStartPosition, boxPosition - last ChunkStartPosition); 62 handleTextChunk(lineLayoutBoxes, lastChunkStartPosition, boxPosition);
63 } 63 }
64 64
65 void SVGTextChunkBuilder::layoutTextChunks(Vector<SVGInlineTextBox*>& lineLayout Boxes) 65 SVGTextPathChunkBuilder::SVGTextPathChunkBuilder()
66 : SVGTextChunkBuilder()
67 , m_totalLength(0)
68 , m_totalCharacters(0)
69 , m_totalTextAnchorShift(0)
66 { 70 {
67 buildTextChunks(lineLayoutBoxes);
68 if (m_textChunks.isEmpty())
69 return;
70
71 unsigned chunkCount = m_textChunks.size();
72 for (unsigned i = 0; i < chunkCount; ++i)
73 processTextChunk(m_textChunks[i]);
74
75 m_textChunks.clear();
76 } 71 }
77 72
78 void SVGTextChunkBuilder::addTextChunk(Vector<SVGInlineTextBox*>& lineLayoutBoxe s, unsigned boxStart, unsigned boxCount) 73 static SVGTextChunk createTextChunk(const Vector<SVGInlineTextBox*>& lineLayoutB oxes, unsigned boxStart, unsigned boxCount)
f(malita) 2015/05/27 15:19:13 Can we fold this into the SVGTextChunk ctor and ju
79 { 74 {
80 SVGInlineTextBox* textBox = lineLayoutBoxes[boxStart]; 75 SVGInlineTextBox* textBox = lineLayoutBoxes[boxStart];
81 ASSERT(textBox); 76 ASSERT(textBox);
82 77
83 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(textBox->layou tObject()); 78 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(textBox->layou tObject());
84 79
85 const ComputedStyle& style = toLayoutSVGInlineText(textBox->layoutObject()). styleRef(); 80 const ComputedStyle& style = toLayoutSVGInlineText(textBox->layoutObject()). styleRef();
86 81
87 const SVGComputedStyle& svgStyle = style.svgStyle(); 82 const SVGComputedStyle& svgStyle = style.svgStyle();
88 83
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 break; 124 break;
130 }; 125 };
131 } 126 }
132 127
133 SVGTextChunk chunk(chunkStyle, desiredTextLength); 128 SVGTextChunk chunk(chunkStyle, desiredTextLength);
134 129
135 Vector<SVGInlineTextBox*>& boxes = chunk.boxes(); 130 Vector<SVGInlineTextBox*>& boxes = chunk.boxes();
136 for (unsigned i = boxStart; i < boxStart + boxCount; ++i) 131 for (unsigned i = boxStart; i < boxStart + boxCount; ++i)
137 boxes.append(lineLayoutBoxes[i]); 132 boxes.append(lineLayoutBoxes[i]);
138 133
139 m_textChunks.append(chunk); 134 return chunk;
135 }
136
137 void SVGTextPathChunkBuilder::handleTextChunk(const Vector<SVGInlineTextBox*>& b oxes, unsigned boxStart, unsigned boxEnd)
138 {
139 SVGTextChunk chunk = createTextChunk(boxes, boxStart, boxEnd - boxStart);
140
141 float length = 0;
142 unsigned characters = 0;
143 chunk.calculateLength(length, characters);
144
145 // Handle text-anchor as additional start offset for text paths.
146 m_totalTextAnchorShift += chunk.calculateTextAnchorShift(length);
147
148 m_totalLength += length;
149 m_totalCharacters += characters;
140 } 150 }
141 151
142 static void buildSpacingAndGlyphsTransform(bool isVerticalText, float scale, con st SVGTextFragment& fragment, AffineTransform& spacingAndGlyphsTransform) 152 static void buildSpacingAndGlyphsTransform(bool isVerticalText, float scale, con st SVGTextFragment& fragment, AffineTransform& spacingAndGlyphsTransform)
143 { 153 {
144 spacingAndGlyphsTransform.translate(fragment.x, fragment.y); 154 spacingAndGlyphsTransform.translate(fragment.x, fragment.y);
145 155
146 if (isVerticalText) 156 if (isVerticalText)
147 spacingAndGlyphsTransform.scaleNonUniform(1, scale); 157 spacingAndGlyphsTransform.scaleNonUniform(1, scale);
148 else 158 else
149 spacingAndGlyphsTransform.scaleNonUniform(scale, 1); 159 spacingAndGlyphsTransform.scaleNonUniform(scale, 1);
150 160
151 spacingAndGlyphsTransform.translate(-fragment.x, -fragment.y); 161 spacingAndGlyphsTransform.translate(-fragment.x, -fragment.y);
152 } 162 }
153 163
154 void SVGTextChunkBuilder::processTextChunk(const SVGTextChunk& chunk) 164 void SVGTextChunkBuilder::handleTextChunk(const Vector<SVGInlineTextBox*>& lineB oxes, unsigned boxStart, unsigned boxEnd)
155 { 165 {
166 SVGTextChunk chunk = createTextChunk(lineBoxes, boxStart, boxEnd - boxStart) ;
167
156 bool processTextLength = chunk.hasDesiredTextLength(); 168 bool processTextLength = chunk.hasDesiredTextLength();
157 bool processTextAnchor = chunk.hasTextAnchor(); 169 bool processTextAnchor = chunk.hasTextAnchor();
158 if (!processTextAnchor && !processTextLength) 170 if (!processTextAnchor && !processTextLength)
159 return; 171 return;
160 172
161 const Vector<SVGInlineTextBox*>& boxes = chunk.boxes(); 173 const Vector<SVGInlineTextBox*>& boxes = chunk.boxes();
162 unsigned boxCount = boxes.size(); 174 unsigned boxCount = boxes.size();
163 if (!boxCount) 175 if (!boxCount)
164 return; 176 return;
165 177
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 continue; 268 continue;
257 269
258 for (SVGTextFragment& fragment : textBox->textFragments()) { 270 for (SVGTextFragment& fragment : textBox->textFragments()) {
259 ASSERT(fragment.lengthAdjustTransform.isIdentity()); 271 ASSERT(fragment.lengthAdjustTransform.isIdentity());
260 fragment.lengthAdjustTransform = textBoxTransformation; 272 fragment.lengthAdjustTransform = textBoxTransformation;
261 } 273 }
262 } 274 }
263 } 275 }
264 276
265 } 277 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698