| 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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 452 struct ExtentOfCharacterData : QueryData { | 452 struct ExtentOfCharacterData : QueryData { | 
| 453     ExtentOfCharacterData(unsigned queryPosition) | 453     ExtentOfCharacterData(unsigned queryPosition) | 
| 454         : position(queryPosition) | 454         : position(queryPosition) | 
| 455     { | 455     { | 
| 456     } | 456     } | 
| 457 | 457 | 
| 458     unsigned position; | 458     unsigned position; | 
| 459     FloatRect extent; | 459     FloatRect extent; | 
| 460 }; | 460 }; | 
| 461 | 461 | 
| 462 static inline void calculateGlyphBoundaries(const QueryData* queryData, const SV
     GTextFragment& fragment, int startPosition, FloatRect& extent) | 462 static inline FloatRect calculateGlyphBoundaries(const QueryData* queryData, con
     st SVGTextFragment& fragment, int startPosition) | 
| 463 { | 463 { | 
| 464     float scalingFactor = queryData->textLineLayout.scalingFactor(); | 464     float scalingFactor = queryData->textLineLayout.scalingFactor(); | 
| 465     ASSERT(scalingFactor); | 465     ASSERT(scalingFactor); | 
| 466 | 466 | 
| 467     FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData,
      fragment, startPosition); | 467     FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData,
      fragment, startPosition); | 
| 468     glyphPosition.move(0, -queryData->textLineLayout.scaledFont().getFontMetrics
     ().floatAscent() / scalingFactor); | 468     glyphPosition.move(0, -queryData->textLineLayout.scaledFont().getFontMetrics
     ().floatAscent() / scalingFactor); | 
| 469     extent.setLocation(glyphPosition); |  | 
| 470 | 469 | 
| 471     // Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends | 470     // Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends | 
| 472     // time attempting to compute more correct glyph bounds already, handling | 471     // time attempting to compute more correct glyph bounds already, handling | 
| 473     // cursive scripts to some degree.) | 472     // cursive scripts to some degree.) | 
| 474     const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLineLayout.
     layoutAttributes()->textMetricsValues(); | 473     const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLineLayout.
     layoutAttributes()->textMetricsValues(); | 
| 475     const SVGTextMetrics& metrics = findMetricsForCharacter(textMetricsValues, f
     ragment, startPosition); | 474     const SVGTextMetrics& metrics = findMetricsForCharacter(textMetricsValues, f
     ragment, startPosition); | 
| 476 | 475 | 
| 477     // TODO(fs): Negative glyph extents seems kind of weird to have, but | 476     // TODO(fs): Negative glyph extents seems kind of weird to have, but | 
| 478     // presently it can occur in some cases (like Arabic.) | 477     // presently it can occur in some cases (like Arabic.) | 
| 479     FloatSize glyphSize(std::max<float>(metrics.width(), 0), std::max<float>(met
     rics.height(), 0)); | 478     FloatSize glyphSize(std::max<float>(metrics.width(), 0), std::max<float>(met
     rics.height(), 0)); | 
| 480     extent.setSize(glyphSize); |  | 
| 481 | 479 | 
| 482     // If RTL, adjust the starting point to align with the LHS of the glyph boun
     ding box. | 480     // If RTL, adjust the starting point to align with the LHS of the glyph boun
     ding box. | 
| 483     if (!queryData->textBox->isLeftToRightDirection()) { | 481     if (!queryData->textBox->isLeftToRightDirection()) { | 
| 484         if (queryData->isVerticalText) | 482         if (queryData->isVerticalText) | 
| 485             extent.move(0, -glyphSize.height()); | 483             glyphPosition.move(0, -glyphSize.height()); | 
| 486         else | 484         else | 
| 487             extent.move(-glyphSize.width(), 0); | 485             glyphPosition.move(-glyphSize.width(), 0); | 
| 488     } | 486     } | 
| 489 | 487 | 
|  | 488     FloatRect extent(glyphPosition, glyphSize); | 
| 490     if (fragment.isTransformed()) { | 489     if (fragment.isTransformed()) { | 
| 491         AffineTransform fragmentTransform = fragment.buildFragmentTransform(SVGT
     extFragment::TransformIgnoringTextLength); | 490         AffineTransform fragmentTransform = fragment.buildFragmentTransform(SVGT
     extFragment::TransformIgnoringTextLength); | 
| 492         extent = fragmentTransform.mapRect(extent); | 491         extent = fragmentTransform.mapRect(extent); | 
| 493     } | 492     } | 
|  | 493     return extent; | 
| 494 } | 494 } | 
| 495 | 495 | 
| 496 static inline FloatRect calculateFragmentBoundaries(LineLayoutSVGInlineText text
     LineLayout, const SVGTextFragment& fragment) | 496 static inline FloatRect calculateFragmentBoundaries(LineLayoutSVGInlineText text
     LineLayout, const SVGTextFragment& fragment) | 
| 497 { | 497 { | 
| 498     float scalingFactor = textLineLayout.scalingFactor(); | 498     float scalingFactor = textLineLayout.scalingFactor(); | 
| 499     ASSERT(scalingFactor); | 499     ASSERT(scalingFactor); | 
| 500     float baseline = textLineLayout.scaledFont().getFontMetrics().floatAscent() 
     / scalingFactor; | 500     float baseline = textLineLayout.scaledFont().getFontMetrics().floatAscent() 
     / scalingFactor; | 
| 501     return fragment.boundingBox(baseline); | 501     return fragment.boundingBox(baseline); | 
| 502 } | 502 } | 
| 503 | 503 | 
| 504 static bool extentOfCharacterCallback(QueryData* queryData, const SVGTextFragmen
     t& fragment) | 504 static bool extentOfCharacterCallback(QueryData* queryData, const SVGTextFragmen
     t& fragment) | 
