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

Side by Side Diff: Source/core/rendering/svg/SVGTextQuery.cpp

Issue 349223003: Optimize SVGTextQuery's character offset ligature adjustment query (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 6 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
« no previous file with comments | « Source/core/rendering/svg/SVGTextQuery.h ('k') | 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 20 matching lines...) Expand all
31 31
32 namespace WebCore { 32 namespace WebCore {
33 33
34 // Base structure for callback user data 34 // Base structure for callback user data
35 struct SVGTextQuery::Data { 35 struct SVGTextQuery::Data {
36 Data() 36 Data()
37 : isVerticalText(false) 37 : isVerticalText(false)
38 , processedCharacters(0) 38 , processedCharacters(0)
39 , textRenderer(0) 39 , textRenderer(0)
40 , textBox(0) 40 , textBox(0)
41 , ligatureAdjustmentLastStartPositionQuery(-1)
42 , ligatureAdjustmentLastEndPositionQuery(-1)
43 , ligatureAdjustmentLastStartPositionResult(-1)
44 , ligatureAdjustmentLastEndPositionResult(-1)
41 { 45 {
42 } 46 }
43 47
48 void setupForTextBox(const SVGInlineTextBox* newTextBox)
49 {
50 textBox = newTextBox;
51 textRenderer = &toRenderSVGInlineText(textBox->textRenderer());
52 ASSERT(textRenderer->style());
53 ASSERT(textRenderer->style()->svgStyle());
54
55 isVerticalText = textRenderer->style()->svgStyle()->isVerticalWritingMod e();
56
57 // Invalidate the ligature-adjustment cache.
pdr. 2014/06/24 21:18:48 Is it possible to invalidate the cache when it rea
fs 2014/06/25 10:29:49 That pretty much what it does ATM - in the loop in
58 ligatureAdjustmentLastStartPositionQuery = ligatureAdjustmentLastEndPosi tionQuery = -1;
59 ligatureAdjustmentLastStartPositionResult = ligatureAdjustmentLastEndPos itionResult = -1;
60 }
61
44 bool isVerticalText; 62 bool isVerticalText;
45 unsigned processedCharacters; 63 unsigned processedCharacters;
46 RenderSVGInlineText* textRenderer; 64 RenderSVGInlineText* textRenderer;
47 const SVGInlineTextBox* textBox; 65 const SVGInlineTextBox* textBox;
66 // Ligature adjustment cache.
pdr. 2014/06/24 21:18:48 The cache key is pretty much {startPosition, proce
fs 2014/06/25 10:29:49 I suppose there could be some merit to that... To
67 int ligatureAdjustmentLastStartPositionQuery;
68 int ligatureAdjustmentLastEndPositionQuery;
69 int ligatureAdjustmentLastStartPositionResult;
70 int ligatureAdjustmentLastEndPositionResult;
48 }; 71 };
49 72
50 static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer) 73 static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer)
51 { 74 {
52 if (!renderer) 75 if (!renderer)
53 return 0; 76 return 0;
54 77
55 if (renderer->isRenderBlock()) { 78 if (renderer->isRenderBlock()) {
56 // If we're given a block element, it has to be a RenderSVGText. 79 // If we're given a block element, it has to be a RenderSVGText.
57 ASSERT(renderer->isSVGText()); 80 ASSERT(renderer->isSVGText());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 127
105 bool SVGTextQuery::executeQuery(Data* queryData, ProcessTextFragmentCallback fra gmentCallback) const 128 bool SVGTextQuery::executeQuery(Data* queryData, ProcessTextFragmentCallback fra gmentCallback) const
106 { 129 {
107 ASSERT(!m_textBoxes.isEmpty()); 130 ASSERT(!m_textBoxes.isEmpty());
108 131
109 unsigned processedCharacters = 0; 132 unsigned processedCharacters = 0;
110 unsigned textBoxCount = m_textBoxes.size(); 133 unsigned textBoxCount = m_textBoxes.size();
111 134
112 // Loop over all text boxes 135 // Loop over all text boxes
113 for (unsigned textBoxPosition = 0; textBoxPosition < textBoxCount; ++textBox Position) { 136 for (unsigned textBoxPosition = 0; textBoxPosition < textBoxCount; ++textBox Position) {
114 queryData->textBox = m_textBoxes.at(textBoxPosition); 137 queryData->setupForTextBox(m_textBoxes.at(textBoxPosition));
115 queryData->textRenderer = &toRenderSVGInlineText(queryData->textBox->tex tRenderer());
116 ASSERT(queryData->textRenderer->style());
117 ASSERT(queryData->textRenderer->style()->svgStyle());
118 138
119 queryData->isVerticalText = queryData->textRenderer->style()->svgStyle() ->isVerticalWritingMode();
120 const Vector<SVGTextFragment>& fragments = queryData->textBox->textFragm ents(); 139 const Vector<SVGTextFragment>& fragments = queryData->textBox->textFragm ents();
121 140
122 // Loop over all text fragments in this text box, firing a callback for each. 141 // Loop over all text fragments in this text box, firing a callback for each.
123 unsigned fragmentCount = fragments.size(); 142 unsigned fragmentCount = fragments.size();
124 for (unsigned i = 0; i < fragmentCount; ++i) { 143 for (unsigned i = 0; i < fragmentCount; ++i) {
125 const SVGTextFragment& fragment = fragments.at(i); 144 const SVGTextFragment& fragment = fragments.at(i);
126 if ((this->*fragmentCallback)(queryData, fragment)) 145 if ((this->*fragmentCallback)(queryData, fragment))
127 return true; 146 return true;
128 147
129 processedCharacters += fragment.length; 148 processedCharacters += fragment.length;
130 } 149 }
131 150
132 queryData->processedCharacters = processedCharacters; 151 queryData->processedCharacters = processedCharacters;
133 } 152 }
134 153
135 return false; 154 return false;
136 } 155 }
137 156
138 bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) const 157 bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) const
139 { 158 {
140 // Reuse the same logic used for text selection & painting, to map our query start/length into start/endPositions of the current text fragment. 159 // Reuse the same logic used for text selection & painting, to map our query start/length into start/endPositions of the current text fragment.
141 startPosition -= queryData->processedCharacters; 160 startPosition -= queryData->processedCharacters;
142 endPosition -= queryData->processedCharacters; 161 endPosition -= queryData->processedCharacters;
143 162
144 startPosition = max(0, startPosition); 163 startPosition = max(0, startPosition);
145 164
146 if (startPosition >= endPosition) 165 if (startPosition >= endPosition)
147 return false; 166 return false;
148 167
149 modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosi tion); 168 modifyStartEndPositionsRespectingLigaturesCached(queryData, startPosition, e ndPosition);
pdr. 2014/06/24 21:18:48 This name was confusing until I read the implement
fs 2014/06/25 10:29:49 Although it didn't like having the additional indi
150 if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragmen t, startPosition, endPosition)) 169 if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragmen t, startPosition, endPosition))
151 return false; 170 return false;
152 171
153 ASSERT(startPosition < endPosition); 172 ASSERT(startPosition < endPosition);
154 return true; 173 return true;
155 } 174 }
156 175
176 void SVGTextQuery::modifyStartEndPositionsRespectingLigaturesCached(Data* queryD ata, int& startPosition, int& endPosition) const
177 {
178 if (queryData->ligatureAdjustmentLastStartPositionQuery == startPosition && queryData->ligatureAdjustmentLastEndPositionQuery == endPosition) {
179 startPosition = queryData->ligatureAdjustmentLastStartPositionResult;
180 endPosition = queryData->ligatureAdjustmentLastEndPositionResult;
181 return;
182 }
183
184 queryData->ligatureAdjustmentLastStartPositionQuery = startPosition;
185 queryData->ligatureAdjustmentLastEndPositionQuery = endPosition;
186
187 modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosi tion);
188
189 queryData->ligatureAdjustmentLastStartPositionResult = startPosition;
190 queryData->ligatureAdjustmentLastEndPositionResult = endPosition;
191 }
192
157 void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i nt& startPosition, int& endPosition) const 193 void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i nt& startPosition, int& endPosition) const
158 { 194 {
159 SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutA ttributes(); 195 SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutA ttributes();
160 Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsVal ues(); 196 Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsVal ues();
161 unsigned boxStart = queryData->textBox->start(); 197 unsigned boxStart = queryData->textBox->start();
162 unsigned boxLength = queryData->textBox->len(); 198 unsigned boxLength = queryData->textBox->len();
163 199
164 unsigned textMetricsOffset = 0; 200 unsigned textMetricsOffset = 0;
165 unsigned textMetricsSize = textMetricsValues.size(); 201 unsigned textMetricsSize = textMetricsValues.size();
166 202
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 return -1; 577 return -1;
542 578
543 CharacterNumberAtPositionData data(position); 579 CharacterNumberAtPositionData data(position);
544 if (!executeQuery(&data, &SVGTextQuery::characterNumberAtPositionCallback)) 580 if (!executeQuery(&data, &SVGTextQuery::characterNumberAtPositionCallback))
545 return -1; 581 return -1;
546 582
547 return data.processedCharacters; 583 return data.processedCharacters;
548 } 584 }
549 585
550 } 586 }
OLDNEW
« no previous file with comments | « Source/core/rendering/svg/SVGTextQuery.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698