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

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

Issue 1548913002: Store a <scale, bias> tuple for textLength scale adjustment (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Baseline. Created 4 years, 12 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
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 "core/layout/svg/SVGTextChunkBuilder.h" 20 #include "core/layout/svg/SVGTextChunkBuilder.h"
21 21
22 #include "core/layout/api/LineLayoutSVGInlineText.h" 22 #include "core/layout/api/LineLayoutSVGInlineText.h"
23 #include "core/layout/svg/LayoutSVGInlineText.h"
24 #include "core/layout/svg/line/SVGInlineTextBox.h" 23 #include "core/layout/svg/line/SVGInlineTextBox.h"
25 #include "core/svg/SVGLengthContext.h" 24 #include "core/svg/SVGLengthContext.h"
26 #include "core/svg/SVGTextContentElement.h" 25 #include "core/svg/SVGTextContentElement.h"
27 #include "platform/transforms/AffineTransform.h"
28 26
29 namespace blink { 27 namespace blink {
30 28
31 namespace { 29 namespace {
32 30
33 float calculateTextAnchorShift(const ComputedStyle& style, float length) 31 float calculateTextAnchorShift(const ComputedStyle& style, float length)
34 { 32 {
35 bool isLTR = style.isLeftToRightDirection(); 33 bool isLTR = style.isLeftToRightDirection();
36 switch (style.svgStyle().textAnchor()) { 34 switch (style.svgStyle().textAnchor()) {
37 default: 35 default:
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 ChunkLengthAccumulator lengthAccumulator(!style.isHorizontalWritingMode()); 163 ChunkLengthAccumulator lengthAccumulator(!style.isHorizontalWritingMode());
166 lengthAccumulator.processRange(boxStart, boxEnd); 164 lengthAccumulator.processRange(boxStart, boxEnd);
167 165
168 // Handle text-anchor as additional start offset for text paths. 166 // Handle text-anchor as additional start offset for text paths.
169 m_totalTextAnchorShift += calculateTextAnchorShift(style, lengthAccumulator. length()); 167 m_totalTextAnchorShift += calculateTextAnchorShift(style, lengthAccumulator. length());
170 168
171 m_totalLength += lengthAccumulator.length(); 169 m_totalLength += lengthAccumulator.length();
172 m_totalCharacters += lengthAccumulator.numCharacters(); 170 m_totalCharacters += lengthAccumulator.numCharacters();
173 } 171 }
174 172
175 static void buildSpacingAndGlyphsTransform(bool isVerticalText, float scale, con st SVGTextFragment& fragment, AffineTransform& spacingAndGlyphsTransform) 173 static float computeTextLengthBias(const SVGTextFragment& fragment, float scale)
176 { 174 {
177 spacingAndGlyphsTransform.translate(fragment.x, fragment.y); 175 float initialPosition = fragment.isVertical ? fragment.y : fragment.x;
178 176 return initialPosition + scale * -initialPosition;
179 if (isVerticalText)
180 spacingAndGlyphsTransform.scaleNonUniform(1, scale);
181 else
182 spacingAndGlyphsTransform.scaleNonUniform(scale, 1);
183
184 spacingAndGlyphsTransform.translate(-fragment.x, -fragment.y);
185 } 177 }
186 178
187 void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxList ConstIterator boxEnd) 179 void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxList ConstIterator boxEnd)
188 { 180 {
189 ASSERT(*boxStart); 181 ASSERT(*boxStart);
190 182
191 const LineLayoutSVGInlineText textLineLayout = LineLayoutSVGInlineText((*box Start)->lineLayoutItem()); 183 const LineLayoutSVGInlineText textLineLayout = LineLayoutSVGInlineText((*box Start)->lineLayoutItem());
192 const ComputedStyle& style = textLineLayout.styleRef(); 184 const ComputedStyle& style = textLineLayout.styleRef();
193 185
194 // Handle 'lengthAdjust' property. 186 // Handle 'lengthAdjust' property.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 221
230 // Fragments have been adjusted, we have to recalculate the chunk 222 // Fragments have been adjusted, we have to recalculate the chunk
231 // length, to be able to apply the text-anchor shift. 223 // length, to be able to apply the text-anchor shift.
232 if (processTextAnchor) { 224 if (processTextAnchor) {
233 lengthAccumulator.reset(); 225 lengthAccumulator.reset();
234 lengthAccumulator.processRange(boxStart, boxEnd); 226 lengthAccumulator.processRange(boxStart, boxEnd);
235 } 227 }
236 } else { 228 } else {
237 ASSERT(lengthAdjust == SVGLengthAdjustSpacingAndGlyphs); 229 ASSERT(lengthAdjust == SVGLengthAdjustSpacingAndGlyphs);
238 float textLengthScale = desiredTextLength / chunkLength; 230 float textLengthScale = desiredTextLength / chunkLength;
239 AffineTransform spacingAndGlyphsTransform; 231 float textLengthBias = 0;
240 232
241 bool foundFirstFragment = false; 233 bool foundFirstFragment = false;
242 for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) { 234 for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) {
243 SVGInlineTextBox* textBox = *boxIter; 235 SVGInlineTextBox* textBox = *boxIter;
244 Vector<SVGTextFragment>& fragments = textBox->textFragments(); 236 Vector<SVGTextFragment>& fragments = textBox->textFragments();
245 if (fragments.isEmpty()) 237 if (fragments.isEmpty())
246 continue; 238 continue;
247 239
248 if (!foundFirstFragment) { 240 if (!foundFirstFragment) {
249 foundFirstFragment = true; 241 foundFirstFragment = true;
250 buildSpacingAndGlyphsTransform(isVerticalText, textLengthSca le, fragments.first(), spacingAndGlyphsTransform); 242 textLengthBias = computeTextLengthBias(fragments.first(), te xtLengthScale);
251 } 243 }
252 244
253 applyTextLengthScaleAdjustment(spacingAndGlyphsTransform, fragme nts); 245 applyTextLengthScaleAdjustment(textLengthScale, textLengthBias, fragments);
254 } 246 }
255 } 247 }
256 } 248 }
257 249
258 if (!processTextAnchor) 250 if (!processTextAnchor)
259 return; 251 return;
260 252
261 float textAnchorShift = calculateTextAnchorShift(style, lengthAccumulator.le ngth()); 253 float textAnchorShift = calculateTextAnchorShift(style, lengthAccumulator.le ngth());
262 for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) { 254 for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) {
263 Vector<SVGTextFragment>& fragments = (*boxIter)->textFragments(); 255 Vector<SVGTextFragment>& fragments = (*boxIter)->textFragments();
264 if (fragments.isEmpty()) 256 if (fragments.isEmpty())
265 continue; 257 continue;
266 processTextAnchorCorrection(isVerticalText, textAnchorShift, fragments); 258 processTextAnchorCorrection(isVerticalText, textAnchorShift, fragments);
267 } 259 }
268 } 260 }
269 261
270 void SVGTextChunkBuilder::processTextLengthSpacingCorrection(bool isVerticalText , float textLengthShift, Vector<SVGTextFragment>& fragments, unsigned& atCharact er) 262 void SVGTextChunkBuilder::processTextLengthSpacingCorrection(bool isVerticalText , float textLengthShift, Vector<SVGTextFragment>& fragments, unsigned& atCharact er)
271 { 263 {
272 for (SVGTextFragment& fragment : fragments) { 264 for (SVGTextFragment& fragment : fragments) {
273 if (isVerticalText) 265 if (isVerticalText)
274 fragment.y += textLengthShift * atCharacter; 266 fragment.y += textLengthShift * atCharacter;
275 else 267 else
276 fragment.x += textLengthShift * atCharacter; 268 fragment.x += textLengthShift * atCharacter;
277 269
278 atCharacter += fragment.length; 270 atCharacter += fragment.length;
279 } 271 }
280 } 272 }
281 273
282 void SVGTextChunkBuilder::applyTextLengthScaleAdjustment(const AffineTransform& spacingAndGlyphsTransform, Vector<SVGTextFragment>& fragments) 274 void SVGTextChunkBuilder::applyTextLengthScaleAdjustment(float textLengthScale, float textLengthBias, Vector<SVGTextFragment>& fragments)
283 { 275 {
284 for (SVGTextFragment& fragment : fragments) { 276 for (SVGTextFragment& fragment : fragments) {
285 ASSERT(fragment.lengthAdjustTransform.isIdentity()); 277 ASSERT(fragment.lengthAdjustScale == 1);
286 fragment.lengthAdjustTransform = spacingAndGlyphsTransform; 278 fragment.lengthAdjustScale = textLengthScale;
279 fragment.lengthAdjustBias = textLengthBias;
287 } 280 }
288 } 281 }
289 282
290 void SVGTextChunkBuilder::processTextAnchorCorrection(bool isVerticalText, float textAnchorShift, Vector<SVGTextFragment>& fragments) 283 void SVGTextChunkBuilder::processTextAnchorCorrection(bool isVerticalText, float textAnchorShift, Vector<SVGTextFragment>& fragments)
291 { 284 {
292 for (SVGTextFragment& fragment : fragments) { 285 for (SVGTextFragment& fragment : fragments) {
293 if (isVerticalText) 286 if (isVerticalText)
294 fragment.y += textAnchorShift; 287 fragment.y += textAnchorShift;
295 else 288 else
296 fragment.x += textAnchorShift; 289 fragment.x += textAnchorShift;
297 } 290 }
298 } 291 }
299 292
300 } 293 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698