Skip to content

Commit 5132004

Browse files
Merge 6b02fef into 8bc6f52
2 parents 8bc6f52 + 6b02fef commit 5132004

1 file changed

Lines changed: 56 additions & 27 deletions

File tree

source/braille.py

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,9 +1760,10 @@ def __init__(self, handler):
17601760
#: The translated braille representation of the entire buffer.
17611761
#: @type: [int, ...]
17621762
self.brailleCells = []
1763-
#: The position in L{brailleCells} where the display window starts (inclusive).
1764-
#: @type: int
1765-
self.windowStartPos = 0
1763+
#: A list representing the rows in the braille window,
1764+
#: each item being a tuple of start and end braille buffer offsets.
1765+
#: Splitting the window into independent rows allows for optional avoidance of splitting words across rows.
1766+
self._windowRowBufferOffsets: list[tuple[int, int]] = [(0, 0)]
17661767

17671768
def clear(self):
17681769
"""Clear the entire buffer.
@@ -1857,28 +1858,47 @@ def bufferPositionsToRawText(self, startPos, endPos):
18571858
)
18581859
return ""
18591860

1860-
def bufferPosToWindowPos(self, bufferPos):
1861-
if not (self.windowStartPos <= bufferPos < self.windowEndPos):
1862-
raise LookupError("Buffer position not in window")
1863-
return bufferPos - self.windowStartPos
1861+
def bufferPosToWindowPos(self, bufferPos: int) -> int:
1862+
for row, (start, end) in enumerate(self._windowRowBufferOffsets):
1863+
if start <= bufferPos < end:
1864+
return row * self.handler.display.numCols + (bufferPos - start)
1865+
raise LookupError("buffer pos not in window")
18641866

1865-
def _get_windowEndPos(self):
1866-
endPos = self.windowStartPos + self.handler.displaySize
1867-
cellsLen = len(self.brailleCells)
1868-
if endPos >= cellsLen:
1869-
return cellsLen
1870-
if not config.conf["braille"]["wordWrap"]:
1871-
return endPos
1872-
try:
1873-
# Try not to split words across windows.
1874-
# To do this, break after the furthest possible space.
1875-
return min(
1876-
rindex(self.brailleCells, 0, self.windowStartPos, endPos) + 1,
1877-
endPos,
1878-
)
1879-
except ValueError:
1880-
pass
1881-
return endPos
1867+
def windowPosToBufferPos(self, windowPos: int) -> int:
1868+
"""
1869+
Converts a position relative to the braille window to a position relative to the braille buffer.
1870+
"""
1871+
windowPos = max(min(windowPos, self.handler.displaySize), 0)
1872+
row, col = divmod(windowPos, self.handler.display.numCols)
1873+
if row < len(self._windowRowBufferOffsets):
1874+
start, end = self._windowRowBufferOffsets[row]
1875+
return min(start + col, end - 1)
1876+
raise ValueError("Position outside window")
1877+
1878+
def _get_windowStartPos(self):
1879+
return self.windowPosToBufferPos(0)
1880+
1881+
def _set_windowStartPos(self, pos):
1882+
self._windowRowBufferOffsets.clear()
1883+
if len(self.brailleCells) == 0:
1884+
# Initialising with no actual braille content.
1885+
self._windowRowBufferOffsets = [(0, 0)] * self.handler.display.numRows
1886+
return
1887+
doWordWrap = config.conf["braille"]["wordWrap"]
1888+
start = pos
1889+
for row in range(self.handler.display.numRows):
1890+
end = start + self.handler.display.numCols
1891+
if doWordWrap:
1892+
try:
1893+
end = rindex(self.brailleCells, 0, start, end) + 1
1894+
except (ValueError, IndexError):
1895+
pass # No space on line
1896+
self._windowRowBufferOffsets.append((start, end))
1897+
start = end
1898+
1899+
def _get_windowEndPos(self) -> int:
1900+
start, end = self._windowRowBufferOffsets[-1]
1901+
return end
18821902

18831903
def _set_windowEndPos(self, endPos):
18841904
"""Sets the end position for the braille window and recalculates the window start position based on several variables.
@@ -2010,6 +2030,8 @@ def update(self):
20102030
start += len(cells)
20112031
if log.isEnabledFor(log.IO):
20122032
log.io("Braille regions text: %r" % logRegions)
2033+
# Ensure that braille cells are padded up to display size.
2034+
self.brailleCells.extend([0 for x in range(len(self.brailleCells), self.handler.displaySize)])
20132035

20142036
def updateDisplay(self):
20152037
if self is self.handler.buffer:
@@ -2027,17 +2049,24 @@ def _get_windowRawText(self):
20272049
return self.bufferPositionsToRawText(self.windowStartPos, self.windowEndPos)
20282050

20292051
def _get_windowBrailleCells(self):
2030-
return self.brailleCells[self.windowStartPos : self.windowEndPos]
2052+
windowCells = []
2053+
for start, end in self._windowRowBufferOffsets:
2054+
rowCells = self.brailleCells[start:end]
2055+
remaining = self.handler.display.numCols - len(rowCells)
2056+
if remaining > 0:
2057+
rowCells.extend([0] * remaining)
2058+
windowCells.extend(rowCells)
2059+
return windowCells
20312060

20322061
def routeTo(self, windowPos):
2033-
pos = self.windowStartPos + windowPos
2062+
pos = self.windowPosToBufferPos(windowPos)
20342063
if pos >= self.windowEndPos:
20352064
return
20362065
region, pos = self.bufferPosToRegionPos(pos)
20372066
region.routeTo(pos)
20382067

20392068
def getTextInfoForWindowPos(self, windowPos):
2040-
pos = self.windowStartPos + windowPos
2069+
pos = self.windowPosToBufferPos(windowPos)
20412070
if pos >= self.windowEndPos:
20422071
return None
20432072
region, pos = self.bufferPosToRegionPos(pos)

0 commit comments

Comments
 (0)