michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "inFlasher.h" michael@0: #include "inLayoutUtils.h" michael@0: michael@0: #include "nsIDOMElement.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsIPresShell.h" michael@0: #include "nsIFrame.h" michael@0: #include "nsIWidget.h" michael@0: #include "nsReadableUtils.h" michael@0: #include "nsRenderingContext.h" michael@0: #include "nsIDOMWindow.h" michael@0: #include "nsIContent.h" michael@0: michael@0: #include "prprf.h" michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: inFlasher::inFlasher() : michael@0: mColor(NS_RGB(0,0,0)), michael@0: mThickness(0), michael@0: mInvert(false) michael@0: { michael@0: } michael@0: michael@0: inFlasher::~inFlasher() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(inFlasher, inIFlasher) michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: // inIFlasher michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::GetColor(nsAString& aColor) michael@0: { michael@0: // Copied from nsGenericHTMLElement::ColorToString() michael@0: char buf[10]; michael@0: PR_snprintf(buf, sizeof(buf), "#%02x%02x%02x", michael@0: NS_GET_R(mColor), NS_GET_G(mColor), NS_GET_B(mColor)); michael@0: CopyASCIItoUTF16(buf, aColor); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::SetColor(const nsAString& aColor) michael@0: { michael@0: NS_ENSURE_FALSE(aColor.IsEmpty(), NS_ERROR_ILLEGAL_VALUE); michael@0: michael@0: nsAutoString colorStr; michael@0: colorStr.Assign(aColor); michael@0: michael@0: if (colorStr.CharAt(0) != '#') { michael@0: if (NS_ColorNameToRGB(colorStr, &mColor)) { michael@0: return NS_OK; michael@0: } michael@0: } michael@0: else { michael@0: colorStr.Cut(0, 1); michael@0: if (NS_HexToRGB(colorStr, &mColor)) { michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: return NS_ERROR_ILLEGAL_VALUE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::GetThickness(uint16_t *aThickness) michael@0: { michael@0: NS_PRECONDITION(aThickness, "Null pointer"); michael@0: *aThickness = mThickness; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::SetThickness(uint16_t aThickness) michael@0: { michael@0: mThickness = aThickness; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::GetInvert(bool *aInvert) michael@0: { michael@0: NS_PRECONDITION(aInvert, "Null pointer"); michael@0: *aInvert = mInvert; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::SetInvert(bool aInvert) michael@0: { michael@0: mInvert = aInvert; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::RepaintElement(nsIDOMElement* aElement) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aElement); michael@0: nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement); michael@0: if (!frame) return NS_OK; michael@0: michael@0: frame->InvalidateFrame(); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::DrawElementOutline(nsIDOMElement* aElement) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aElement); michael@0: nsCOMPtr window = inLayoutUtils::GetWindowFor(aElement); michael@0: if (!window) return NS_OK; michael@0: nsCOMPtr presShell = inLayoutUtils::GetPresShellFor(window); michael@0: if (!presShell) return NS_OK; michael@0: michael@0: nsIFrame* frame = inLayoutUtils::GetFrameFor(aElement); michael@0: michael@0: bool isFirstFrame = true; michael@0: michael@0: while (frame) { michael@0: nsPoint offset; michael@0: nsIWidget* widget = frame->GetNearestWidget(offset); michael@0: if (widget) { michael@0: nsRefPtr rcontext = new nsRenderingContext(); michael@0: rcontext->Init(frame->PresContext()->DeviceContext(), michael@0: widget->GetThebesSurface()); michael@0: michael@0: nsRect rect(offset, frame->GetSize()); michael@0: if (mInvert) { michael@0: rcontext->InvertRect(rect); michael@0: } michael@0: michael@0: bool isLastFrame = frame->GetNextContinuation() == nullptr; michael@0: DrawOutline(rect.x, rect.y, rect.width, rect.height, rcontext, michael@0: isFirstFrame, isLastFrame); michael@0: isFirstFrame = false; michael@0: } michael@0: frame = frame->GetNextContinuation(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: inFlasher::ScrollElementIntoView(nsIDOMElement *aElement) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aElement); michael@0: nsCOMPtr window = inLayoutUtils::GetWindowFor(aElement); michael@0: if (!window) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsCOMPtr presShell = inLayoutUtils::GetPresShellFor(window); michael@0: if (!presShell) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aElement); michael@0: presShell->ScrollContentIntoView(content, michael@0: nsIPresShell::ScrollAxis(), michael@0: nsIPresShell::ScrollAxis(), michael@0: nsIPresShell::SCROLL_OVERFLOW_HIDDEN); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: // inFlasher michael@0: michael@0: void michael@0: inFlasher::DrawOutline(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, michael@0: nsRenderingContext* aRenderContext, michael@0: bool aDrawBegin, bool aDrawEnd) michael@0: { michael@0: aRenderContext->SetColor(mColor); michael@0: michael@0: DrawLine(aX, aY, aWidth, DIR_HORIZONTAL, BOUND_OUTER, aRenderContext); michael@0: if (aDrawBegin) { michael@0: DrawLine(aX, aY, aHeight, DIR_VERTICAL, BOUND_OUTER, aRenderContext); michael@0: } michael@0: DrawLine(aX, aY+aHeight, aWidth, DIR_HORIZONTAL, BOUND_INNER, aRenderContext); michael@0: if (aDrawEnd) { michael@0: DrawLine(aX+aWidth, aY, aHeight, DIR_VERTICAL, BOUND_INNER, aRenderContext); michael@0: } michael@0: } michael@0: michael@0: void michael@0: inFlasher::DrawLine(nscoord aX, nscoord aY, nscoord aLength, michael@0: bool aDir, bool aBounds, michael@0: nsRenderingContext* aRenderContext) michael@0: { michael@0: nscoord thickTwips = nsPresContext::CSSPixelsToAppUnits(mThickness); michael@0: if (aDir) { // horizontal michael@0: aRenderContext->FillRect(aX, aY+(aBounds?0:-thickTwips), aLength, thickTwips); michael@0: } else { // vertical michael@0: aRenderContext->FillRect(aX+(aBounds?0:-thickTwips), aY, thickTwips, aLength); michael@0: } michael@0: }