def test_collection(self): """Tests whether a collection of several rectangle and point types convert to the expected L{RectLTRB}.""" rect=RectLTRB(left=10, top=15, right=500, bottom=1000) self.assertEqual(RectLTRB.fromCollection( rect.topLeft, rect.bottomRight, rect.center, Point(15, 15), Point(20, 20), Point(50, 50), Point(400, 400), POINT(x=15, y=15), POINT(x=20, y=20), POINT(x=50, y=50), POINT(x=400, y=400), RectLTRB(left=450, top=450, right=490, bottom=990), RECT(450, 450, 490, 990) ), rect) location=RectLTWH(left=10, top=15, width=500, height=1000) self.assertEqual(RectLTWH.fromCollection( location.topLeft, location.bottomRight, location.center, Point(15, 15), Point(20, 20), Point(50, 50), Point(400, 400), POINT(x=15, y=15), POINT(x=20, y=20), POINT(x=50, y=50), POINT(x=400, y=400), RectLTRB(left=450, top=450, right=505, bottom=1010), RECT(450, 450, 490, 990) ), location)
def _get_boundingRects(self): if self.isCollapsed: return [] startOffset = self._startOffset try: firstVisibleOffset = self._getFirstVisibleOffset() if firstVisibleOffset >= 0: startOffset = max(startOffset, firstVisibleOffset) except (LookupError, NotImplementedError): pass getLocationFromOffset = self._getBoundingRectFromOffset try: startLocation = getLocationFromOffset(startOffset) except NotImplementedError: # Getting bounding rectangles is not implemented. # Therefore, we need to create a bounding rectangle with points. # This, though less accurate, is acceptable for use cases within NVDA. getLocationFromOffset = self._getPointFromOffset startLocation = getLocationFromOffset(startOffset) inclusiveEndOffset = self._endOffset - 1 try: lastVisibleOffset = self._getLastVisibleOffset() if lastVisibleOffset >= startOffset: inclusiveEndOffset = min(inclusiveEndOffset, lastVisibleOffset) except (LookupError, NotImplementedError): pass # If the inclusive end offset is greater than the start offset, we are working with a range. # If not, i.e. the range only contains one character, we have only one location to deal with. objLocation = self.obj.rootNVDAObject.location if isinstance( self.obj, TreeInterceptor) else self.obj.location rects = [] if inclusiveEndOffset > startOffset: offset = startOffset while offset <= inclusiveEndOffset: lineStart, lineEnd = self._getLineOffsets(offset) if lineStart < startOffset: lineStart = startOffset # Line offsets are exclusive, so the end offset is at the start of the next line, if any. inclusiveLineEnd = lineEnd - 1 if inclusiveLineEnd > inclusiveEndOffset: # The end offset is in this line inclusiveLineEnd = inclusiveEndOffset rects.append( RectLTWH.fromCollection( startLocation if lineStart == startOffset else getLocationFromOffset(lineStart), getLocationFromOffset(inclusiveLineEnd))) offset = inclusiveLineEnd + 1 else: if isinstance(startLocation, textInfos.Point): rects.append(RectLTWH.fromPoint(startLocation)) else: rects.append(startLocation) intersectedRects = [] for rect in rects: intersection = rect.intersection(objLocation) if not any(intersection): continue intersectedRects.append(intersection) return intersectedRects
def _get_boundingRects(self): # The base implementation for OffsetsTextInfo is conservative, # However here, since bounding rectangles are always known and on screen, we can use them all. lineEndOffsets = [ offset for offset in self._storyFieldsAndRects[2] if self._startOffset < offset < self._endOffset ] lineEndOffsets.append(self._endOffset) startOffset = endOffset = self._startOffset rects = [] for lineEndOffset in lineEndOffsets: startOffset=endOffset endOffset=lineEndOffset rects.append(RectLTWH.fromCollection(*self._storyFieldsAndRects[1][startOffset:endOffset]).toPhysical(self.obj.windowHandle)) return rects
def _get_boundingRects(self): # The base implementation for OffsetsTextInfo is conservative, # However here, since bounding rectangles are always known and on screen, we can use them all. lineEndOffsets = [ offset for offset in self._storyFieldsAndRects[2] if self._startOffset < offset < self._endOffset ] lineEndOffsets.append(self._endOffset) startOffset = endOffset = self._startOffset rects = [] for lineEndOffset in lineEndOffsets: startOffset=endOffset endOffset=lineEndOffset rects.append(RectLTWH.fromCollection(*self._storyFieldsAndRects[1][startOffset:endOffset].toPhysical(self.obj.windowHandle))) return rects
def _get_boundingRects(self): # The base implementation for OffsetsTextInfo is conservative, # However here, since bounding rectangles are always known and on screen, we can use them all. lineEndOffsets = [ offset for offset in self._storyFieldsAndRects[2] if self._startOffset < offset < self._endOffset ] lineEndOffsets.append(self._endOffset) startOffset = endOffset = self._startOffset rects = [] for lineEndOffset in lineEndOffsets: startOffset = endOffset endOffset = lineEndOffset lineRect = RectLTWH.fromCollection( *self._storyFieldsAndRects[1][startOffset:endOffset]) try: lineRect = lineRect.toPhysical(self.obj.windowHandle) except RuntimeError: raise LookupError( f"Couldn't convert line rectangle at offsets {startOffset} to {endOffset} " "to physical coordinates") rects.append(lineRect) return rects
def _get_boundingRects(self): if self.isCollapsed: return [] startOffset = self._startOffset try: firstVisibleOffset = self._getFirstVisibleOffset() if firstVisibleOffset >=0: startOffset = max(startOffset, firstVisibleOffset) except (LookupError, NotImplementedError): pass getLocationFromOffset = self._getBoundingRectFromOffset try: startLocation = getLocationFromOffset(startOffset) except NotImplementedError: # Getting bounding rectangles is not implemented. # Therefore, we need to create a bounding rectangle with points. # This, though less accurate, is acceptable for use cases within NVDA. getLocationFromOffset = self._getPointFromOffset startLocation = getLocationFromOffset(startOffset) inclusiveEndOffset = self._endOffset - 1 try: lastVisibleOffset = self._getLastVisibleOffset() if lastVisibleOffset >= startOffset: inclusiveEndOffset = min(inclusiveEndOffset, lastVisibleOffset) except (LookupError, NotImplementedError): pass # If the inclusive end offset is greater than the start offset, we are working with a range. # If not, i.e. the range only contains one character, we have only one location to deal with. obj = self.obj.rootNVDAObject if isinstance(self.obj, TreeInterceptor) else self.obj for i in range(100): objLocation = obj.location if objLocation: break obj = obj.parent if not objLocation: raise LookupError rects = [] if inclusiveEndOffset > startOffset: offset = startOffset while offset <= inclusiveEndOffset: lineStart, lineEnd = self._getLineOffsets(offset) if lineStart < startOffset: lineStart = startOffset # Line offsets are exclusive, so the end offset is at the start of the next line, if any. inclusiveLineEnd = lineEnd - 1 if inclusiveLineEnd > inclusiveEndOffset: # The end offset is in this line inclusiveLineEnd = inclusiveEndOffset rects.append( RectLTWH.fromCollection( startLocation if lineStart == startOffset else getLocationFromOffset(lineStart), getLocationFromOffset(inclusiveLineEnd) ) ) offset = inclusiveLineEnd + 1 else: if isinstance(startLocation, textInfos.Point): rects.append(RectLTWH.fromPoint(startLocation)) else: rects.append(startLocation) intersectedRects = [] for rect in rects: intersection = rect.intersection(objLocation) if not any(intersection): continue intersectedRects.append(intersection) return intersectedRects