bug 405756 - be careful with coordinateType, r=aaronlev, evan.yan, a=dsicore

This commit is contained in:
surkov.alexander@gmail.com 2007-12-01 09:30:09 -08:00
parent d19a3cd646
commit c5b280eeca
8 changed files with 163 additions and 106 deletions

View File

@ -40,11 +40,27 @@
*
* @status UNDER_REVIEW
*/
[scriptable, uuid(6e80cec3-ff7f-48f2-9823-0b962a0ed508)]
interface nsIAccessibleImage: nsISupports
[scriptable, uuid(09086623-0f09-4310-ac56-c2cda7c29648)]
interface nsIAccessibleImage : nsISupports
{
void getImageBounds(out long x,
out long y,
out long width,
out long height);
/**
* Returns the coordinates of the image.
*
* @param coordType specifies coordinates origin (for available constants
* refer to nsIAccessibleCoordinateType)
* @param x the x coordinate
* @param y the y coordinate
*/
void getImagePosition(in unsigned long coordType,
out long x,
out long y);
/**
* Returns the size of the image.
*
* @param width the heigth
* @param height the width
*/
void getImageSize(out long width, out long height);
};

View File

@ -68,19 +68,12 @@ getImagePositionCB(AtkImage *aImage, gint *aAccX, gint *aAccY,
if (!image)
return;
PRInt32 width, height; // dummy
PRUint32 geckoCoordType = (aCoordType == ATK_XY_WINDOW) ?
nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
// Returned in screen coordinates
nsresult rv = image->GetImageBounds(aAccX, aAccY, &width, &height);
if (NS_FAILED(rv))
return;
if (aCoordType == ATK_XY_WINDOW) {
nsCOMPtr<nsIDOMNode> domNode;
accWrap->GetDOMNode(getter_AddRefs(domNode));
nsIntPoint winCoords = nsAccUtils::GetScreenCoordsForWindow(domNode);
*aAccX -= winCoords.x;
*aAccY -= winCoords.y;
}
image->GetImagePosition(geckoCoordType, aAccX, aAccY);
}
const gchar *
@ -102,6 +95,5 @@ getImageSizeCB(AtkImage *aImage, gint *aAccWidth, gint *aAccHeight)
if (!image)
return;
PRInt32 x,y; // dummy
image->GetImageBounds(&x, &y, aAccWidth, aAccHeight);
image->GetImageSize(aAccWidth, aAccHeight);
}

View File

