Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker::MarkerType markerType) { Vector<IntRect> result; if (!possiblyHasMarkers(markerType)) return result; ASSERT(!(m_markers.isEmpty())); // outer loop: process each node MarkerMap::iterator end = m_markers.end(); for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) { // inner loop; process each marker in this node MarkerLists* markers = nodeIterator->value.get(); for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) { OwnPtr<MarkerList>& list = (*markers)[markerListIndex]; if (!list || list->isEmpty() || (*list->begin())->type() != markerType) continue; for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) { RenderedDocumentMarker* marker = list->at(markerIndex).get(); if (!marker->isRendered()) continue; result.append(marker->renderedRect()); } } } return result; }
static void updateRenderedRectsForMarker(RenderedDocumentMarker& marker, Node& node) { ASSERT(!node.document().view() || !node.document().view()->needsLayout()); // FIXME: We should refactor this so that we don't use Range (because we only have one Node), but still share code with absoluteTextQuads(). RefPtr<Range> markerRange = Range::create(node.document(), &node, marker.startOffset(), &node, marker.endOffset()); if (!markerRange) return; Vector<FloatQuad> absoluteMarkerQuads; markerRange->absoluteTextQuads(absoluteMarkerQuads, true); Vector<FloatRect> absoluteMarkerRects; absoluteMarkerRects.reserveInitialCapacity(absoluteMarkerQuads.size()); for (const auto& quad : absoluteMarkerQuads) absoluteMarkerRects.append(quad.boundingBox()); marker.setUnclippedAbsoluteRects(absoluteMarkerRects); }
DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType) { if (!possiblyHasMarkers(markerType)) return 0; ASSERT(!(m_markers.isEmpty())); // outer loop: process each node that contains any markers MarkerMap::iterator end = m_markers.end(); for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) { // inner loop; process each marker in this node MarkerLists* markers = nodeIterator->value.get(); OwnPtr<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)]; unsigned markerCount = list.get() ? list->size() : 0; for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) { RenderedDocumentMarker* marker = list->at(markerIndex).get(); if (marker->contains(point)) return marker; } } return 0; }
unsigned TouchEventHandler::spellCheck(Platform::TouchPoint& touchPoint) { Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); if (!m_lastFatFingersResult.isTextInput() || !elementUnderFatFinger) return 0; LayoutPoint contentPos(m_webPage->mapFromViewportToContents(touchPoint.m_pos)); contentPos = DOMSupport::convertPointToFrame(m_webPage->mainFrame(), m_webPage->focusedOrMainFrame(), contentPos); Document* document = elementUnderFatFinger->document(); ASSERT(document); RenderedDocumentMarker* marker = document->markers()->renderedMarkerContainingPoint(contentPos, DocumentMarker::Spelling); if (!marker) return 0; IntRect rect = marker->renderedRect(); LayoutPoint newContentPos = LayoutPoint(rect.x() + rect.width(), rect.y() + rect.height() / 2); Frame* frame = m_webPage->focusedOrMainFrame(); if (frame != m_webPage->mainFrame()) newContentPos = m_webPage->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(newContentPos)); m_lastFatFingersResult.m_adjustedPosition = newContentPos; m_lastFatFingersResult.m_positionWasAdjusted = true; return marker->endOffset() - marker->startOffset(); }