| 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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |