Пример #1
0
static RefPtr<Image> takeSnapshot(Frame& frame, IntRect rect, SnapshotOptions options, float& scaleFactor)
{
    std::unique_ptr<ImageBuffer> buffer = snapshotFrameRect(frame, rect, options);
    if (!buffer)
        return nullptr;
    scaleFactor = buffer->resolutionScale();
    return buffer->copyImage(CopyBackingStore, Unscaled);
}
Пример #2
0
std::unique_ptr<ImageBuffer> snapshotSelection(Frame& frame, SnapshotOptions options)
{
    if (!frame.selection().isRange())
        return nullptr;

    options |= SnapshotOptionsPaintSelectionOnly;
    return snapshotFrameRect(frame, enclosingIntRect(frame.selection().bounds()), options);
}
Пример #3
0
std::unique_ptr<ImageBuffer> snapshotNode(Frame& frame, Node& node)
{
    if (!node.renderer())
        return nullptr;

    ScopedFramePaintingState state(frame, &node);

    frame.view()->setBaseBackgroundColor(Color::transparent);
    frame.view()->setNodeToDraw(&node);

    LayoutRect topLevelRect;
    return snapshotFrameRect(frame, snappedIntRect(node.renderer()->paintingRootRect(topLevelRect)));
}
Пример #4
0
std::unique_ptr<ImageBuffer> snapshotSelection(Frame& frame, SnapshotOptions options)
{
    auto& selection = frame.selection();

    if (!selection.isRange())
        return nullptr;

    FloatRect selectionBounds = selection.selectionBounds();

    // It is possible for the selection bounds to be empty; see https://bugs.webkit.org/show_bug.cgi?id=56645.
    if (selectionBounds.isEmpty())
        return nullptr;

    options |= SnapshotOptionsPaintSelectionOnly;
    return snapshotFrameRect(frame, enclosingIntRect(selectionBounds), options);
}
Пример #5
0
// FIXME (138889): Ideally the FrameSnapshotting functions would be more flexible
// and we wouldn't have to implement this here.
static RefPtr<Image> snapshotSelectionWithHighlight(Frame& frame)
{
    auto& selection = frame.selection();

    if (!selection.isRange())
        return nullptr;

    FloatRect selectionBounds = selection.selectionBounds();

    // It is possible for the selection bounds to be empty; see https://bugs.webkit.org/show_bug.cgi?id=56645.
    if (selectionBounds.isEmpty())
        return nullptr;

    std::unique_ptr<ImageBuffer> snapshot = snapshotFrameRect(frame, enclosingIntRect(selectionBounds), 0);

    if (!snapshot)
        return nullptr;

    return snapshot->copyImage(CopyBackingStore, Unscaled);
}
Пример #6
0
RefPtr<TextIndicator> TextIndicator::createWithSelectionInFrame(Frame& frame, TextIndicatorPresentationTransition presentationTransition, unsigned margin)
{
    Vector<FloatRect> textRects;

    // On iOS, we don't need to expand the TextIndicator to cover the whole selection height.
    // FIXME: Ideally, on Mac, there are times when we don't need to (if we don't have a selection),
    // and using TextHeight would provide a more sensible appearance.
#if PLATFORM(IOS)
    FrameSelection::TextRectangleHeight textRectHeight = FrameSelection::TextRectangleHeight::TextHeight;
#else
    FrameSelection::TextRectangleHeight textRectHeight = FrameSelection::TextRectangleHeight::SelectionHeight;
#endif
    frame.selection().getClippedVisibleTextRectangles(textRects, textRectHeight);

    // The bounding rect of all the text rects can be different than the selection
    // rect when the selection spans multiple lines; the indicator doesn't actually
    // care where the selection highlight goes, just where the text actually is.
    FloatRect textBoundingRectInRootViewCoordinates;
    FloatRect textBoundingRectInDocumentCoordinates;
    Vector<FloatRect> textRectsInRootViewCoordinates;
    for (const FloatRect& textRect : textRects) {
        FloatRect textRectInDocumentCoordinatesIncludingMargin = textRect;
        textRectInDocumentCoordinatesIncludingMargin.inflate(margin);

        textBoundingRectInDocumentCoordinates.unite(textRectInDocumentCoordinatesIncludingMargin);

        FloatRect textRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(textRectInDocumentCoordinatesIncludingMargin));
        textRectsInRootViewCoordinates.append(textRectInRootViewCoordinates);
        textBoundingRectInRootViewCoordinates.unite(textRectInRootViewCoordinates);
    }

    Vector<FloatRect> textRectsInBoundingRectCoordinates;
    for (auto rect : textRectsInRootViewCoordinates) {
        rect.moveBy(-textBoundingRectInRootViewCoordinates.location());
        textRectsInBoundingRectCoordinates.append(rect);
    }

    // FIXME: We should have TextIndicator options instead of this being platform-specific.
#if PLATFORM(IOS)
    SnapshotOptions snapshotOptions = SnapshotOptionsPaintSelectionAndBackgroundsOnly;
#else
    SnapshotOptions snapshotOptions = SnapshotOptionsForceBlackText | SnapshotOptionsPaintSelectionOnly;
#endif

    std::unique_ptr<ImageBuffer> indicatorBuffer = snapshotFrameRect(frame, enclosingIntRect(textBoundingRectInDocumentCoordinates), snapshotOptions);
    if (!indicatorBuffer)
        return nullptr;
    RefPtr<Image> indicatorBitmap = indicatorBuffer->copyImage(CopyBackingStore, Unscaled);
    if (!indicatorBitmap)
        return nullptr;

    RefPtr<Image> indicatorBitmapWithHighlight;
    if (presentationTransition == TextIndicatorPresentationTransition::BounceAndCrossfade)
        indicatorBitmapWithHighlight = snapshotSelectionWithHighlight(frame);

    TextIndicatorData data;

    // Store the selection rect in window coordinates, to be used subsequently
    // to determine if the indicator and selection still precisely overlap.
    data.selectionRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(frame.selection().selectionBounds()));
    data.textBoundingRectInRootViewCoordinates = textBoundingRectInRootViewCoordinates;
    data.textRectsInBoundingRectCoordinates = textRectsInBoundingRectCoordinates;
    data.contentImageScaleFactor = indicatorBuffer->resolutionScale();
    data.contentImage = indicatorBitmap;
    data.contentImageWithHighlight = indicatorBitmapWithHighlight;
    data.presentationTransition = presentationTransition;
    data.wantsMargin = true;

    return TextIndicator::create(data);
}