def within_double_byte(text, line_start, pos): """Return whether pos is within a double-byte encoded character. text -- byte string in question line_start -- offset of beginning of line (< pos) pos -- offset in question Return values: 0 -- not within dbe char, or double_byte_encoding == False 1 -- pos is on the 1st half of a dbe char 2 -- pos is on the 2nd half of a dbe char """ assert isinstance(text, bytes) v = ord2(text[pos]) if v >= 0x40 and v < 0x7f: # might be second half of big5, uhc or gbk encoding if pos == line_start: return 0 if ord2(text[pos-1]) >= 0x81: if within_double_byte(text, line_start, pos-1) == 1: return 2 return 0 if v < 0x80: return 0 i = pos -1 while i >= line_start: if ord2(text[i]) < 0x80: break i -= 1 if (pos - i) & 1: return 1 return 2
def within_double_byte(text, line_start, pos): """Return whether pos is within a double-byte encoded character. text -- byte string in question line_start -- offset of beginning of line (< pos) pos -- offset in question Return values: 0 -- not within dbe char, or double_byte_encoding == False 1 -- pos is on the 1st half of a dbe char 2 -- pos is on the 2nd half og a dbe char """ assert isinstance(text, bytes) v = ord2(text[pos]) if v >= 0x40 and v < 0x7f: # might be second half of big5, uhc or gbk encoding if pos == line_start: return 0 if ord2(text[pos-1]) >= 0x81: if within_double_byte(text, line_start, pos-1) == 1: return 2 return 0 if v < 0x80: return 0 i = pos -1 while i >= line_start: if ord2(text[i]) < 0x80: break i -= 1 if (pos - i) & 1: return 1 return 2
def addstr(self, data): if self.width <= 0 or self.height <= 0: # not displayable, do nothing! return for byte in data: self.addbyte(ord2(byte))
def render(self, size, focus=False): """ Render the progress bar. """ (maxcol, ) = size txt = Text(self.get_text(), self.text_align, CLIP) c = txt.render((maxcol, )) cf = float(self.current) * maxcol / self.done ccol_dirty = int(cf) ccol = len(c._text[0][:ccol_dirty].decode('utf-8', 'ignore').encode('utf-8')) cs = 0 if self.satt is not None: cs = int((cf - ccol) * 8) if ccol < 0 or (ccol == 0 and cs == 0): c._attr = [[(self.normal, maxcol)]] elif ccol >= maxcol: c._attr = [[(self.complete, maxcol)]] elif cs and ord2(c._text[0][ccol]) == 32: t = c._text[0] cenc = self.eighths[cs].encode("utf-8") c._text[0] = t[:ccol] + cenc + t[ccol + 1:] a = [] if ccol > 0: a.append((self.complete, ccol)) a.append((self.satt, len(cenc))) if maxcol - ccol - 1 > 0: a.append((self.normal, maxcol - ccol - 1)) c._attr = [a] c._cs = [[(None, len(c._text[0]))]] else: c._attr = [[(self.complete, ccol), (self.normal, maxcol - ccol)]] return c
def decode_one(text, pos): """ Return (ordinal at pos, next position) for UTF-8 encoded text. """ assert isinstance(text, bytes), text b1 = ord2(text[pos]) if not b1 & 0x80: return b1, pos + 1 error = ord("?"), pos + 1 lt = len(text) lt = lt - pos if lt < 2: return error if b1 & 0xe0 == 0xc0: b2 = ord2(text[pos + 1]) if b2 & 0xc0 != 0x80: return error o = ((b1 & 0x1f) << 6) | (b2 & 0x3f) if o < 0x80: return error return o, pos + 2 if lt < 3: return error if b1 & 0xf0 == 0xe0: b2 = ord2(text[pos + 1]) if b2 & 0xc0 != 0x80: return error b3 = ord2(text[pos + 2]) if b3 & 0xc0 != 0x80: return error o = ((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f) if o < 0x800: return error return o, pos + 3 if lt < 4: return error if b1 & 0xf8 == 0xf0: b2 = ord2(text[pos + 1]) if b2 & 0xc0 != 0x80: return error b3 = ord2(text[pos + 2]) if b3 & 0xc0 != 0x80: return error b4 = ord2(text[pos + 2]) if b4 & 0xc0 != 0x80: return error o = ((b1 & 0x07) << 18) | ((b2 & 0x3f) << 12) | ( (b3 & 0x3f) << 6) | (b4 & 0x3f) if o < 0x10000: return error return o, pos + 4 return error
def decode_one_right(text, pos): """ Return (ordinal at pos, next position) for UTF-8 encoded text. pos is assumed to be on the trailing byte of a utf-8 sequence. """ assert isinstance(text, bytes), text error = ord("?"), pos-1 p = pos while p >= 0: if ord2(text[p])&0xc0 != 0x80: o, next = decode_one( text, p ) return o, p-1 p -=1 if p == p-4: return error
def decode_one( text, pos ): """ Return (ordinal at pos, next position) for UTF-8 encoded text. """ assert isinstance(text, bytes), text b1 = ord2(text[pos]) if not b1 & 0x80: return b1, pos+1 error = ord("?"), pos+1 lt = len(text) lt = lt-pos if lt < 2: return error if b1 & 0xe0 == 0xc0: b2 = ord2(text[pos+1]) if b2 & 0xc0 != 0x80: return error o = ((b1&0x1f)<<6)|(b2&0x3f) if o < 0x80: return error return o, pos+2 if lt < 3: return error if b1 & 0xf0 == 0xe0: b2 = ord2(text[pos+1]) if b2 & 0xc0 != 0x80: return error b3 = ord2(text[pos+2]) if b3 & 0xc0 != 0x80: return error o = ((b1&0x0f)<<12)|((b2&0x3f)<<6)|(b3&0x3f) if o < 0x800: return error return o, pos+3 if lt < 4: return error if b1 & 0xf8 == 0xf0: b2 = ord2(text[pos+1]) if b2 & 0xc0 != 0x80: return error b3 = ord2(text[pos+2]) if b3 & 0xc0 != 0x80: return error b4 = ord2(text[pos+2]) if b4 & 0xc0 != 0x80: return error o = ((b1&0x07)<<18)|((b2&0x3f)<<12)|((b3&0x3f)<<6)|(b4&0x3f) if o < 0x10000: return error return o, pos+4 return error
def move_next_char(text, start_offs, end_offs): """ Return the position of the character after start_offs. """ assert start_offs < end_offs if isinstance(text, text_type): return start_offs+1 assert isinstance(text, bytes) if _byte_encoding == "utf8": o = start_offs+1 while o<end_offs and ord2(text[o])&0xc0 == 0x80: o += 1 return o if _byte_encoding == "wide" and within_double_byte(text, start_offs, start_offs) == 1: return start_offs +2 return start_offs+1
def move_prev_char(text, start_offs, end_offs): """ Return the position of the character before end_offs. """ assert start_offs < end_offs if isinstance(text, text_type): return end_offs-1 assert isinstance(text, bytes) if _byte_encoding == "utf8": o = end_offs-1 while ord2(text[o])&0xc0 == 0x80: o -= 1 return o if _byte_encoding == "wide" and within_double_byte(text, start_offs, end_offs-1) == 2: return end_offs-2 return end_offs-1
def move_next_char(text, start_offs, end_offs): """ Return the position of the character after start_offs. """ assert start_offs < end_offs if isinstance(text, unicode): return start_offs+1 assert isinstance(text, bytes) if _byte_encoding == "utf8": o = start_offs+1 while o<end_offs and ord2(text[o])&0xc0 == 0x80: o += 1 return o if _byte_encoding == "wide" and within_double_byte(text, start_offs, start_offs) == 1: return start_offs +2 return start_offs+1
def move_prev_char(text, start_offs, end_offs): """ Return the position of the character before end_offs. """ assert start_offs < end_offs if isinstance(text, unicode): return end_offs-1 assert isinstance(text, bytes) if _byte_encoding == "utf8": o = end_offs-1 while ord2(text[o])&0xc0 == 0x80: o -= 1 return o if _byte_encoding == "wide" and within_double_byte(text, start_offs, end_offs-1) == 2: return end_offs-2 return end_offs-1
def draw_screen(self, size, r): """Paint screen with rendered canvas.""" assert self._started cols, rows = size assert r.rows() == rows, "canvas size and passed size don't match" y = -1 for row in r.content(): y += 1 try: self.s.move(y, 0) except _curses.error: # terminal shrunk? # move failed so stop rendering. return first = True lasta = None nr = 0 for a, cs, seg in row: if cs != 'U': seg = seg.translate(UNPRINTABLE_TRANS_TABLE) assert isinstance(seg, bytes) if first or lasta != a: self._setattr(a) lasta = a try: if cs in ("0", "U"): for i in range(len(seg)): self.s.addch(0x400000 + ord2(seg[i])) else: assert cs is None if PYTHON3: assert isinstance(seg, bytes) self.s.addstr(seg.decode('utf-8')) else: self.s.addstr(seg) except _curses.error: # it's ok to get out of the # screen on the lower right if (y == rows - 1 and nr == len(row) - 1): pass else: # perhaps screen size changed # quietly abort. return nr += 1 if r.cursor is not None: x, y = r.cursor self._curs_set(1) try: self.s.move(y, x) except _curses.error: pass else: self._curs_set(0) self.s.move(0, 0) self.s.refresh() self.keep_cache_alive_link = r
def append_button(b): b |= mod l.extend([27, ord2('['), ord2('M'), b + 32, x + 33, y + 33])