1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/windows/sdn/sdnTextAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,211 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "sdnTextAccessible.h" 1.11 + 1.12 +#include "ISimpleDOMText_i.c" 1.13 + 1.14 +#include "nsCoreUtils.h" 1.15 +#include "DocAccessible.h" 1.16 + 1.17 +#include "nsIFrame.h" 1.18 +#include "nsFontMetrics.h" 1.19 +#include "nsPresContext.h" 1.20 +#include "nsLayoutUtils.h" 1.21 +#include "gfxFont.h" 1.22 +#include "nsIAccessibleTypes.h" 1.23 +#include "mozilla/gfx/2D.h" 1.24 + 1.25 +using namespace mozilla::a11y; 1.26 + 1.27 +//////////////////////////////////////////////////////////////////////////////// 1.28 +// sdnTextAccessible 1.29 +//////////////////////////////////////////////////////////////////////////////// 1.30 + 1.31 +IMPL_IUNKNOWN_QUERY_HEAD(sdnTextAccessible) 1.32 + IMPL_IUNKNOWN_QUERY_IFACE(ISimpleDOMText) 1.33 +IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible) 1.34 + 1.35 +STDMETHODIMP 1.36 +sdnTextAccessible::get_domText(BSTR __RPC_FAR* aText) 1.37 +{ 1.38 + A11Y_TRYBLOCK_BEGIN 1.39 + 1.40 + if (!aText) 1.41 + return E_INVALIDARG; 1.42 + *aText = nullptr; 1.43 + 1.44 + if (mAccessible->IsDefunct()) 1.45 + return CO_E_OBJNOTCONNECTED; 1.46 + 1.47 + nsAutoString nodeValue; 1.48 + 1.49 + nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mAccessible->GetContent())); 1.50 + DOMNode->GetNodeValue(nodeValue); 1.51 + if (nodeValue.IsEmpty()) 1.52 + return S_FALSE; 1.53 + 1.54 + *aText = ::SysAllocStringLen(nodeValue.get(), nodeValue.Length()); 1.55 + return *aText ? S_OK : E_OUTOFMEMORY; 1.56 + 1.57 + A11Y_TRYBLOCK_END 1.58 +} 1.59 + 1.60 +STDMETHODIMP 1.61 +sdnTextAccessible::get_clippedSubstringBounds(unsigned int aStartIndex, 1.62 + unsigned int aEndIndex, 1.63 + int __RPC_FAR* aX, 1.64 + int __RPC_FAR* aY, 1.65 + int __RPC_FAR* aWidth, 1.66 + int __RPC_FAR* aHeight) 1.67 +{ 1.68 + A11Y_TRYBLOCK_BEGIN 1.69 + 1.70 + nscoord x = 0, y = 0, width = 0, height = 0; 1.71 + HRESULT rv = get_unclippedSubstringBounds(aStartIndex, aEndIndex, 1.72 + &x, &y, &width, &height); 1.73 + if (FAILED(rv)) 1.74 + return rv; 1.75 + 1.76 + DocAccessible* document = mAccessible->Document(); 1.77 + NS_ASSERTION(document, 1.78 + "There must always be a doc accessible, but there isn't. Crash!"); 1.79 + 1.80 + nscoord docX = 0, docY = 0, docWidth = 0, docHeight = 0; 1.81 + document->GetBounds(&docX, &docY, &docWidth, &docHeight); 1.82 + 1.83 + nsIntRect unclippedRect(x, y, width, height); 1.84 + nsIntRect docRect(docX, docY, docWidth, docHeight); 1.85 + 1.86 + nsIntRect clippedRect; 1.87 + clippedRect.IntersectRect(unclippedRect, docRect); 1.88 + 1.89 + *aX = clippedRect.x; 1.90 + *aY = clippedRect.y; 1.91 + *aWidth = clippedRect.width; 1.92 + *aHeight = clippedRect.height; 1.93 + return S_OK; 1.94 + 1.95 + A11Y_TRYBLOCK_END 1.96 +} 1.97 + 1.98 +STDMETHODIMP 1.99 +sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex, 1.100 + unsigned int aEndIndex, 1.101 + int __RPC_FAR* aX, 1.102 + int __RPC_FAR* aY, 1.103 + int __RPC_FAR* aWidth, 1.104 + int __RPC_FAR* aHeight) 1.105 +{ 1.106 + A11Y_TRYBLOCK_BEGIN 1.107 + 1.108 + if (!aX || !aY || !aWidth || !aHeight) 1.109 + return E_INVALIDARG; 1.110 + *aX = *aY = *aWidth = *aHeight = 0; 1.111 + 1.112 + if (mAccessible->IsDefunct()) 1.113 + return CO_E_OBJNOTCONNECTED; 1.114 + 1.115 + nsIFrame *frame = mAccessible->GetFrame(); 1.116 + NS_ENSURE_TRUE(frame, E_FAIL); 1.117 + 1.118 + nsPoint startPoint, endPoint; 1.119 + nsIFrame* startFrame = GetPointFromOffset(frame, aStartIndex, true, startPoint); 1.120 + nsIFrame* endFrame = GetPointFromOffset(frame, aEndIndex, false, endPoint); 1.121 + if (!startFrame || !endFrame) 1.122 + return E_FAIL; 1.123 + 1.124 + nsRect sum; 1.125 + nsIFrame* iter = startFrame; 1.126 + nsIFrame* stopLoopFrame = endFrame->GetNextContinuation(); 1.127 + for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) { 1.128 + nsRect rect = iter->GetScreenRectInAppUnits(); 1.129 + nscoord start = (iter == startFrame) ? startPoint.x : 0; 1.130 + nscoord end = (iter == endFrame) ? endPoint.x : rect.width; 1.131 + rect.x += start; 1.132 + rect.width = end - start; 1.133 + sum.UnionRect(sum, rect); 1.134 + } 1.135 + 1.136 + nsPresContext* presContext = mAccessible->Document()->PresContext(); 1.137 + *aX = presContext->AppUnitsToDevPixels(sum.x); 1.138 + *aY = presContext->AppUnitsToDevPixels(sum.y); 1.139 + *aWidth = presContext->AppUnitsToDevPixels(sum.width); 1.140 + *aHeight = presContext->AppUnitsToDevPixels(sum.height); 1.141 + 1.142 + return S_OK; 1.143 + 1.144 + A11Y_TRYBLOCK_END 1.145 +} 1.146 + 1.147 +STDMETHODIMP 1.148 +sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex, 1.149 + unsigned int aEndIndex) 1.150 +{ 1.151 + A11Y_TRYBLOCK_BEGIN 1.152 + 1.153 + if (mAccessible->IsDefunct()) 1.154 + return CO_E_OBJNOTCONNECTED; 1.155 + 1.156 + nsRefPtr<nsRange> range = new nsRange(mAccessible->GetContent()); 1.157 + if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex))) 1.158 + return E_FAIL; 1.159 + 1.160 + if (NS_FAILED(range->SetEnd(mAccessible->GetContent(), aEndIndex))) 1.161 + return E_FAIL; 1.162 + 1.163 + nsresult rv = 1.164 + nsCoreUtils::ScrollSubstringTo(mAccessible->GetFrame(), range, 1.165 + nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE); 1.166 + return GetHRESULT(rv); 1.167 + 1.168 + A11Y_TRYBLOCK_END 1.169 +} 1.170 + 1.171 +STDMETHODIMP 1.172 +sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily) 1.173 +{ 1.174 + A11Y_TRYBLOCK_BEGIN 1.175 + 1.176 + if (!aFontFamily) 1.177 + return E_INVALIDARG; 1.178 + *aFontFamily = nullptr; 1.179 + 1.180 + if (mAccessible->IsDefunct()) 1.181 + return CO_E_OBJNOTCONNECTED; 1.182 + 1.183 + nsIFrame* frame = mAccessible->GetFrame(); 1.184 + if (!frame) 1.185 + return E_FAIL; 1.186 + 1.187 + nsRefPtr<nsFontMetrics> fm; 1.188 + nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm)); 1.189 + 1.190 + const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName(); 1.191 + if (name.IsEmpty()) 1.192 + return S_FALSE; 1.193 + 1.194 + *aFontFamily = ::SysAllocStringLen(name.get(), name.Length()); 1.195 + return *aFontFamily ? S_OK : E_OUTOFMEMORY; 1.196 + 1.197 + A11Y_TRYBLOCK_END 1.198 +} 1.199 + 1.200 +nsIFrame* 1.201 +sdnTextAccessible::GetPointFromOffset(nsIFrame* aContainingFrame, 1.202 + int32_t aOffset, 1.203 + bool aPreferNext, 1.204 + nsPoint& aOutPoint) 1.205 +{ 1.206 + nsIFrame* textFrame = nullptr; 1.207 + int32_t outOffset; 1.208 + aContainingFrame->GetChildFrameContainingOffset(aOffset, aPreferNext, 1.209 + &outOffset, &textFrame); 1.210 + if (textFrame) 1.211 + textFrame->GetPointFromOffset(aOffset, &aOutPoint); 1.212 + 1.213 + return textFrame; 1.214 +}