| 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 |