@ -436,40 +436,48 @@ nsAccUtils::ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
{
NS_ENSURE_ARG(aAccessNode);
nsCOMPtr<nsIDOMNode> DOMNode;
aAccessNode->GetDOMNode(getter_AddRefs(DOMNode));
NS_ENSURE_STATE(DOMNode);
nsIntPoint wndCoords = nsAccUtils::GetScreenCoordsForWindow(DOMNode);
*aCoords += wndCoords;
*aCoords += GetScreenCoordsForWindow(aAccessNode);
break;
}
case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
{
NS_ENSURE_ARG(aAccessNode);
*aCoords += GetScreenCoordsForParent(aAccessNode);
break;
}
nsCOMPtr<nsPIAccessNode> parent;
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(aAccessNode));
if (accessible) {
nsCOMPtr<nsIAccessible> parentAccessible;
accessible->GetParent(getter_AddRefs(parentAccessible));
parent = do_QueryInterface(parentAccessible);
} else {
nsCOMPtr<nsIAccessNode> parentAccessNode;
aAccessNode->GetParentNode(getter_AddRefs(parentAccessNode));
parent = do_QueryInterface(parentAccessNode);
}
default:
return NS_ERROR_INVALID_ARG;
}
NS_ENSURE_STATE(parent);
return NS_OK;
}
nsIFrame *parentFrame = parent->GetFrame();
NS_ENSURE_STATE(parentFrame);
nsresult
nsAccUtils::ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
PRUint32 aCoordinateType,
nsIAccessNode *aAccessNode)
{
switch (aCoordinateType) {
case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
break;
nsIntRect parentRect = parentFrame->GetScreenRectExternal();
aCoords->x += parentRect.x;
aCoords->y += parentRect.y;
case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
{
NS_ENSURE_ARG(aAccessNode);
nsIntPoint coords = GetScreenCoordsForWindow(aAccessNode);
*aX -= coords.x;
*aY -= coords.y;
break;
}
case nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE:
{
NS_ENSURE_ARG(aAccessNode);
nsIntPoint coords = GetScreenCoordsForParent(aAccessNode);
*aX -= coords.x;
*aY -= coords.y;
break;
}
@ -506,6 +514,43 @@ nsAccUtils::GetScreenCoordsForWindow(nsIDOMNode *aNode)
return coords;
}
nsIntPoint
nsAccUtils::GetScreenCoordsForWindow(nsIAccessNode *aAccessNode)
{
nsCOMPtr<nsIDOMNode> DOMNode;
aAccessNode->GetDOMNode(getter_AddRefs(DOMNode));
if (DOMNode)
return GetScreenCoordsForWindow(DOMNode);
return nsIntPoint(0, 0);
}
nsIntPoint
nsAccUtils::GetScreenCoordsForParent(nsIAccessNode *aAccessNode)
{
nsCOMPtr<nsPIAccessNode> parent;
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(aAccessNode));
if (accessible) {
nsCOMPtr<nsIAccessible> parentAccessible;
accessible->GetParent(getter_AddRefs(parentAccessible));
parent = do_QueryInterface(parentAccessible);
} else {
nsCOMPtr<nsIAccessNode> parentAccessNode;
aAccessNode->GetParentNode(getter_AddRefs(parentAccessNode));
parent = do_QueryInterface(parentAccessNode);
}
if (!parent)
return nsIntPoint(0, 0);
nsIFrame *parentFrame = parent->GetFrame();
if (!parentFrame)
return nsIntPoint(0, 0);
nsIntRect parentRect = parentFrame->GetScreenRectExternal();
return nsIntPoint(parentRect.x, parentRect.y);
}
already_AddRefed<nsIDocShellTreeItem>
nsAccUtils::GetDocShellTreeItemFor(nsIDOMNode *aNode)
{

View File

@ -214,13 +214,42 @@ public:
nsIAccessNode *aAccessNode,
nsIntPoint *aCoords);
/**
* Converts the given coordinates relative screen to another coordinate
* system.
*
* @param aX [in, out] the given x coord
* @param aY [in, out] the given y coord
* @param aCoordinateType [in] specifies coordinates origin (refer to
* nsIAccessibleCoordinateType)
* @param aAccessNode [in] the accessible if coordinates are given
* relative it
*/
static nsresult ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
PRUint32 aCoordinateType,
nsIAccessNode *aAccessNode);
/**
* Returns coordinates relative screen for the top level window.
*
* @param - aNode - the DOM node hosted in the window.
* @param aNode the DOM node hosted in the window.
*/
static nsIntPoint GetScreenCoordsForWindow(nsIDOMNode *aNode);
/**
* Returns coordinates relative screen for the top level window.
*
* @param aAccessNode the accessible hosted in the window
*/
static nsIntPoint GetScreenCoordsForWindow(nsIAccessNode *aAccessNode);
/**
* Returns coordinates relative screen for the parent of the given accessible.
*
* @param aAccessNode the accessible
*/
static nsIntPoint GetScreenCoordsForParent(nsIAccessNode *aAccessNode);
/**
* Return document shell tree item for the given DOM node.
*/

View File

@ -263,9 +263,23 @@ NS_IMETHODIMP nsHTMLImageAccessible::DoAction(PRUint8 index)
return nsLinkableAccessible::DoAction(index);
}
NS_IMETHODIMP nsHTMLImageAccessible::GetImageBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
NS_IMETHODIMP
nsHTMLImageAccessible::GetImagePosition(PRUint32 aCoordType,
PRInt32 *aX, PRInt32 *aY)
{
return GetBounds(x, y, width, height);
PRInt32 width, height;
nsresult rv = GetBounds(aX, aY, &width, &height);
if (NS_FAILED(rv))
return rv;
return nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
}
NS_IMETHODIMP
nsHTMLImageAccessible::GetImageSize(PRInt32 *aWidth, PRInt32 *aHeight)
{
PRInt32 x, y;
return GetBounds(&x, &y, aWidth, aHeight);
}
NS_IMETHODIMP

View File

@ -66,11 +66,12 @@ public:
NS_IMETHOD GetRole(PRUint32 *_retval);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetImageBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
// nsPIAccessNode
NS_IMETHOD Shutdown();
// nsIAccessibleImage
NS_DECL_NSIACCESSIBLEIMAGE
protected:
virtual void CacheChildren();
already_AddRefed<nsIAccessible> GetAreaAccessible(PRInt32 aAreaNum);

