OLD | NEW |
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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 } | 127 } |
128 | 128 |
129 queryData->processedCharacters = processedCharacters; | 129 queryData->processedCharacters = processedCharacters; |
130 } | 130 } |
131 | 131 |
132 return false; | 132 return false; |
133 } | 133 } |
134 | 134 |
135 bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData,
const SVGTextFragment& fragment, int& startPosition, int& endPosition) const | 135 bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData,
const SVGTextFragment& fragment, int& startPosition, int& endPosition) const |
136 { | 136 { |
137 // Reuse the same logic used for text selection & painting, to map our query
start/length into start/endPositions of the current text fragment. | 137 // Make <startPosition, endPosition> offsets relative to the current text bo
x. |
138 startPosition -= queryData->processedCharacters; | 138 startPosition -= queryData->processedCharacters; |
139 endPosition -= queryData->processedCharacters; | 139 endPosition -= queryData->processedCharacters; |
140 | 140 |
141 // <startPosition, endPosition> is now a tuple of offsets relative to the cu
rrent text box. | 141 // Reuse the same logic used for text selection & painting, to map our |
142 // Compute the offsets of the fragment in the same offset space. | 142 // query start/length into start/endPositions of the current text fragment. |
143 int fragmentStartInBox = fragment.characterOffset - queryData->textBox->star
t(); | 143 if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragmen
t, startPosition, endPosition)) |
144 int fragmentEndInBox = fragmentStartInBox + fragment.length; | |
145 | |
146 // Check if the ranges intersect. | |
147 startPosition = std::max(startPosition, fragmentStartInBox); | |
148 endPosition = std::min(endPosition, fragmentEndInBox); | |
149 | |
150 if (startPosition >= endPosition) | |
151 return false; | 144 return false; |
152 | 145 |
153 modifyStartEndPositionsRespectingLigatures(queryData, fragment, startPositio
n, endPosition); | 146 modifyStartEndPositionsRespectingLigatures(queryData, fragment, startPositio
n, endPosition); |
154 if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragmen
t, startPosition, endPosition)) | |
155 return false; | |
156 | |
157 ASSERT(startPosition < endPosition); | 147 ASSERT(startPosition < endPosition); |
158 return true; | 148 return true; |
159 } | 149 } |
160 | 150 |
161 void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, c
onst SVGTextFragment& fragment, int& startPosition, int& endPosition) const | 151 void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, c
onst SVGTextFragment& fragment, int& startPosition, int& endPosition) const |
162 { | 152 { |
163 SVGTextLayoutAttributes* layoutAttributes = queryData->textLayoutObject->lay
outAttributes(); | 153 const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLayoutObjec
t->layoutAttributes()->textMetricsValues(); |
164 Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsVal
ues(); | |
165 | 154 |
166 unsigned textMetricsOffset = fragment.metricsListOffset; | 155 unsigned textMetricsOffset = fragment.metricsListOffset; |
167 | 156 int fragmentOffset = 0; |
168 // Compute the offset of the fragment within the box, since that's the | 157 int fragmentEnd = static_cast<int>(fragment.length); |
169 // space <startPosition, endPosition> is in (and that's what we need). | |
170 int fragmentOffsetInBox = fragment.characterOffset - queryData->textBox->sta
rt(); | |
171 int fragmentEndInBox = fragmentOffsetInBox + fragment.length; | |
172 | 158 |
173 // Find the text metrics cell that start at or contain the character startPo
sition. | 159 // Find the text metrics cell that start at or contain the character startPo
sition. |
174 while (fragmentOffsetInBox < fragmentEndInBox) { | 160 while (fragmentOffset < fragmentEnd) { |
175 SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; | 161 const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; |
176 int glyphEnd = fragmentOffsetInBox + metrics.length(); | 162 int glyphEnd = fragmentOffset + metrics.length(); |
177 if (startPosition < glyphEnd) | 163 if (startPosition < glyphEnd) |
178 break; | 164 break; |
179 fragmentOffsetInBox = glyphEnd; | 165 fragmentOffset = glyphEnd; |
180 textMetricsOffset++; | 166 textMetricsOffset++; |
181 } | 167 } |
182 | 168 |
183 startPosition = fragmentOffsetInBox; | 169 startPosition = fragmentOffset; |
184 | 170 |
185 // Find the text metrics cell that contain or ends at the character endPosit
ion. | 171 // Find the text metrics cell that contain or ends at the character endPosit
ion. |
186 while (fragmentOffsetInBox < fragmentEndInBox) { | 172 while (fragmentOffset < fragmentEnd) { |
187 SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; | 173 const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; |
188 fragmentOffsetInBox += metrics.length(); | 174 fragmentOffset += metrics.length(); |
189 if (fragmentOffsetInBox >= endPosition) | 175 if (fragmentOffset >= endPosition) |
190 break; | 176 break; |
191 textMetricsOffset++; | 177 textMetricsOffset++; |
192 } | 178 } |
193 | 179 |
194 endPosition = fragmentOffsetInBox; | 180 endPosition = fragmentOffset; |
195 } | 181 } |
196 | 182 |
197 // numberOfCharacters() implementation | 183 // numberOfCharacters() implementation |
198 bool SVGTextQuery::numberOfCharactersCallback(Data*, const SVGTextFragment&) con
st | 184 bool SVGTextQuery::numberOfCharactersCallback(Data*, const SVGTextFragment&) con
st |
199 { | 185 { |
200 // no-op | 186 // no-op |
201 return false; | 187 return false; |
202 } | 188 } |
203 | 189 |
204 unsigned SVGTextQuery::numberOfCharacters() const | 190 unsigned SVGTextQuery::numberOfCharacters() const |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const | 530 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const |
545 { | 531 { |
546 CharacterNumberAtPositionData data(position); | 532 CharacterNumberAtPositionData data(position); |
547 if (!executeQuery(&data, &SVGTextQuery::characterNumberAtPositionCallback)) | 533 if (!executeQuery(&data, &SVGTextQuery::characterNumberAtPositionCallback)) |
548 return -1; | 534 return -1; |
549 | 535 |
550 return data.processedCharacters; | 536 return data.processedCharacters; |
551 } | 537 } |
552 | 538 |
553 } | 539 } |
OLD | NEW |