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

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: Update per reviewer comments 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.
186 // TreeWalkTextState should be used to maintain the value list position which
187 // indexes into the SVGCharacterDataMap of all characters.
188 struct UpdateAttributes {
189 UpdateAttributes(SVGTextLayoutAttributes& textAttributes, const SVGCharacter DataMap* allCharacters)
190 : attributes(textAttributes)
191 , allCharactersMap(allCharacters) { }
192
193 void clearExistingAttributes()
194 {
195 if (allCharactersMap)
196 attributes.clear();
197 else
198 attributes.textMetricsValues().clear();
199 }
200
201 void addMetrics(SVGTextMetrics metrics)
202 {
203 attributes.textMetricsValues().append(metrics);
204 }
205
206 void updateCharacterDataMap(unsigned valueListPosition, unsigned currentText Position)
207 {
208 if (!allCharactersMap)
209 return;
210 const SVGCharacterDataMap::const_iterator it = allCharactersMap->find(va lueListPosition);
211 if (it != allCharactersMap->end())
212 attributes.characterDataMap().set(currentTextPosition, it->value);
213 }
214
215 SVGTextLayoutAttributes& attributes;
216 const SVGCharacterDataMap* allCharactersMap;
217 };
218
219 static void walkInlineText(LayoutSVGInlineText* text, TreeWalkTextState& textSta te, UpdateAttributes* attributesToUpdate = nullptr)
190 { 220 {
191 ASSERT(text); 221 if (attributesToUpdate)
192 222 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 223
202 if (!text->textLength()) 224 if (!text->textLength())
203 return; 225 return;
204 226
205 // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator. 227 // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator.
206 // We should refactor SVGTextMetricsCalculator to be a simple bidi run 228 // We should refactor SVGTextMetricsCalculator to be a simple bidi run
207 // iterator and move all subrun logic to a single function. 229 // iterator and move all subrun logic to a single function.
208 SVGTextMetricsCalculator calculator(text); 230 SVGTextMetricsCalculator calculator(text);
209 bool preserveWhiteSpace = text->style()->whiteSpace() == PRE; 231 bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
210 unsigned surrogatePairCharacters = 0; 232 unsigned surrogatePairCharacters = 0;
211 unsigned skippedCharacters = 0; 233 unsigned skippedWhitespace = 0;
212 do { 234 do {
213 SVGTextMetrics metrics = calculator.currentCharacterMetrics(); 235 bool currentCharacterIsWhiteSpace = calculator.currentCharacterIsWhiteSp ace();
214 if (!metrics.length()) 236 if (currentCharacterIsWhiteSpace && !preserveWhiteSpace && textState.las tCharacterWasWhiteSpace) {
215 break; 237 if (attributesToUpdate)
216 238 attributesToUpdate->addMetrics(SVGTextMetrics(SVGTextMetrics::Sk ippedSpaceMetrics));
217 bool characterIsWhiteSpace = calculator.currentCharacterIsWhiteSpace(); 239 ASSERT(calculator.currentCharacterMetrics().length() == 1);
218 if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterW asWhiteSpace) { 240 skippedWhitespace++;
219 if (processLayoutObject)
220 textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::Skipped SpaceMetrics));
221 if (data->allCharactersMap)
222 skippedCharacters += metrics.length();
223 continue; 241 continue;
224 } 242 }
225 243
226 if (processLayoutObject) { 244 if (attributesToUpdate) {
227 if (data->allCharactersMap) { 245 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); 246 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 } 247 }
234 248
235 if (data->allCharactersMap && calculator.currentCharacterStartsSurrogate Pair()) 249 if (calculator.currentCharacterStartsSurrogatePair())
236 surrogatePairCharacters++; 250 surrogatePairCharacters++;
237 251 textState.lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace;
238 data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
239 } while (calculator.advancePosition()); 252 } while (calculator.advancePosition());
240 253
241 if (!data->allCharactersMap) 254 textState.valueListPosition += calculator.currentPosition() - skippedWhitesp ace;
242 return;
243
244 data->valueListPosition += calculator.currentPosition() - skippedCharacters;
245 } 255 }
246 256
247 static void walkTree(LayoutSVGText* start, LayoutSVGInlineText* stopAtLeaf, Meas ureTextData* data) 257 static void walkTree(LayoutSVGText* start, LayoutSVGInlineText* stopAtText, SVGC haracterDataMap* allCharactersMap = nullptr)
248 { 258 {
259 TreeWalkTextState textState;
249 LayoutObject* child = start->firstChild(); 260 LayoutObject* child = start->firstChild();
250 while (child) { 261 while (child) {
251 if (child->isSVGInlineText()) { 262 if (child->isSVGInlineText()) {
252 LayoutSVGInlineText* text = toLayoutSVGInlineText(child); 263 LayoutSVGInlineText* text = toLayoutSVGInlineText(child);
253 measureTextLayoutObject(text, data, !stopAtLeaf || stopAtLeaf == tex t); 264 OwnPtr<UpdateAttributes> attributesToUpdate = nullptr;
254 if (stopAtLeaf && stopAtLeaf == text) 265 if (!stopAtText || stopAtText == text)
266 attributesToUpdate = adoptPtr(new UpdateAttributes(*text->layout Attributes(), allCharactersMap));
267 walkInlineText(text, textState, attributesToUpdate.get());
268 if (stopAtText == text)
255 return; 269 return;
256 } else if (child->isSVGInline()) { 270 } else if (child->isSVGInline()) {
257 // Visit children of text content elements. 271 // Visit children of text content elements.
258 if (LayoutObject* inlineChild = toLayoutSVGInline(child)->firstChild ()) { 272 if (LayoutObject* inlineChild = toLayoutSVGInline(child)->firstChild ()) {
259 child = inlineChild; 273 child = inlineChild;
260 continue; 274 continue;
261 } 275 }
262 } 276 }
263 child = child->nextInPreOrderAfterChildren(start); 277 child = child->nextInPreOrderAfterChildren(start);
264 } 278 }
265 } 279 }
266 280
267 void SVGTextMetricsBuilder::measureTextLayoutObject(LayoutSVGInlineText* text) 281 void SVGTextMetricsBuilder::measureTextLayoutObject(LayoutSVGInlineText* text)
268 { 282 {
269 ASSERT(text); 283 ASSERT(text);
270 284 if (LayoutSVGText* textRoot = LayoutSVGText::locateLayoutSVGTextAncestor(tex t))
271 LayoutSVGText* textRoot = LayoutSVGText::locateLayoutSVGTextAncestor(text); 285 walkTree(textRoot, text);
272 if (!textRoot)
273 return;
274
275 MeasureTextData data(0);
276 walkTree(textRoot, text, &data);
277 } 286 }
278 287
279 void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(LayoutSVGText* textR oot, LayoutSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap) 288 void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(LayoutSVGText* textR oot, LayoutSVGInlineText* stopAtText, SVGCharacterDataMap& allCharactersMap)
280 { 289 {
281 ASSERT(textRoot); 290 ASSERT(textRoot);
282 MeasureTextData data(&allCharactersMap); 291 walkTree(textRoot, stopAtText, &allCharactersMap);
283 walkTree(textRoot, stopAtLeaf, &data);
284 } 292 }
285 293
286 } // namespace blink 294 } // 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