1 | /* |
2 | * Copyright (C) 2010 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include "FloatRect.h" |
29 | #include "Image.h" |
30 | #include <wtf/RefCounted.h> |
31 | #include <wtf/Vector.h> |
32 | |
33 | namespace WebCore { |
34 | |
35 | class Frame; |
36 | class GraphicsContext; |
37 | class Range; |
38 | |
39 | // FIXME: Move PresentationTransition to TextIndicatorWindow, because it's about presentation. |
40 | enum class TextIndicatorPresentationTransition : uint8_t { |
41 | None, |
42 | |
43 | // These animations drive themselves. |
44 | Bounce, |
45 | BounceAndCrossfade, |
46 | |
47 | // This animation needs to be driven manually via TextIndicatorWindow::setAnimationProgress. |
48 | FadeIn, |
49 | }; |
50 | |
51 | // Make sure to keep these in sync with the ones in Internals.idl. |
52 | enum TextIndicatorOption : uint16_t { |
53 | TextIndicatorOptionDefault = 0, |
54 | |
55 | // Use the styled text color instead of forcing black text (the default) |
56 | TextIndicatorOptionRespectTextColor = 1 << 0, |
57 | |
58 | // Paint backgrounds, even if they're not part of the Range |
59 | TextIndicatorOptionPaintBackgrounds = 1 << 1, |
60 | |
61 | // Don't restrict painting to the given Range |
62 | TextIndicatorOptionPaintAllContent = 1 << 2, |
63 | |
64 | // Take two snapshots: |
65 | // - one including the selection highlight and ignoring other painting-related options |
66 | // - one respecting the other painting-related options |
67 | TextIndicatorOptionIncludeSnapshotWithSelectionHighlight = 1 << 3, |
68 | |
69 | // Tightly fit the content instead of expanding to cover the bounds of the selection highlight |
70 | TextIndicatorOptionTightlyFitContent = 1 << 4, |
71 | |
72 | // If there are any non-inline or replaced elements in the Range, indicate the bounding rect |
73 | // of the range instead of the individual subrects, and don't restrict painting to the given Range |
74 | TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges = 1 << 5, |
75 | |
76 | // By default, TextIndicator removes any margin if the given Range matches the |
77 | // selection Range. If this option is set, maintain the margin in any case. |
78 | TextIndicatorOptionIncludeMarginIfRangeMatchesSelection = 1 << 6, |
79 | |
80 | // By default, TextIndicator clips the indicated rects to the visible content rect. |
81 | // If this option is set, expand the clip rect outward so that slightly offscreen content will be included. |
82 | TextIndicatorOptionExpandClipBeyondVisibleRect = 1 << 7, |
83 | |
84 | // By default, TextIndicator clips the indicated rects to the visible content rect. |
85 | // If this option is set, do not clip to the visible rect. |
86 | TextIndicatorOptionDoNotClipToVisibleRect = 1 << 8, |
87 | |
88 | // Include an additional snapshot of everything in view, with the exception of nodes within the currently selected range. |
89 | TextIndicatorOptionIncludeSnapshotOfAllVisibleContentWithoutSelection = 1 << 9, |
90 | |
91 | // By default, TextIndicator uses text rects to size the snapshot. Enabling this flag causes it to use the bounds of the |
92 | // selection rects that would enclose the given Range instead. |
93 | // Currently, this is only supported on iOS. |
94 | TextIndicatorOptionUseSelectionRectForSizing = 1 << 10, |
95 | |
96 | // Compute a background color to use when rendering a platter around the content image, falling back to a default if the |
97 | // content's background is too complex to be captured by a single color. |
98 | TextIndicatorOptionComputeEstimatedBackgroundColor = 1 << 11, |
99 | }; |
100 | typedef uint16_t TextIndicatorOptions; |
101 | |
102 | struct TextIndicatorData { |
103 | FloatRect selectionRectInRootViewCoordinates; |
104 | FloatRect textBoundingRectInRootViewCoordinates; |
105 | FloatRect contentImageWithoutSelectionRectInRootViewCoordinates; |
106 | Vector<FloatRect> textRectsInBoundingRectCoordinates; |
107 | float contentImageScaleFactor; |
108 | RefPtr<Image> contentImageWithHighlight; |
109 | RefPtr<Image> contentImageWithoutSelection; |
110 | RefPtr<Image> contentImage; |
111 | Color estimatedBackgroundColor; |
112 | TextIndicatorPresentationTransition presentationTransition; |
113 | TextIndicatorOptions options; |
114 | }; |
115 | |
116 | class TextIndicator : public RefCounted<TextIndicator> { |
117 | public: |
118 | // FIXME: These are fairly Mac-specific, and they don't really belong here. |
119 | // But they're needed at TextIndicator creation time, so they can't go in TextIndicatorWindow. |
120 | // Maybe they can live in some Theme code somewhere? |
121 | constexpr static float defaultHorizontalMargin { 2 }; |
122 | constexpr static float defaultVerticalMargin { 1 }; |
123 | |
124 | WEBCORE_EXPORT static Ref<TextIndicator> create(const TextIndicatorData&); |
125 | WEBCORE_EXPORT static RefPtr<TextIndicator> createWithSelectionInFrame(Frame&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin)); |
126 | WEBCORE_EXPORT static RefPtr<TextIndicator> createWithRange(const Range&, TextIndicatorOptions, TextIndicatorPresentationTransition, FloatSize margin = FloatSize(defaultHorizontalMargin, defaultVerticalMargin)); |
127 | |
128 | WEBCORE_EXPORT ~TextIndicator(); |
129 | |
130 | FloatRect selectionRectInRootViewCoordinates() const { return m_data.selectionRectInRootViewCoordinates; } |
131 | FloatRect textBoundingRectInRootViewCoordinates() const { return m_data.textBoundingRectInRootViewCoordinates; } |
132 | const Vector<FloatRect>& textRectsInBoundingRectCoordinates() const { return m_data.textRectsInBoundingRectCoordinates; } |
133 | float contentImageScaleFactor() const { return m_data.contentImageScaleFactor; } |
134 | Image* contentImageWithHighlight() const { return m_data.contentImageWithHighlight.get(); } |
135 | Image* contentImage() const { return m_data.contentImage.get(); } |
136 | |
137 | TextIndicatorPresentationTransition presentationTransition() const { return m_data.presentationTransition; } |
138 | void setPresentationTransition(TextIndicatorPresentationTransition transition) { m_data.presentationTransition = transition; } |
139 | |
140 | TextIndicatorData data() const { return m_data; } |
141 | |
142 | private: |
143 | TextIndicator(const TextIndicatorData&); |
144 | |
145 | TextIndicatorData m_data; |
146 | }; |
147 | |
148 | } // namespace WebKit |
149 | |