accessible/src/windows/sdn/sdnTextAccessible.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "sdnTextAccessible.h"
michael@0 8
michael@0 9 #include "ISimpleDOMText_i.c"
michael@0 10
michael@0 11 #include "nsCoreUtils.h"
michael@0 12 #include "DocAccessible.h"
michael@0 13
michael@0 14 #include "nsIFrame.h"
michael@0 15 #include "nsFontMetrics.h"
michael@0 16 #include "nsPresContext.h"
michael@0 17 #include "nsLayoutUtils.h"
michael@0 18 #include "gfxFont.h"
michael@0 19 #include "nsIAccessibleTypes.h"
michael@0 20 #include "mozilla/gfx/2D.h"
michael@0 21
michael@0 22 using namespace mozilla::a11y;
michael@0 23
michael@0 24 ////////////////////////////////////////////////////////////////////////////////
michael@0 25 // sdnTextAccessible
michael@0 26 ////////////////////////////////////////////////////////////////////////////////
michael@0 27
michael@0 28 IMPL_IUNKNOWN_QUERY_HEAD(sdnTextAccessible)
michael@0 29 IMPL_IUNKNOWN_QUERY_IFACE(ISimpleDOMText)
michael@0 30 IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible)
michael@0 31
michael@0 32 STDMETHODIMP
michael@0 33 sdnTextAccessible::get_domText(BSTR __RPC_FAR* aText)
michael@0 34 {
michael@0 35 A11Y_TRYBLOCK_BEGIN
michael@0 36
michael@0 37 if (!aText)
michael@0 38 return E_INVALIDARG;
michael@0 39 *aText = nullptr;
michael@0 40
michael@0 41 if (mAccessible->IsDefunct())
michael@0 42 return CO_E_OBJNOTCONNECTED;
michael@0 43
michael@0 44 nsAutoString nodeValue;
michael@0 45
michael@0 46 nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mAccessible->GetContent()));
michael@0 47 DOMNode->GetNodeValue(nodeValue);
michael@0 48 if (nodeValue.IsEmpty())
michael@0 49 return S_FALSE;
michael@0 50
michael@0 51 *aText = ::SysAllocStringLen(nodeValue.get(), nodeValue.Length());
michael@0 52 return *aText ? S_OK : E_OUTOFMEMORY;
michael@0 53
michael@0 54 A11Y_TRYBLOCK_END
michael@0 55 }
michael@0 56
michael@0 57 STDMETHODIMP
michael@0 58 sdnTextAccessible::get_clippedSubstringBounds(unsigned int aStartIndex,
michael@0 59 unsigned int aEndIndex,
michael@0 60 int __RPC_FAR* aX,
michael@0 61 int __RPC_FAR* aY,
michael@0 62 int __RPC_FAR* aWidth,
michael@0 63 int __RPC_FAR* aHeight)
michael@0 64 {
michael@0 65 A11Y_TRYBLOCK_BEGIN
michael@0 66
michael@0 67 nscoord x = 0, y = 0, width = 0, height = 0;
michael@0 68 HRESULT rv = get_unclippedSubstringBounds(aStartIndex, aEndIndex,
michael@0 69 &x, &y, &width, &height);
michael@0 70 if (FAILED(rv))
michael@0 71 return rv;
michael@0 72
michael@0 73 DocAccessible* document = mAccessible->Document();
michael@0 74 NS_ASSERTION(document,
michael@0 75 "There must always be a doc accessible, but there isn't. Crash!");
michael@0 76
michael@0 77 nscoord docX = 0, docY = 0, docWidth = 0, docHeight = 0;
michael@0 78 document->GetBounds(&docX, &docY, &docWidth, &docHeight);
michael@0 79
michael@0 80 nsIntRect unclippedRect(x, y, width, height);
michael@0 81 nsIntRect docRect(docX, docY, docWidth, docHeight);
michael@0 82
michael@0 83 nsIntRect clippedRect;
michael@0 84 clippedRect.IntersectRect(unclippedRect, docRect);
michael@0 85
michael@0 86 *aX = clippedRect.x;
michael@0 87 *aY = clippedRect.y;
michael@0 88 *aWidth = clippedRect.width;
michael@0 89 *aHeight = clippedRect.height;
michael@0 90 return S_OK;
michael@0 91
michael@0 92 A11Y_TRYBLOCK_END
michael@0 93 }
michael@0 94
michael@0 95 STDMETHODIMP
michael@0 96 sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex,
michael@0 97 unsigned int aEndIndex,
michael@0 98 int __RPC_FAR* aX,
michael@0 99 int __RPC_FAR* aY,
michael@0 100 int __RPC_FAR* aWidth,
michael@0 101 int __RPC_FAR* aHeight)
michael@0 102 {
michael@0 103 A11Y_TRYBLOCK_BEGIN
michael@0 104
michael@0 105 if (!aX || !aY || !aWidth || !aHeight)
michael@0 106 return E_INVALIDARG;
michael@0 107 *aX = *aY = *aWidth = *aHeight = 0;
michael@0 108
michael@0 109 if (mAccessible->IsDefunct())
michael@0 110 return CO_E_OBJNOTCONNECTED;
michael@0 111
michael@0 112 nsIFrame *frame = mAccessible->GetFrame();
michael@0 113 NS_ENSURE_TRUE(frame, E_FAIL);
michael@0 114
michael@0 115 nsPoint startPoint, endPoint;
michael@0 116 nsIFrame* startFrame = GetPointFromOffset(frame, aStartIndex, true, startPoint);
michael@0 117 nsIFrame* endFrame = GetPointFromOffset(frame, aEndIndex, false, endPoint);
michael@0 118 if (!startFrame || !endFrame)
michael@0 119 return E_FAIL;
michael@0 120
michael@0 121 nsRect sum;
michael@0 122 nsIFrame* iter = startFrame;
michael@0 123 nsIFrame* stopLoopFrame = endFrame->GetNextContinuation();
michael@0 124 for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) {
michael@0 125 nsRect rect = iter->GetScreenRectInAppUnits();
michael@0 126 nscoord start = (iter == startFrame) ? startPoint.x : 0;
michael@0 127 nscoord end = (iter == endFrame) ? endPoint.x : rect.width;
michael@0 128 rect.x += start;
michael@0 129 rect.width = end - start;
michael@0 130 sum.UnionRect(sum, rect);
michael@0 131 }
michael@0 132
michael@0 133 nsPresContext* presContext = mAccessible->Document()->PresContext();
michael@0 134 *aX = presContext->AppUnitsToDevPixels(sum.x);
michael@0 135 *aY = presContext->AppUnitsToDevPixels(sum.y);
michael@0 136 *aWidth = presContext->AppUnitsToDevPixels(sum.width);
michael@0 137 *aHeight = presContext->AppUnitsToDevPixels(sum.height);
michael@0 138
michael@0 139 return S_OK;
michael@0 140
michael@0 141 A11Y_TRYBLOCK_END
michael@0 142 }
michael@0 143
michael@0 144 STDMETHODIMP
michael@0 145 sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
michael@0 146 unsigned int aEndIndex)
michael@0 147 {
michael@0 148 A11Y_TRYBLOCK_BEGIN
michael@0 149
michael@0 150 if (mAccessible->IsDefunct())
michael@0 151 return CO_E_OBJNOTCONNECTED;
michael@0 152
michael@0 153 nsRefPtr<nsRange> range = new nsRange(mAccessible->GetContent());
michael@0 154 if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex)))
michael@0 155 return E_FAIL;
michael@0 156
michael@0 157 if (NS_FAILED(range->SetEnd(mAccessible->GetContent(), aEndIndex)))
michael@0 158 return E_FAIL;
michael@0 159
michael@0 160 nsresult rv =
michael@0 161 nsCoreUtils::ScrollSubstringTo(mAccessible->GetFrame(), range,
michael@0 162 nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE);
michael@0 163 return GetHRESULT(rv);
michael@0 164
michael@0 165 A11Y_TRYBLOCK_END
michael@0 166 }
michael@0 167
michael@0 168 STDMETHODIMP
michael@0 169 sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily)
michael@0 170 {
michael@0 171 A11Y_TRYBLOCK_BEGIN
michael@0 172
michael@0 173 if (!aFontFamily)
michael@0 174 return E_INVALIDARG;
michael@0 175 *aFontFamily = nullptr;
michael@0 176
michael@0 177 if (mAccessible->IsDefunct())
michael@0 178 return CO_E_OBJNOTCONNECTED;
michael@0 179
michael@0 180 nsIFrame* frame = mAccessible->GetFrame();
michael@0 181 if (!frame)
michael@0 182 return E_FAIL;
michael@0 183
michael@0 184 nsRefPtr<nsFontMetrics> fm;
michael@0 185 nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
michael@0 186
michael@0 187 const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName();
michael@0 188 if (name.IsEmpty())
michael@0 189 return S_FALSE;
michael@0 190
michael@0 191 *aFontFamily = ::SysAllocStringLen(name.get(), name.Length());
michael@0 192 return *aFontFamily ? S_OK : E_OUTOFMEMORY;
michael@0 193
michael@0 194 A11Y_TRYBLOCK_END
michael@0 195 }
michael@0 196
michael@0 197 nsIFrame*
michael@0 198 sdnTextAccessible::GetPointFromOffset(nsIFrame* aContainingFrame,
michael@0 199 int32_t aOffset,
michael@0 200 bool aPreferNext,
michael@0 201 nsPoint& aOutPoint)
michael@0 202 {
michael@0 203 nsIFrame* textFrame = nullptr;
michael@0 204 int32_t outOffset;
michael@0 205 aContainingFrame->GetChildFrameContainingOffset(aOffset, aPreferNext,
michael@0 206 &outOffset, &textFrame);
michael@0 207 if (textFrame)
michael@0 208 textFrame->GetPointFromOffset(aOffset, &aOutPoint);
michael@0 209
michael@0 210 return textFrame;
michael@0 211 }

mercurial