View File

@ -1107,32 +1107,7 @@ NS_IMETHODIMP nsHyperTextAccessible::GetRangeExtents(PRInt32 aStartOffset, PRInt
*aWidth = boundsRect.width;
*aHeight = boundsRect.height;
if (aCoordType == nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE) {
//co-ord type = window
nsCOMPtr<nsIPresShell> shell = GetPresShell();
NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> doc = shell->GetDocument();
nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(doc));
NS_ENSURE_TRUE(docView, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMAbstractView> abstractView;
docView->GetDefaultView(getter_AddRefs(abstractView));
NS_ENSURE_TRUE(abstractView, NS_ERROR_FAILURE);
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 -= screenX;
*aY -= screenY;
}
// else default: co-ord type = screen
return NS_OK;
return nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
}
/*
@ -1154,32 +1129,18 @@ nsHyperTextAccessible::GetOffsetAtPoint(PRInt32 aX, PRInt32 aY,
}
nsIntRect frameScreenRect = hyperFrame->GetScreenRectExternal();
if (aCoordType == nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE) {
nsCOMPtr<nsIDocument> doc = shell->GetDocument();
nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(doc));
NS_ENSURE_TRUE(docView, NS_ERROR_FAILURE);
nsIntPoint coords;
nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordType,
this, &coords);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMAbstractView> abstractView;
docView->GetDefaultView(getter_AddRefs(abstractView));
NS_ENSURE_TRUE(abstractView, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMWindowInternal> windowInter(do_QueryInterface(abstractView));
NS_ENSURE_TRUE(windowInter, NS_ERROR_FAILURE);
PRInt32 windowX, windowY;
if (NS_FAILED(windowInter->GetScreenX(&windowX)) ||
NS_FAILED(windowInter->GetScreenY(&windowY))) {
return NS_ERROR_FAILURE;
}
aX += windowX;
aY += windowY;
}
// aX, aY are currently screen coordinates, and we need to turn them into
// coords are currently screen coordinates, and we need to turn them into
// frame coordinates relative to the current accessible
if (!frameScreenRect.Contains(aX, aY)) {
if (!frameScreenRect.Contains(coords.x, coords.y)) {
return NS_OK; // Not found, will return -1
}
nsPoint pointInHyperText(aX - frameScreenRect.x, aY - frameScreenRect.y);
nsPoint pointInHyperText(coords.x - frameScreenRect.x,
coords.y - frameScreenRect.y);
nsPresContext *context = GetPresContext();
NS_ENSURE_TRUE(context, NS_ERROR_FAILURE);
pointInHyperText.x = context->DevPixelsToAppUnits(pointInHyperText.x);

View File

@ -44,6 +44,7 @@
#include "nsIAccessible.h"
#include "nsIAccessibleImage.h"
#include "nsIAccessibleTypes.h"
#include "nsCOMPtr.h"
#include "nsString.h"
@ -88,25 +89,23 @@ CAccessibleImage::get_description(BSTR *aDescription)
}
STDMETHODIMP
CAccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordinateType,
CAccessibleImage::get_imagePosition(enum IA2CoordinateType aCoordType,
long *aX,
long *aY)
{
*aX = 0;
*aY = 0;
// XXX: nsIAccessibleImage::getImageBounds() return coordinates relative
// to the screen. Make getImageBounds() to use nsIAccessibleCoordinateType to
// control it.
if (aCoordinateType != IA2_COORDTYPE_SCREEN_RELATIVE)
return E_NOTIMPL;
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
nsCOMPtr<nsIAccessibleImage> imageAcc(do_QueryInterface(this));
if (!imageAcc)
return E_FAIL;
PRInt32 x = 0, y = 0, width = 0, height = 0;
nsresult rv = imageAcc->GetImageBounds(&x, &y, &width, &height);
PRInt32 x = 0, y = 0;
nsresult rv = imageAcc->GetImagePosition(geckoCoordType, &x, &y);
if (NS_FAILED(rv))
return E_FAIL;
@ -127,7 +126,7 @@ CAccessibleImage::get_imageSize(long *aHeight, long *aWidth)
return E_FAIL;
PRInt32 x = 0, y = 0, width = 0, height = 0;
nsresult rv = imageAcc->GetImageBounds(&x, &y, &width, &height);
nsresult rv = imageAcc->GetImageSize(&width, &height);
if (NS_FAILED(rv))
return E_FAIL;