static bool characterNumberAtPositionCallback(QueryData* queryData, const SVGTextFragment& fragment) { CharacterNumberAtPositionData* data = static_cast<CharacterNumberAtPositionData*>(queryData); // Test the query point against the bounds of the entire fragment first. FloatRect fragmentExtents = calculateFragmentBoundaries(*queryData->textLayoutObject, fragment); if (!fragmentExtents.contains(data->position)) return false; // Iterate through the glyphs in this fragment, and check if their extents // contain the query point. FloatRect extent; const Vector<SVGTextMetrics>& textMetrics = queryData->textLayoutObject->layoutAttributes()->textMetricsValues(); unsigned textMetricsOffset = fragment.metricsListOffset; unsigned fragmentOffset = 0; while (fragmentOffset < fragment.length) { calculateGlyphBoundaries(queryData, fragment, fragmentOffset, extent); if (extent.contains(data->position)) { // Compute the character offset of the glyph within the text node. unsigned offsetInBox = fragment.characterOffset - queryData->textBox->start() + fragmentOffset; data->offsetInTextNode = logicalOffsetInTextNode(*queryData->textLayoutObject, queryData->textBox, offsetInBox); data->hitLayoutObject = data->textLayoutObject; return true; } fragmentOffset += textMetrics[textMetricsOffset].length(); textMetricsOffset++; } return false; }
bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGTextFragment& fragment) const { CharacterNumberAtPositionData* data = static_cast<CharacterNumberAtPositionData*>(queryData); // Test the query point against the bounds of the entire fragment first. FloatRect fragmentExtents = calculateFragmentBoundaries(*queryData->textRenderer, fragment); if (!fragmentExtents.contains(data->position)) return false; // Iterate through the glyphs in this fragment, and check if their extents // contain the query point. FloatRect extent; const Vector<SVGTextMetrics>& textMetrics = queryData->textRenderer->layoutAttributes()->textMetricsValues(); unsigned textMetricsOffset = fragment.metricsListOffset; unsigned fragmentOffset = 0; while (fragmentOffset < fragment.length) { calculateGlyphBoundaries(queryData, fragment, fragmentOffset, extent); if (extent.contains(data->position)) { // Compute the character offset of the glyph within the text box // and add to processedCharacters. unsigned characterOffset = fragment.characterOffset + fragmentOffset; data->processedCharacters += characterOffset - data->textBox->start(); return true; } fragmentOffset += textMetrics[textMetricsOffset].length(); textMetricsOffset++; } return false; }
bool SVGTextQuery::extentOfCharacterCallback(Data* queryData, const SVGTextFragment& fragment) const { ExtentOfCharacterData* data = static_cast<ExtentOfCharacterData*>(queryData); int startPosition = data->position; int endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) return false; calculateGlyphBoundaries(queryData, fragment, startPosition, data->extent); return true; }
bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGTextFragment& fragment) const { CharacterNumberAtPositionData* data = static_cast<CharacterNumberAtPositionData*>(queryData); FloatRect extent; for (unsigned i = 0; i < fragment.length; ++i) { int startPosition = data->processedCharacters + i; int endPosition = startPosition + 1; if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) continue; calculateGlyphBoundaries(queryData, fragment, startPosition, extent); if (extent.contains(data->position)) { data->processedCharacters += i; return true; } } return false; }