|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "inFlasher.h" |
|
6 #include "inLayoutUtils.h" |
|
7 |
|
8 #include "nsIDOMElement.h" |
|
9 #include "nsIServiceManager.h" |
|
10 #include "nsIPresShell.h" |
|
11 #include "nsIFrame.h" |
|
12 #include "nsIWidget.h" |
|
13 #include "nsReadableUtils.h" |
|
14 #include "nsRenderingContext.h" |
|
15 #include "nsIDOMWindow.h" |
|
16 #include "nsIContent.h" |
|
17 |
|
18 #include "prprf.h" |
|
19 |
|
20 /////////////////////////////////////////////////////////////////////////////// |
|
21 |
|
22 inFlasher::inFlasher() : |
|
23 mColor(NS_RGB(0,0,0)), |
|
24 mThickness(0), |
|
25 mInvert(false) |
|
26 { |
|
27 } |
|
28 |
|
29 inFlasher::~inFlasher() |
|
30 { |
|
31 } |
|
32 |
|
33 NS_IMPL_ISUPPORTS(inFlasher, inIFlasher) |
|
34 |
|
35 /////////////////////////////////////////////////////////////////////////////// |
|
36 // inIFlasher |
|
37 |
|
38 NS_IMETHODIMP |
|
39 inFlasher::GetColor(nsAString& aColor) |
|
40 { |
|
41 // Copied from nsGenericHTMLElement::ColorToString() |
|
42 char buf[10]; |
|
43 PR_snprintf(buf, sizeof(buf), "#%02x%02x%02x", |
|
44 NS_GET_R(mColor), NS_GET_G(mColor), NS_GET_B(mColor)); |
|
45 CopyASCIItoUTF16(buf, aColor); |
|
46 |
|
47 return NS_OK; |
|
48 } |
|
49 |
|
50 NS_IMETHODIMP |
|
51 inFlasher::SetColor(const nsAString& aColor) |
|
52 { |
|
53 NS_ENSURE_FALSE(aColor.IsEmpty(), NS_ERROR_ILLEGAL_VALUE); |
|
54 |
|
55 nsAutoString colorStr; |
|
56 colorStr.Assign(aColor); |
|
57 |
|
58 if (colorStr.CharAt(0) != '#') { |
|
59 if (NS_ColorNameToRGB(colorStr, &mColor)) { |
|
60 return NS_OK; |
|
61 } |
|
62 } |
|
63 else { |
|
64 colorStr.Cut(0, 1); |
|
65 if (NS_HexToRGB(colorStr, &mColor)) { |
|
66 return NS_OK; |
|
67 } |
|
68 } |
|
69 |
|
70 return NS_ERROR_ILLEGAL_VALUE; |
|
71 } |
|
72 |
|
73 NS_IMETHODIMP |
|
74 inFlasher::GetThickness(uint16_t *aThickness) |
|
75 { |
|
76 NS_PRECONDITION(aThickness, "Null pointer"); |
|
77 *aThickness = mThickness; |
|
78 return NS_OK; |
|
79 } |
|
80 |
|
81 NS_IMETHODIMP |
|
82 inFlasher::SetThickness(uint16_t aThickness) |
|
83 { |
|
84 mThickness = aThickness; |
|
85 return NS_OK; |
|
86 } |
|
87 |
|
88 NS_IMETHODIMP |
|
89 inFlasher::GetInvert(bool *aInvert) |
|
90 { |
|
91 NS_PRECONDITION(aInvert, "Null pointer"); |
|
92 *aInvert = mInvert; |
|
93 return NS_OK; |
|
94 } |
|
95 |
|
96 NS_IMETHODIMP |
|
97 inFlasher::SetInvert(bool aInvert) |
|
98 { |
|
99 mInvert = aInvert; |
|
100 return NS_OK; |
|
101 } |
|
102 |
|
103 NS_IMETHODIMP |
|
104 inFlasher::RepaintElement(nsIDOMElement* aElement) |
|
105 { |
|
106 NS_ENSURE_ARG_POINTER(aElement); |
|
107 nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement); |
|
108 if (!frame) return NS_OK; |
|
109 |
|
110 frame->InvalidateFrame(); |
|
111 |
|
112 return NS_OK; |
|
113 } |
|
114 |
|
115 NS_IMETHODIMP |
|
116 inFlasher::DrawElementOutline(nsIDOMElement* aElement) |
|
117 { |
|
118 NS_ENSURE_ARG_POINTER(aElement); |
|
119 nsCOMPtr<nsIDOMWindow> window = inLayoutUtils::GetWindowFor(aElement); |
|
120 if (!window) return NS_OK; |
|
121 nsCOMPtr<nsIPresShell> presShell = inLayoutUtils::GetPresShellFor(window); |
|
122 if (!presShell) return NS_OK; |
|
123 |
|
124 nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement); |
|
125 |
|
126 bool isFirstFrame = true; |
|
127 |
|
128 while (frame) { |
|
129 nsPoint offset; |
|
130 nsIWidget* widget = frame->GetNearestWidget(offset); |
|
131 if (widget) { |
|
132 nsRefPtr<nsRenderingContext> rcontext = new nsRenderingContext(); |
|
133 rcontext->Init(frame->PresContext()->DeviceContext(), |
|
134 widget->GetThebesSurface()); |
|
135 |
|
136 nsRect rect(offset, frame->GetSize()); |
|
137 if (mInvert) { |
|
138 rcontext->InvertRect(rect); |
|
139 } |
|
140 |
|
141 bool isLastFrame = frame->GetNextContinuation() == nullptr; |
|
142 DrawOutline(rect.x, rect.y, rect.width, rect.height, rcontext, |
|
143 isFirstFrame, isLastFrame); |
|
144 isFirstFrame = false; |
|
145 } |
|
146 frame = frame->GetNextContinuation(); |
|
147 } |
|
148 |
|
149 return NS_OK; |
|
150 } |
|
151 |
|
152 NS_IMETHODIMP |
|
153 inFlasher::ScrollElementIntoView(nsIDOMElement *aElement) |
|
154 { |
|
155 NS_ENSURE_ARG_POINTER(aElement); |
|
156 nsCOMPtr<nsIDOMWindow> window = inLayoutUtils::GetWindowFor(aElement); |
|
157 if (!window) { |
|
158 return NS_OK; |
|
159 } |
|
160 |
|
161 nsCOMPtr<nsIPresShell> presShell = inLayoutUtils::GetPresShellFor(window); |
|
162 if (!presShell) { |
|
163 return NS_OK; |
|
164 } |
|
165 |
|
166 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement); |
|
167 presShell->ScrollContentIntoView(content, |
|
168 nsIPresShell::ScrollAxis(), |
|
169 nsIPresShell::ScrollAxis(), |
|
170 nsIPresShell::SCROLL_OVERFLOW_HIDDEN); |
|
171 |
|
172 return NS_OK; |
|
173 } |
|
174 |
|
175 /////////////////////////////////////////////////////////////////////////////// |
|
176 // inFlasher |
|
177 |
|
178 void |
|
179 inFlasher::DrawOutline(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, |
|
180 nsRenderingContext* aRenderContext, |
|
181 bool aDrawBegin, bool aDrawEnd) |
|
182 { |
|
183 aRenderContext->SetColor(mColor); |
|
184 |
|
185 DrawLine(aX, aY, aWidth, DIR_HORIZONTAL, BOUND_OUTER, aRenderContext); |
|
186 if (aDrawBegin) { |
|
187 DrawLine(aX, aY, aHeight, DIR_VERTICAL, BOUND_OUTER, aRenderContext); |
|
188 } |
|
189 DrawLine(aX, aY+aHeight, aWidth, DIR_HORIZONTAL, BOUND_INNER, aRenderContext); |
|
190 if (aDrawEnd) { |
|
191 DrawLine(aX+aWidth, aY, aHeight, DIR_VERTICAL, BOUND_INNER, aRenderContext); |
|
192 } |
|
193 } |
|
194 |
|
195 void |
|
196 inFlasher::DrawLine(nscoord aX, nscoord aY, nscoord aLength, |
|
197 bool aDir, bool aBounds, |
|
198 nsRenderingContext* aRenderContext) |
|
199 { |
|
200 nscoord thickTwips = nsPresContext::CSSPixelsToAppUnits(mThickness); |
|
201 if (aDir) { // horizontal |
|
202 aRenderContext->FillRect(aX, aY+(aBounds?0:-thickTwips), aLength, thickTwips); |
|
203 } else { // vertical |
|
204 aRenderContext->FillRect(aX+(aBounds?0:-thickTwips), aY, thickTwips, aLength); |
|
205 } |
|
206 } |