Skip to content

Commit

Permalink
[UnifiedPDF] Describe selection rects in terms of PDFPageCoverage
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=274139
rdar://128043619

Reviewed by Abrar Rahman Protyasha.

Replace `UnifiedPDFPlugin::boundsForSelection()` with `UnifiedPDFPlugin::pageCoverageForSelection()`
which returns a `PDFPageCoverage`, which will be useful in future when we need to have per-page
selection bounds info.

`UnifiedPDFPlugin::textIndicatorForSelection()` can use this, asking for only the first page.
`UnifiedPDFPlugin::selectionBoundsForFirstPageInDocumentSpace()` can be removed.

* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.h:
* Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.mm:
(WebKit::UnifiedPDFPlugin::pageCoverageForSelection const):
(WebKit::UnifiedPDFPlugin::boundsForSelection const):
(WebKit::UnifiedPDFPlugin::repaintOnSelectionActiveStateChangeIfNeeded):
(WebKit::UnifiedPDFPlugin::setCurrentSelection):
(WebKit::UnifiedPDFPlugin::textIndicatorForSelection):
(WebKit::UnifiedPDFPlugin::selectionBoundsForFirstPageInDocumentSpace const): Deleted.

Canonical link: https://commits.webkit.org/278759@main
  • Loading branch information
smfr committed May 14, 2024
1 parent 1fdc4a1 commit 5d5ae59
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ class UnifiedPDFPlugin final : public PDFPluginBase, public WebCore::GraphicsLay
Plugin
};

Vector<WebCore::FloatRect> boundsForSelection(const PDFSelection *, CoordinateSpace inSpace) const;

RetainPtr<PDFPage> pageAtIndex(PDFDocumentLayout::PageIndex) const;

void setPDFDisplayModeForTesting(const String&) final;
Expand Down Expand Up @@ -391,8 +389,14 @@ class UnifiedPDFPlugin final : public PDFPluginBase, public WebCore::GraphicsLay

RefPtr<WebCore::TextIndicator> textIndicatorForCurrentSelection(OptionSet<WebCore::TextIndicatorOption>, WebCore::TextIndicatorPresentationTransition) final;
RefPtr<WebCore::TextIndicator> textIndicatorForSelection(PDFSelection *, OptionSet<WebCore::TextIndicatorOption>, WebCore::TextIndicatorPresentationTransition);

bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override;
std::optional<WebCore::FloatRect> selectionBoundsForFirstPageInDocumentSpace(const RetainPtr<PDFSelection>&) const;

enum class FirstPageOnly : bool { No, Yes };
PDFPageCoverage pageCoverageForSelection(PDFSelection *, FirstPageOnly = FirstPageOnly::No) const;

Vector<WebCore::FloatRect> boundsForSelection(PDFSelection *, CoordinateSpace) const;

bool showDefinitionForSelection(PDFSelection *);
std::pair<String, RetainPtr<PDFSelection>> textForImmediateActionHitTestAtPoint(const WebCore::FloatPoint&, WebHitTestResultData&) override;
WebCore::DictionaryPopupInfo dictionaryPopupInfoForSelection(PDFSelection *, WebCore::TextIndicatorPresentationTransition) override;
Expand Down
60 changes: 32 additions & 28 deletions Source/WebKit/WebProcess/Plugins/PDF/UnifiedPDF/UnifiedPDFPlugin.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3284,17 +3284,39 @@ static FloatRect computeMarqueeSelectionRect(const WebCore::FloatPoint& point1,
unfreezeCursorAfterSelectionDragIfNeeded();
}

Vector<FloatRect> UnifiedPDFPlugin::boundsForSelection(const PDFSelection *selection, CoordinateSpace inSpace) const
PDFPageCoverage UnifiedPDFPlugin::pageCoverageForSelection(PDFSelection *selection, FirstPageOnly firstPageOnly) const
{
if (!selection || [selection isEmpty])
return { };

return makeVector([selection pages], [this, selection, inSpace](PDFPage *page) -> std::optional<FloatRect> {
auto pageCoverage = PDFPageCoverage { };

for (PDFPage *page in [selection pages]) {
auto pageIndex = m_documentLayout.indexForPage(page);
if (!pageIndex)
return { };
return convertUp(CoordinateSpace::PDFPage, inSpace, FloatRect { [selection boundsForPage:page] }, *pageIndex);
});
continue;

pageCoverage.append({ *pageIndex, FloatRect { [selection boundsForPage:page] } });
if (firstPageOnly == FirstPageOnly::Yes)
break;
}

return pageCoverage;
}

