void CheckerboardEvent::LogInfo(RendertraceProperty aProperty, const TimeStamp& aTimestamp, const CSSRect& aRect, const std::string& aExtraInfo, const MonitorAutoLock& aProofOfLock) { MOZ_ASSERT(mRecordTrace); if (mRendertraceInfo.tellp() >= LOG_LENGTH_LIMIT) { // The log is already long enough, don't put more things into it. We'll // append a truncation message when this event ends. return; } // The log is consumed by the page at // http://people.mozilla.org/~kgupta/rendertrace.html and will move to // about:checkerboard in bug 1238042. The format is not formally specced, but // an informal description can be found at // https://github.com/staktrace/rendertrace/blob/master/index.html#L30 mRendertraceInfo << "RENDERTRACE " << (aTimestamp - mOriginTime).ToMilliseconds() << " rect " << sColors[aProperty] << " " << aRect.X() << " " << aRect.Y() << " " << aRect.Width() << " " << aRect.Height() << " " << "// " << sDescriptions[aProperty] << aExtraInfo << std::endl; }
CSSRect CalculateRectToZoomTo(const RefPtr<dom::Document>& aRootContentDocument, const CSSPoint& aPoint) { // Ensure the layout information we get is up-to-date. aRootContentDocument->FlushPendingNotifications(FlushType::Layout); // An empty rect as return value is interpreted as "zoom out". const CSSRect zoomOut; nsCOMPtr<nsIPresShell> shell = aRootContentDocument->GetShell(); if (!shell) { return zoomOut; } nsIScrollableFrame* rootScrollFrame = shell->GetRootScrollFrameAsScrollable(); if (!rootScrollFrame) { return zoomOut; } nsCOMPtr<dom::Element> element = ElementFromPoint(shell, aPoint); if (!element) { return zoomOut; } while (element && !ShouldZoomToElement(element)) { element = element->GetParentElement(); } if (!element) { return zoomOut; } FrameMetrics metrics = nsLayoutUtils::CalculateBasicFrameMetrics(rootScrollFrame); CSSRect compositedArea( CSSPoint::FromAppUnits(shell->GetVisualViewportOffset()), metrics.CalculateCompositedSizeInCssPixels()); const CSSCoord margin = 15; CSSRect rect = nsLayoutUtils::GetBoundingContentRect(element, rootScrollFrame); // If the element is taller than the visible area of the page scale // the height of the |rect| so that it has the same aspect ratio as // the root frame. The clipped |rect| is centered on the y value of // the touch point. This allows tall narrow elements to be zoomed. if (!rect.IsEmpty() && compositedArea.Width() > 0.0f) { const float widthRatio = rect.Width() / compositedArea.Width(); float targetHeight = compositedArea.Height() * widthRatio; if (widthRatio < 0.9 && targetHeight < rect.Height()) { const CSSPoint scrollPoint = CSSPoint::FromAppUnits(rootScrollFrame->GetScrollPosition()); float newY = aPoint.y + scrollPoint.y - (targetHeight * 0.5f); if ((newY + targetHeight) > rect.YMost()) { rect.MoveByY(rect.Height() - targetHeight); } else if (newY > rect.Y()) { rect.MoveToY(newY); } rect.SetHeight(targetHeight); } } rect = CSSRect(std::max(metrics.GetScrollableRect().X(), rect.X() - margin), rect.Y(), rect.Width() + 2 * margin, rect.Height()); // Constrict the rect to the screen's right edge rect.SetWidth( std::min(rect.Width(), metrics.GetScrollableRect().XMost() - rect.X())); // If the rect is already taking up most of the visible area and is // stretching the width of the page, then we want to zoom out instead. if (IsRectZoomedIn(rect, compositedArea)) { return zoomOut; } CSSRect rounded(rect); rounded.Round(); // If the block we're zooming to is really tall, and the user double-tapped // more than a screenful of height from the top of it, then adjust the // y-coordinate so that we center the actual point the user double-tapped // upon. This prevents flying to the top of the page when double-tapping // to zoom in (bug 761721). The 1.2 multiplier is just a little fuzz to // compensate for 'rect' including horizontal margins but not vertical ones. CSSCoord cssTapY = metrics.GetScrollOffset().y + aPoint.y; if ((rect.Height() > rounded.Height()) && (cssTapY > rounded.Y() + (rounded.Height() * 1.2))) { rounded.MoveToY(cssTapY - (rounded.Height() / 2)); } return rounded; }