| 505 { | 505 { | 
| 506     ExtentOfCharacterData* data = static_cast<ExtentOfCharacterData*>(queryData)
     ; | 506     ExtentOfCharacterData* data = static_cast<ExtentOfCharacterData*>(queryData)
     ; | 
| 507 | 507 | 
| 508     int startPosition = data->position; | 508     int startPosition = data->position; | 
| 509     int endPosition = startPosition + 1; | 509     int endPosition = startPosition + 1; | 
| 510     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startP
     osition, endPosition)) | 510     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startP
     osition, endPosition)) | 
| 511         return false; | 511         return false; | 
| 512 | 512 | 
| 513     calculateGlyphBoundaries(queryData, fragment, startPosition, data->extent); | 513     data->extent = calculateGlyphBoundaries(queryData, fragment, startPosition); | 
| 514     return true; | 514     return true; | 
| 515 } | 515 } | 
| 516 | 516 | 
| 517 FloatRect SVGTextQuery::extentOfCharacter(unsigned position) const | 517 FloatRect SVGTextQuery::extentOfCharacter(unsigned position) const | 
| 518 { | 518 { | 
| 519     ExtentOfCharacterData data(position); | 519     ExtentOfCharacterData data(position); | 
| 520     logicalQuery(m_queryRootLayoutObject, &data, extentOfCharacterCallback); | 520     logicalQuery(m_queryRootLayoutObject, &data, extentOfCharacterCallback); | 
| 521     return data.extent; | 521     return data.extent; | 
| 522 } | 522 } | 
| 523 | 523 | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 578 { | 578 { | 
| 579     CharacterNumberAtPositionData* data = static_cast<CharacterNumberAtPositionD
     ata*>(queryData); | 579     CharacterNumberAtPositionData* data = static_cast<CharacterNumberAtPositionD
     ata*>(queryData); | 
| 580 | 580 | 
| 581     // Test the query point against the bounds of the entire fragment first. | 581     // Test the query point against the bounds of the entire fragment first. | 
| 582     FloatRect fragmentExtents = calculateFragmentBoundaries(queryData->textLineL
     ayout, fragment); | 582     FloatRect fragmentExtents = calculateFragmentBoundaries(queryData->textLineL
     ayout, fragment); | 
| 583     if (!fragmentExtents.contains(data->position)) | 583     if (!fragmentExtents.contains(data->position)) | 
| 584         return false; | 584         return false; | 
| 585 | 585 | 
| 586     // Iterate through the glyphs in this fragment, and check if their extents | 586     // Iterate through the glyphs in this fragment, and check if their extents | 
| 587     // contain the query point. | 587     // contain the query point. | 
| 588     FloatRect extent; |  | 
| 589     const Vector<SVGTextMetrics>& textMetrics = queryData->textLineLayout.layout
     Attributes()->textMetricsValues(); | 588     const Vector<SVGTextMetrics>& textMetrics = queryData->textLineLayout.layout
     Attributes()->textMetricsValues(); | 
| 590     unsigned textMetricsOffset = fragment.metricsListOffset; | 589     unsigned textMetricsOffset = fragment.metricsListOffset; | 
| 591     unsigned fragmentOffset = 0; | 590     unsigned fragmentOffset = 0; | 
| 592     while (fragmentOffset < fragment.length) { | 591     while (fragmentOffset < fragment.length) { | 
| 593         calculateGlyphBoundaries(queryData, fragment, fragmentOffset, extent); | 592         FloatRect extent = calculateGlyphBoundaries(queryData, fragment, fragmen
     tOffset); | 
| 594         if (extent.contains(data->position)) { | 593         if (extent.contains(data->position)) { | 
| 595             // Compute the character offset of the glyph within the text node. | 594             // Compute the character offset of the glyph within the text node. | 
| 596             unsigned offsetInBox = fragment.characterOffset - queryData->textBox
     ->start() + fragmentOffset; | 595             unsigned offsetInBox = fragment.characterOffset - queryData->textBox
     ->start() + fragmentOffset; | 
| 597             data->offsetInTextNode = logicalOffsetInTextNode(queryData->textLine
     Layout, queryData->textBox, offsetInBox); | 596             data->offsetInTextNode = logicalOffsetInTextNode(queryData->textLine
     Layout, queryData->textBox, offsetInBox); | 
| 598             data->hitLayoutItem = LineLayoutItem(data->textLineLayout); | 597             data->hitLayoutItem = LineLayoutItem(data->textLineLayout); | 
| 599             return true; | 598             return true; | 
| 600         } | 599         } | 
| 601         fragmentOffset += textMetrics[textMetricsOffset].length(); | 600         fragmentOffset += textMetrics[textMetricsOffset].length(); | 
| 602         textMetricsOffset++; | 601         textMetricsOffset++; | 
| 603     } | 602     } | 
| 604     return false; | 603     return false; | 
| 605 } | 604 } | 
| 606 | 605 | 
| 607 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const | 606 int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const | 
| 608 { | 607 { | 
| 609     CharacterNumberAtPositionData data(position); | 608     CharacterNumberAtPositionData data(position); | 
| 610     spatialQuery(m_queryRootLayoutObject, &data, characterNumberAtPositionCallba
     ck); | 609     spatialQuery(m_queryRootLayoutObject, &data, characterNumberAtPositionCallba
     ck); | 
| 611     return data.characterNumberWithin(m_queryRootLayoutObject); | 610     return data.characterNumberWithin(m_queryRootLayoutObject); | 
| 612 } | 611 } | 
| 613 | 612 | 
| 614 } // namespace blink | 613 } // namespace blink | 
| OLD | NEW | 
|---|