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;
}
示例#2
0
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;
}