Commit 9e94a3b5 authored by bzbarsky%mit.edu's avatar bzbarsky%mit.edu
Browse files

Add methods to get screen coordinates of frames and views. Bug 268576,

r+sr=roc
parent 6b78bd4a
Loading
Loading
Loading
Loading
+7 −40
Original line number Diff line number Diff line
@@ -712,7 +712,7 @@ NS_IMETHODIMP nsAccessibleText::GetCharacterExtents(PRInt32 aOffset,
  shell->GetPrimaryFrameFor(content, &frame);
  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);

  nsRect frameRect = frame->GetRect();
  nsIntRect frameScreenRect = frame->GetScreenRectExternal();

  nsCOMPtr<nsIRenderingContext> rc;
  shell->CreateRenderingContext(frame, getter_AddRefs(rc));
@@ -749,43 +749,15 @@ NS_IMETHODIMP nsAccessibleText::GetCharacterExtents(PRInt32 aOffset,
    *aHeight = NSTwipsToIntPixels(tmpHeight, t2p);
  }

  //Getting x and y
  PRInt32 tmpX, tmpY;
  tmpX = frameRect.x;
  tmpY = frameRect.y;

  //add the width of the string before current char
  nsAutoString beforeString;
  nscoord beforeWidth;
  if (NS_SUCCEEDED(GetText(0, aOffset, beforeString)) &&
      NS_SUCCEEDED(rc->GetWidth(beforeString, beforeWidth))) {
    tmpX += beforeWidth;
  }

  //find the topest frame, add the offset recursively
  nsIFrame* tmpFrame = frame;
  nsIFrame* parentFrame = tmpFrame->GetParent();
  while (parentFrame) {
    nsPoint origin = parentFrame->GetPosition();
    tmpX += origin.x;
    tmpY += origin.y;
    tmpFrame = parentFrame;
    parentFrame = tmpFrame->GetParent();
  }

  tmpX = NSTwipsToIntPixels(tmpX, t2p);
  tmpY = NSTwipsToIntPixels(tmpY, t2p);

  //change to screen co-ord
  nsIWidget *frameWidget = tmpFrame->GetWindow();
  if (frameWidget) {
    nsRect oldRect(tmpX, tmpY, 0, 0), newRect;
    if (NS_SUCCEEDED(frameWidget->WidgetToScreen(oldRect, newRect))) {
      tmpX = newRect.x;
      tmpY = newRect.y;
    }
    frameScreenRect.x += NSTwipsToIntPixels(beforeWidth, t2p);
  }

  PRInt32 screenX = 0, screenY = 0;
  if (aCoordType == COORD_TYPE_WINDOW) {
    //co-ord type = window
    nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(doc));
