gecko/accessible/windows/sdn/sdnTextAccessible.cpp

211 lines
6.2 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "sdnTextAccessible.h"
#include "ISimpleDOMText_i.c"
#include "nsCoreUtils.h"
#include "DocAccessible.h"
#include "nsIFrame.h"
#include "nsFontMetrics.h"
#include "nsPresContext.h"
#include "nsLayoutUtils.h"
#include "nsRange.h"
#include "gfxFont.h"
#include "nsIAccessibleTypes.h"
#include "mozilla/gfx/2D.h"
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// sdnTextAccessible
////////////////////////////////////////////////////////////////////////////////
IMPL_IUNKNOWN_QUERY_HEAD(sdnTextAccessible)
IMPL_IUNKNOWN_QUERY_IFACE(ISimpleDOMText)
IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible)
STDMETHODIMP
sdnTextAccessible::get_domText(BSTR __RPC_FAR* aText)
{
A11Y_TRYBLOCK_BEGIN
if (!aText)
return E_INVALIDARG;
*aText = nullptr;
if (mAccessible->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsAutoString nodeValue;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mAccessible->GetContent()));
DOMNode->GetNodeValue(nodeValue);
if (nodeValue.IsEmpty())
return S_FALSE;
*aText = ::SysAllocStringLen(nodeValue.get(), nodeValue.Length());
return *aText ? S_OK : E_OUTOFMEMORY;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnTextAccessible::get_clippedSubstringBounds(unsigned int aStartIndex,
unsigned int aEndIndex,
int __RPC_FAR* aX,
int __RPC_FAR* aY,
int __RPC_FAR* aWidth,
int __RPC_FAR* aHeight)
{
A11Y_TRYBLOCK_BEGIN
nscoord x = 0, y = 0, width = 0, height = 0;
HRESULT rv = get_unclippedSubstringBounds(aStartIndex, aEndIndex,
&x, &y, &width, &height);
if (FAILED(rv))
return rv;
DocAccessible* document = mAccessible->Document();
NS_ASSERTION(document,
"There must always be a doc accessible, but there isn't. Crash!");
nsIntRect docRect = document->Bounds();
nsIntRect unclippedRect(x, y, width, height);
nsIntRect clippedRect;
clippedRect.IntersectRect(unclippedRect, docRect);
*aX = clippedRect.x;
*aY = clippedRect.y;
*aWidth = clippedRect.width;
*aHeight = clippedRect.height;
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex,
unsigned int aEndIndex,
int __RPC_FAR* aX,
int __RPC_FAR* aY,
int __RPC_FAR* aWidth,
int __RPC_FAR* aHeight)
{
A11Y_TRYBLOCK_BEGIN
if (!aX || !aY || !aWidth || !aHeight)
return E_INVALIDARG;
*aX = *aY = *aWidth = *aHeight = 0;
if (mAccessible->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsIFrame *frame = mAccessible->GetFrame();
NS_ENSURE_TRUE(frame, E_FAIL);
nsPoint startPoint, endPoint;
nsIFrame* startFrame = GetPointFromOffset(frame, aStartIndex, true, startPoint);
nsIFrame* endFrame = GetPointFromOffset(frame, aEndIndex, false, endPoint);
if (!startFrame || !endFrame)
return E_FAIL;
nsRect sum;
nsIFrame* iter = startFrame;
nsIFrame* stopLoopFrame = endFrame->GetNextContinuation();
for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) {
nsRect rect = iter->GetScreenRectInAppUnits();
nscoord start = (iter == startFrame) ? startPoint.x : 0;
nscoord end = (iter == endFrame) ? endPoint.x : rect.width;
rect.x += start;
rect.width = end - start;
sum.UnionRect(sum, rect);
}
nsPresContext* presContext = mAccessible->Document()->PresContext();
*aX = presContext->AppUnitsToDevPixels(sum.x);
*aY = presContext->AppUnitsToDevPixels(sum.y);
*aWidth = presContext->AppUnitsToDevPixels(sum.width);
*aHeight = presContext->AppUnitsToDevPixels(sum.height);
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
unsigned int aEndIndex)
{
A11Y_TRYBLOCK_BEGIN
if (mAccessible->IsDefunct())
return CO_E_OBJNOTCONNECTED;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi
2015-10-17 22:24:48 -07:00
RefPtr<nsRange> range = new nsRange(mAccessible->GetContent());
if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex)))
return E_FAIL;
if (NS_FAILED(range->SetEnd(mAccessible->GetContent(), aEndIndex)))
return E_FAIL;
nsresult rv =
nsCoreUtils::ScrollSubstringTo(mAccessible->GetFrame(), range,
nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE);
return GetHRESULT(rv);
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily)
{
A11Y_TRYBLOCK_BEGIN
if (!aFontFamily)
return E_INVALIDARG;
*aFontFamily = nullptr;
if (mAccessible->IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsIFrame* frame = mAccessible->GetFrame();
if (!frame)
return E_FAIL;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi
2015-10-17 22:24:48 -07:00
RefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
const nsString& name =
fm->GetThebesFontGroup()->GetFirstValidFont()->GetName();
if (name.IsEmpty())
return S_FALSE;
*aFontFamily = ::SysAllocStringLen(name.get(), name.Length());
return *aFontFamily ? S_OK : E_OUTOFMEMORY;
A11Y_TRYBLOCK_END
}
nsIFrame*
sdnTextAccessible::GetPointFromOffset(nsIFrame* aContainingFrame,
int32_t aOffset,
bool aPreferNext,
nsPoint& aOutPoint)
{
nsIFrame* textFrame = nullptr;
int32_t outOffset;
aContainingFrame->GetChildFrameContainingOffset(aOffset, aPreferNext,
&outOffset, &textFrame);
if (textFrame)
textFrame->GetPointFromOffset(aOffset, &aOutPoint);
return textFrame;
}