Vector<FloatRect> UnifiedPDFPlugin::boundsForSelection(PDFSelection *selection, CoordinateSpace targetSpace) const
{
auto pageCoverage = pageCoverageForSelection(selection);
if (pageCoverage.isEmpty())
return { };

Vector<FloatRect> pageRects;
pageRects.reserveInitialCapacity(pageCoverage.size());

for (auto& page : pageCoverage)
pageRects.append(convertUp(CoordinateSpace::PDFPage, targetSpace, page.pageBounds, page.pageIndex));

return pageRects;
}

void UnifiedPDFPlugin::repaintOnSelectionActiveStateChangeIfNeeded(ActiveStateChangeReason reason, const Vector<FloatRect>& additionalDocumentRectsToRepaint)
Expand All @@ -3312,7 +3334,6 @@ static FloatRect computeMarqueeSelectionRect(const WebCore::FloatPoint& point1,

auto selectionDocumentRectsToRepaint = boundsForSelection(protectedCurrentSelection().get(), CoordinateSpace::PDFDocumentLayout);
selectionDocumentRectsToRepaint.appendVector(additionalDocumentRectsToRepaint);

setNeedsRepaintInDocumentRects(RepaintRequirement::Selection, selectionDocumentRectsToRepaint);
}

Expand All @@ -3323,12 +3344,12 @@ static FloatRect computeMarqueeSelectionRect(const WebCore::FloatPoint& point1,

void UnifiedPDFPlugin::setCurrentSelection(RetainPtr<PDFSelection>&& selection)
{
auto staleSelectionDocumentRectsToRepaint = boundsForSelection(protectedCurrentSelection().get(), CoordinateSpace::PDFDocumentLayout);
auto previousSelectionDocumentRectsToRepaint = boundsForSelection(protectedCurrentSelection().get(), CoordinateSpace::PDFDocumentLayout);

m_currentSelection = WTFMove(selection);
// FIXME: <https://webkit.org/b/268980> Selection painting requests should be only be made if the current selection has changed.
// FIXME: <https://webkit.org/b/270070> Selection painting should be optimized by only repainting diff between old and new selection.
repaintOnSelectionActiveStateChangeIfNeeded(ActiveStateChangeReason::SetCurrentSelection, staleSelectionDocumentRectsToRepaint);
repaintOnSelectionActiveStateChangeIfNeeded(ActiveStateChangeReason::SetCurrentSelection, previousSelectionDocumentRectsToRepaint);
notifySelectionChanged();
}

Expand Down Expand Up @@ -3574,12 +3595,11 @@ static NSStringCompareOptions compareOptionsForFindOptions(WebCore::FindOptions

RefPtr<TextIndicator> UnifiedPDFPlugin::textIndicatorForSelection(PDFSelection *selection, OptionSet<WebCore::TextIndicatorOption> options, WebCore::TextIndicatorPresentationTransition transition)
{
auto selectionBounds = selectionBoundsForFirstPageInDocumentSpace(selection);
if (!selectionBounds)
auto selectionPageCoverage = pageCoverageForSelection(selection, FirstPageOnly::Yes);
if (selectionPageCoverage.isEmpty())
return nullptr;

auto rectInDocumentCoordinates = *selectionBounds;
auto rectInContentsCoordinates = convertUp(CoordinateSpace::PDFDocumentLayout, CoordinateSpace::Contents, rectInDocumentCoordinates);
auto rectInContentsCoordinates = convertUp(CoordinateSpace::PDFPage, CoordinateSpace::Contents, selectionPageCoverage[0].pageBounds, selectionPageCoverage[0].pageIndex);
auto rectInPluginCoordinates = convertUp(CoordinateSpace::Contents, CoordinateSpace::Plugin, rectInContentsCoordinates);
auto rectInRootViewCoordinates = convertFromPluginToRootView(enclosingIntRect(rectInPluginCoordinates));

Expand Down Expand Up @@ -3636,22 +3656,6 @@ static NSStringCompareOptions compareOptionsForFindOptions(WebCore::FindOptions
return showDefinitionForSelection(lookupSelection.get());
}

std::optional<FloatRect> UnifiedPDFPlugin::selectionBoundsForFirstPageInDocumentSpace(const RetainPtr<PDFSelection>& selection) const
{
if (!selection)
return { };

for (PDFPage *page in [selection pages]) {
auto pageIndex = m_documentLayout.indexForPage(page);
if (!pageIndex)
continue;
auto rectForPage = FloatRect { [selection boundsForPage:page] };
return convertUp(CoordinateSpace::PDFPage, CoordinateSpace::PDFDocumentLayout, rectForPage, *pageIndex);
}

return { };
}

WebCore::DictionaryPopupInfo UnifiedPDFPlugin::dictionaryPopupInfoForSelection(PDFSelection *selection, WebCore::TextIndicatorPresentationTransition transition)
{
DictionaryPopupInfo dictionaryPopupInfo = PDFPluginBase::dictionaryPopupInfoForSelection(selection, transition);
Expand Down

0 comments on commit 5d5ae59

Please sign in to comment.