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

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

Issue 1822513002: Cleanup SVGTextMetricsBuilder::measureTextLayoutObject (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10 matching lines...) Expand all
21 21
22 #include "core/layout/api/LineLayoutSVGInlineText.h" 22 #include "core/layout/api/LineLayoutSVGInlineText.h"
23 #include "core/layout/svg/LayoutSVGInline.h" 23 #include "core/layout/svg/LayoutSVGInline.h"
24 #include "core/layout/svg/LayoutSVGInlineText.h" 24 #include "core/layout/svg/LayoutSVGInlineText.h"
25 #include "core/layout/svg/LayoutSVGText.h" 25 #include "core/layout/svg/LayoutSVGText.h"
26 #include "core/layout/svg/SVGTextMetrics.h" 26 #include "core/layout/svg/SVGTextMetrics.h"
27 #include "platform/fonts/CharacterRange.h" 27 #include "platform/fonts/CharacterRange.h"
28 #include "platform/text/BidiCharacterRun.h" 28 #include "platform/text/BidiCharacterRun.h"
29 #include "platform/text/BidiResolver.h" 29 #include "platform/text/BidiResolver.h"
30 #include "platform/text/TextDirection.h" 30 #include "platform/text/TextDirection.h"
31 #include "platform/text/TextPath.h"
32 #include "platform/text/TextRun.h" 31 #include "platform/text/TextRun.h"
33 #include "platform/text/TextRunIterator.h" 32 #include "platform/text/TextRunIterator.h"
34 #include "wtf/Vector.h" 33 #include "wtf/Vector.h"
35 34
36 namespace blink { 35 namespace blink {
37 36
38 class SVGTextMetricsCalculator { 37 class SVGTextMetricsCalculator {
39 public: 38 public:
40 SVGTextMetricsCalculator(LayoutSVGInlineText*); 39 SVGTextMetricsCalculator(LayoutSVGInlineText*);
41 ~SVGTextMetricsCalculator(); 40 ~SVGTextMetricsCalculator();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 165 }
167 166
168 SVGTextMetrics SVGTextMetricsCalculator::currentCharacterMetrics() 167 SVGTextMetrics SVGTextMetricsCalculator::currentCharacterMetrics()
169 { 168 {
170 unsigned currentSubrunPosition = updateSubrunRangesForCurrentPosition(); 169 unsigned currentSubrunPosition = updateSubrunRangesForCurrentPosition();
171 unsigned length = currentCharacterStartsSurrogatePair() ? 2 : 1; 170 unsigned length = currentCharacterStartsSurrogatePair() ? 2 : 1;
172 float width = m_subrunRanges[currentSubrunPosition].width(); 171 float width = m_subrunRanges[currentSubrunPosition].width();
173 return SVGTextMetrics(m_text, length, width); 172 return SVGTextMetrics(m_text, length, width);
174 } 173 }
175 174
176 struct MeasureTextData { 175 struct TreeWalkTextState {
177 MeasureTextData(SVGCharacterDataMap* characterDataMap) 176 TreeWalkTextState()
178 : allCharactersMap(characterDataMap) 177 : lastCharacterWasWhiteSpace(true)
179 , lastCharacterWasWhiteSpace(true) 178 , valueListPosition(0) { }
180 , valueListPosition(0)
181 {
182 }
183 179
184 SVGCharacterDataMap* allCharactersMap;
185 bool lastCharacterWasWhiteSpace; 180 bool lastCharacterWasWhiteSpace;
186 unsigned valueListPosition; 181 unsigned valueListPosition;
187 }; 182 };
188 183
189 static void measureTextLayoutObject(LayoutSVGInlineText* text, MeasureTextData* data, bool processLayoutObject) 184 // Struct for updating SVGTextLayoutAttributes. If an SVGCharacterDataMap is
185 // available, the attribute's character data map will also be updated.
fs 2016/03/20 23:43:38 Maybe mention the relation to valueListPosition to
pdr. 2016/03/21 18:44:22 Good idea, done.
186 struct UpdateAttributes {
187 UpdateAttributes(SVGTextLayoutAttributes& textAttributes, const SVGCharacter DataMap* allCharacters)
188 : attributes(textAttributes)
189 , allCharactersMap(allCharacters) { }
190
191 void clearExistingAttributes()
192 {
193 if (allCharactersMap)
194 attributes.clear();
195 else
196 attributes.textMetricsValues().clear();
197 }
198
199 void addMetrics(SVGTextMetrics metrics)
200 {
201 attributes.textMetricsValues().append(metrics);
202 }
203
204 void updateCharacterDataMap(unsigned valueListPosition, unsigned currentText Position)
205 {
206 if (!allCharactersMap)
207 return;
208 const SVGCharacterDataMap::const_iterator it = allCharactersMap->find(va lueListPosition);
209 if (it != allCharactersMap->end())
210 attributes.characterDataMap().set(currentTextPosition, it->value);
211 }
212
213 SVGTextLayoutAttributes& attributes;
214 const SVGCharacterDataMap* allCharactersMap;
215 };
216
217 static void walkInlineText(LayoutSVGInlineText* text, TreeWalkTextState& textSta te, UpdateAttributes* attributesToUpdate = nullptr)
190 { 218 {
191 ASSERT(text); 219 if (attributesToUpdate)
192 220 attributesToUpdate->clearExistingAttributes();
193 SVGTextLayoutAttributes* attributes = text->layoutAttributes();
194 Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues() ;
195 if (processLayoutObject) {
196 if (data->allCharactersMap)
197 attributes->clear();
198 else
199 textMetricsValues->clear();
200 }
201 221
202 if (!text->textLength()) 222 if (!text->textLength())
203 return; 223 return;
204 224
205 // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator. 225 // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator.
206 // We should refactor SVGTextMetricsCalculator to be a simple bidi run 226 // We should refactor SVGTextMetricsCalculator to be a simple bidi run
207 // iterator and move all subrun logic to a single function. 227 // iterator and move all subrun logic to a single function.
208 SVGTextMetricsCalculator calculator(text); 228 SVGTextMetricsCalculator calculator(text);
209 bool preserveWhiteSpace = text->style()->whiteSpace() == PRE; 229 bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
210 unsigned surrogatePairCharacters = 0; 230 unsigned surrogatePairCharacters = 0;
211 unsigned skippedCharacters = 0; 231 unsigned skippedWhitespace = 0;
212 do { 232 do {
213 SVGTextMetrics metrics = calculator.currentCharacterMetrics(); 233 bool currentCharacterIsWhiteSpace = calculator.currentCharacterIsWhiteSp ace();
214 if (!metrics.length()) 234 if (currentCharacterIsWhiteSpace && !preserveWhiteSpace && textState.las tCharacterWasWhiteSpace) {
215 break; 235 if (attributesToUpdate)
216 236 attributesToUpdate->addMetrics(SVGTextMetrics(SVGTextMetrics::Sk ippedSpaceMetrics));
217 bool characterIsWhiteSpace = calculator.currentCharacterIsWhiteSpace(); 237 ASSERT(!calculator.currentCharacterStartsSurrogatePair());
fs 2016/03/20 23:43:38 Maybe just assert calculator.currentCharacterMetri
pdr. 2016/03/21 18:44:22 Done
218 if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterW asWhiteSpace) { 238 ASSERT(textState.lastCharacterWasWhiteSpace);
fs 2016/03/20 23:43:38 This is part of the condition, so maybe a tad over
pdr. 2016/03/21 18:44:22 Done
219 if (processLayoutObject) 239 skippedWhitespace++;
220 textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::Skipped SpaceMetrics));
221 if (data->allCharactersMap)
222 skippedCharacters += metrics.length();
223 continue; 240 continue;
224 } 241 }
225 242
226 if (processLayoutObject) { 243 if (attributesToUpdate) {
227 if (data->allCharactersMap) { 244 attributesToUpdate->updateCharacterDataMap(textState.valueListPositi on - skippedWhitespace - surrogatePairCharacters + calculator.currentPosition() + 1, calculator.currentPosition() + 1);
228 const SVGCharacterDataMap::const_iterator it = data->allCharacte rsMap->find(data->valueListPosition + calculator.currentPosition() - skippedChar acters - surrogatePairCharacters + 1); 245 attributesToUpdate->addMetrics(calculator.currentCharacterMetrics()) ;
229 if (it != data->allCharactersMap->end())
230 attributes->characterDataMap().set(calculator.currentPositio n() + 1, it->value);
231 }
232 textMetricsValues->append(metrics);
233 } 246 }
234 247
235 if (data->allCharactersMap && calculator.currentCharacterStartsSurrogate Pair()) 248 if (calculator.currentCharacterStartsSurrogatePair())
236 surrogatePairCharacters++; 249 surrogatePairCharacters++;
237 250 textState.lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace;
238 data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
239 } while (calculator.advancePosition()); 251 } while (calculator.advancePosition());
240 252
241 if (!data->allCharactersMap) 253 textState.valueListPosition += calculator.currentPosition() - skippedWhitesp ace;
242 return;
243
244 data->valueListPosition += calculator.currentPosition() - skippedCharacters;
245 } 254 }
246 255
247 static void walkTree(LayoutSVGText* start, LayoutSVGInlineText* stopAtLeaf, Meas ureTextData* data) 256 static void walkTree(LayoutSVGText* start, LayoutSVGInlineText* stopAtText, SVGC haracterDataMap* allCharactersMap = nullptr)
248 { 257 {
258 TreeWalkTextState textState;
249 LayoutObject* child = start->firstChild(); 259 LayoutObject* child = start->firstChild();
250 while (child) { 260 while (child) {
251 if (child->isSVGInlineText()) { 261 if (child->isSVGInlineText()) {
252 LayoutSVGInlineText* text = toLayoutSVGInlineText(child); 262 LayoutSVGInlineText* text = toLayoutSVGInlineText(child);
253 measureTextLayoutObject(text, data, !stopAtLeaf || stopAtLeaf == tex t); 263 OwnPtr<UpdateAttributes> attributesToUpdate = nullptr;
254 if (stopAtLeaf && stopAtLeaf == text) 264 if (!stopAtText || stopAtText == text)
265 attributesToUpdate = adoptPtr(new UpdateAttributes(*text->layout Attributes(), allCharactersMap));
266 walkInlineText(text, textState, attributesToUpdate.get());
267 if (stopAtText == text)
255 return; 268 return;
256 } else if (child->isSVGInline()) { 269 } else if (child->isSVGInline()) {
257 // Visit children of text content elements. 270 // Visit children of text content elements.
258 if (LayoutObject* inlineChild = toLayoutSVGInline(child)->firstChild ()) { 271 if (LayoutObject* inlineChild = toLayoutSVGInline(child)->firstChild ()) {
259 child = inlineChild; 272 child = inlineChild;
260 continue; 273 continue;
261 } 274 }
262 } 275 }
263 child = child->nextInPreOrderAfterChildren(start); 276 child = child->nextInPreOrderAfterChildren(start);
264 } 277 }
265 } 278 }
266 279
267 void SVGTextMetricsBuilder::measureTextLayoutObject(LayoutSVGInlineText* text) 280 void SVGTextMetricsBuilder::measureTextLayoutObject(LayoutSVGInlineText* text)
268 { 281 {
269 ASSERT(text); 282 ASSERT(text);
270 283 if (LayoutSVGText* textRoot = LayoutSVGText::locateLayoutSVGTextAncestor(tex t))
271 LayoutSVGText* textRoot = LayoutSVGText::locateLayoutSVGTextAncestor(text); 284 walkTree(textRoot, text);
272 if (!textRoot)
273 return;
274
275 MeasureTextData data(0);
276 walkTree(textRoot, text, &data);
277 } 285 }
278 286
279 void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(LayoutSVGText* textR oot, LayoutSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap) 287 void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(LayoutSVGText* textR oot, LayoutSVGInlineText* stopAtText, SVGCharacterDataMap& allCharactersMap)
280 { 288 {
281 ASSERT(textRoot); 289 ASSERT(textRoot);
282 MeasureTextData data(&allCharactersMap); 290 walkTree(textRoot, stopAtText, &allCharactersMap);
283 walkTree(textRoot, stopAtLeaf, &data);
284 } 291 }
285 292
286 } // namespace blink 293 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698