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

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

Issue 355373003: Simplify SVGTextQuery::modifyStartEndPositionsRespectingLigatures (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 int fragmentStartInBox = fragment.characterOffset - queryData->textBox->star t(); 144 int fragmentStartInBox = fragment.characterOffset - queryData->textBox->star t();
145 int fragmentEndInBox = fragmentStartInBox + fragment.length; 145 int fragmentEndInBox = fragmentStartInBox + fragment.length;
146 146
147 // Check if the ranges intersect. 147 // Check if the ranges intersect.
148 startPosition = std::max(startPosition, fragmentStartInBox); 148 startPosition = std::max(startPosition, fragmentStartInBox);
149 endPosition = std::min(endPosition, fragmentEndInBox); 149 endPosition = std::min(endPosition, fragmentEndInBox);
150 150
151 if (startPosition >= endPosition) 151 if (startPosition >= endPosition)
152 return false; 152 return false;
153 153
154 modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosi tion); 154 modifyStartEndPositionsRespectingLigatures(queryData, fragment, startPositio n, endPosition);
155 if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragmen t, startPosition, endPosition)) 155 if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragmen t, startPosition, endPosition))
156 return false; 156 return false;
157 157
158 ASSERT(startPosition < endPosition); 158 ASSERT(startPosition < endPosition);
159 return true; 159 return true;
160 } 160 }
161 161
162 void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i nt& startPosition, int& endPosition) const 162 void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, c onst SVGTextFragment& fragment, int& startPosition, int& endPosition) const
163 { 163 {
164 SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutA ttributes(); 164 SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutA ttributes();
165 Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsVal ues(); 165 Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsVal ues();
166 unsigned boxStart = queryData->textBox->start();
167 unsigned boxLength = queryData->textBox->len();
168 166
169 unsigned textMetricsOffset = 0; 167 unsigned textMetricsOffset = fragment.metricsListOffset;
170 unsigned textMetricsSize = textMetricsValues.size();
171 168
172 unsigned positionOffset = 0; 169 // Compute the offset of the fragment within the box, since that's the
173 unsigned positionSize = layoutAttributes->context()->textLength(); 170 // space <startPosition, endPosition> is in (and that's what we need).
171 int fragmentOffsetInBox = fragment.characterOffset - queryData->textBox->sta rt();
172 int fragmentEndInBox = fragmentOffsetInBox + fragment.length;
174 173
175 bool alterStartPosition = true; 174 // Find the text metrics cell that start at or contain the character startPo sition.
176 bool alterEndPosition = true; 175 while (fragmentOffsetInBox < fragmentEndInBox) {
177
178 int lastPositionOffset = -1;
179 for (; textMetricsOffset < textMetricsSize && positionOffset < positionSize; ++textMetricsOffset) {
180 SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; 176 SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset];
181 177 int glyphEnd = fragmentOffsetInBox + metrics.length();
182 // Advance to text box start location. 178 if (startPosition < glyphEnd)
183 if (positionOffset < boxStart) {
184 positionOffset += metrics.length();
185 continue;
186 }
187
188 // Stop if we've finished processing this text box.
189 if (positionOffset >= boxStart + boxLength)
190 break; 179 break;
191 180 fragmentOffsetInBox = glyphEnd;
192 // If the start position maps to a character in the metrics list, we don 't need to modify it. 181 textMetricsOffset++;
193 if (startPosition == static_cast<int>(positionOffset))
194 alterStartPosition = false;
195
196 // If the start position maps to a character in the metrics list, we don 't need to modify it.
197 if (endPosition == static_cast<int>(positionOffset))
198 alterEndPosition = false;
199
200 // Detect ligatures.
201 if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) {
202 if (alterStartPosition && startPosition > lastPositionOffset && star tPosition < static_cast<int>(positionOffset)) {
203 startPosition = lastPositionOffset;
204 alterStartPosition = false;
205 }
206
207 if (alterEndPosition && endPosition > lastPositionOffset && endPosit ion < static_cast<int>(positionOffset)) {
208 endPosition = positionOffset;
209 alterEndPosition = false;
210 }
211 }
212
213 if (!alterStartPosition && !alterEndPosition)
214 break;
215
216 lastPositionOffset = positionOffset;
217 positionOffset += metrics.length();
218 } 182 }
219 183
220 if (!alterStartPosition && !alterEndPosition) 184 startPosition = fragmentOffsetInBox;
221 return;
222 185
223 if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) { 186 // Find the text metrics cell that contain or ends at the character endPosit ion.
224 if (alterStartPosition && startPosition > lastPositionOffset && startPos ition < static_cast<int>(positionOffset)) 187 while (fragmentOffsetInBox < fragmentEndInBox) {
225 startPosition = lastPositionOffset; 188 SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset];
189 fragmentOffsetInBox += metrics.length();
190 if (fragmentOffsetInBox >= endPosition)
191 break;
192 textMetricsOffset++;
193 }
226 194
227 if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) 195 endPosition = fragmentOffsetInBox;
228 endPosition = positionOffset;
229 }
230 } 196 }
231 197
232 // numberOfCharacters() implementation 198 // numberOfCharacters() implementation
233 bool SVGTextQuery::numberOfCharactersCallback(Data*, const SVGTextFragment&) con st 199 bool SVGTextQuery::numberOfCharactersCallback(Data*, const SVGTextFragment&) con st
234 { 200 {
235 // no-op 201 // no-op
236 return false; 202 return false;
237 } 203 }
238 204
239 unsigned SVGTextQuery::numberOfCharacters() const 205 unsigned SVGTextQuery::numberOfCharacters() const
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const 492 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const
527 { 493 {
528 CharacterNumberAtPositionData data(position); 494 CharacterNumberAtPositionData data(position);
529 if (!executeQuery(&data, &SVGTextQuery::characterNumberAtPositionCallback)) 495 if (!executeQuery(&data, &SVGTextQuery::characterNumberAtPositionCallback))
530 return -1; 496 return -1;
531 497
532 return data.processedCharacters; 498 return data.processedCharacters;
533 } 499 }
534 500
535 } 501 }
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