@@ -798,20 +770,15 @@ NS_IMETHODIMP nsAccessibleText::GetCharacterExtents(PRInt32 aOffset,
    nsCOMPtr<nsIDOMWindowInternal> windowInter(do_QueryInterface(abstractView));
    NS_ENSURE_TRUE(windowInter, NS_ERROR_FAILURE);

    PRInt32 screenX,screenY;
    if (NS_FAILED(windowInter->GetScreenX(&screenX)) ||
        NS_FAILED(windowInter->GetScreenY(&screenY))) {
      return NS_ERROR_FAILURE;
    }

    *aX = tmpX - screenX;
    *aY = tmpY - screenY;
  }
  else {
    //default: co-ord type = screen
    *aX = tmpX;
    *aY = tmpY;
  }
  // else default: co-ord type = screen

  *aX = frameScreenRect.x - screenX;
  *aY = frameScreenRect.y - screenY;

  return NS_OK;
}
+9 −56
Original line number Diff line number Diff line
@@ -1200,69 +1200,22 @@ void nsSVGSVGElement::GetScreenPosition(PRInt32 &x, PRInt32 &y)
  nsIDocument *document = GetCurrentDoc();
  if (!document) return;

  // Flush all pending notifications so that our frames are uptodate
  // Make sure to do this before we start grabbing layout objects like
  // presshells.
  document->FlushPendingNotifications(Flush_Layout);
  
  nsIPresShell *presShell = document->GetShellAt(0);
  if (!presShell) {
    NS_ERROR("couldn't get presshell");
    return;
  }

  nsPresContext *context = presShell->GetPresContext();
  if (!context) {
    NS_ERROR("couldn't get prescontext");
    return;
  }

  // Flush all pending notifications so that our frames are uptodate
  document->FlushPendingNotifications(Flush_Layout);
    
  nsIFrame* frame;
  presShell->GetPrimaryFrameFor(this, &frame);

  float t2p;
  t2p = context->TwipsToPixels();

  
  nsIWidget* widget = nsnull;
        
  while (frame) {
    // Look for a widget so we can get screen coordinates
    nsIView* view = frame->GetView();
    if (view) {
      // handle scrolled views along the way:
      nsIScrollableView* scrollableView = nsnull;
      CallQueryInterface(view, &scrollableView);
      if (scrollableView) {
        nscoord scrollX, scrollY;
        scrollableView->GetScrollPosition(scrollX, scrollY);
        x -= scrollX;
        y -= scrollY;
      }

      // if this is a widget we break and get screen coords from it:
      widget = view->GetWidget();
      if (widget)
        break;
    }
          
    // No widget yet, so count up the coordinates of the frame 
    nsPoint origin = frame->GetPosition();
    x += origin.x;
    y += origin.y;
      
    frame = frame->GetParent();
  }
        
  
  // Convert to pixels using that scale
  x = NSTwipsToIntPixels(x, t2p);
  y = NSTwipsToIntPixels(y, t2p);
  
  if (widget) {
    // Add the widget's screen coordinates to the offset we've counted
    nsRect client(0,0,0,0);
    nsRect screen;
    widget->WidgetToScreen(client, screen);
    x += screen.x;
    y += screen.y;
  if (frame) {
    nsIntRect rect = frame->GetScreenRect();
    x = rect.x;
    y = rect.y;
  }
}
+7 −0
Original line number Diff line number Diff line
@@ -999,6 +999,13 @@ public:
  nsPoint GetOffsetTo(const nsIFrame* aOther) const;
  virtual nsPoint GetOffsetToExternal(const nsIFrame* aOther) const;

  /**
   * Get the screen rect of the frame.
   * @return the pixel rect of the frame in screen coordinates.
   */
  nsIntRect GetScreenRect() const;
  virtual nsIntRect GetScreenRectExternal() const;

  /**
   * Returns the offset from this frame to the closest geometric parent that
   * has a view. Also returns the containing view or null in case of error
+31 −0
Original line number Diff line number Diff line
@@ -2296,6 +2296,37 @@ nsPoint nsIFrame::GetOffsetTo(const nsIFrame* aOther) const
  return offset;
}

// virtual
nsIntRect nsIFrame::GetScreenRectExternal() const
{
  return GetScreenRect();
}

nsIntRect nsIFrame::GetScreenRect() const
{
  nsIntRect retval(0,0,0,0);
  nsPoint toViewOffset(0,0);
  nsIView* view = GetClosestView(&toViewOffset);

  if (view) {
    nsPoint toWidgetOffset(0,0);
    nsIWidget* widget = view->GetNearestWidget(&toWidgetOffset);

    if (widget) {
      nsRect ourRect = mRect;
      ourRect += toViewOffset + toWidgetOffset;
      ourRect.ScaleRoundOut(GetPresContext()->TwipsToPixels());
      // Is it safe to pass the same rect for both args of WidgetToScreen?
      // It's not clear, so let's not...
      nsIntRect ourPxRect(ourRect.x, ourRect.y, ourRect.width, ourRect.height);
      
      widget->WidgetToScreen(ourPxRect, retval);
    }
  }

  return retval;
}

// Returns the offset from this frame to the closest geometric parent that
// has a view. Also returns the containing view or null in case of error
NS_IMETHODIMP nsFrame::GetOffsetFromView(nsPresContext* aPresContext,
+7 −0
Original line number Diff line number Diff line
@@ -999,6 +999,13 @@ public:
  nsPoint GetOffsetTo(const nsIFrame* aOther) const;
  virtual nsPoint GetOffsetToExternal(const nsIFrame* aOther) const;

  /**
   * Get the screen rect of the frame.
   * @return the pixel rect of the frame in screen coordinates.
   */
  nsIntRect GetScreenRect() const;
  virtual nsIntRect GetScreenRectExternal() const;

  /**
   * Returns the offset from this frame to the closest geometric parent that
   * has a view. Also returns the containing view or null in case of error
Loading