calloc(w * h, sizeof(int))
if achFill != achBlankI:
for iach in range(w * h):
self.rgach[iach] = achFill
self.w = w
self.h = h
def __dealloc__(self):
free(self.rgach)
cdef Zpos(self, int xz, int yz):
return Pos(self.w, self.h, xz + 1, yz + 1)
cdef inline IAch(self, int xz, int yz):
return xz + (self.w * yz)
cdef PutAch(self, int ach, int x, int y):
if not (x < 1 or y < 1 or x > self.w or y > self.h): #clip
self.rgach[self.IAch(x - 1, y - 1)] = ach
#self.mpyzxz_ach[y-1][x-1] = ach
cdef inline GetAch(self, int x, int y):
return self.rgach[self.IAch(x - 1, y - 1)]
cdef PutRgach(self, rgach, int x, int y):
cdef int xz = x - 1
cdef int iach
if xz < self.w:
if xz < 0:
rgach = rgach[min(-xz, len(rgach)):]
xz = 0
if xz + len(rgach) >= self.w:
rgach = rgach[:self.w - xz]
iach = self.IAch(xz, y - 1)
for ach in rgach:
if ach != achBlankI:
self.rgach[iach] = ach
iach = iach + 1
#self.mpyzxz_ach[y-1][xz:xz + len(rgach)] = rgach
cdef PutSt(self, char *st, int x, int y, int colFg = WHITE, int colBg=BLACK):
if y < 1 or y > self.h:
return
cdef int cch = len(st)
cdef int ichStart = 0
cdef int xz = x - 1
if xz < 0:
ichStart = (-xz)
cch = cch - ichStart
xz = 0
cch = min(cch, self.w - xz)
cdef UAch uach
uach.sach.fgCol = colFg
uach.sach.bgCol = colBg
cdef int iach = self.IAch(xz, y - 1)
for ich in range(ichStart, ichStart + cch):
uach.sach.ch = st[ich]
self.rgach[iach] = uach.ach
iach = iach + 1
#self.PutRgach([MkAch(ch, colFg, colBg) for ch in st], x, y)
cdef Fill(self, int ach, int wIn, int hIn, int x = 1, int y = 1):
if x > self.w or y > self.h or ach == achBlankI:
return
cdef int xz = max(x - 1, 0)
cdef int yz = max(y - 1, 0)
cdef int w = min(self.w - xz, wIn)
cdef int h = min(self.h - yz, hIn)
cdef int iach
for yzT in range(yz, yz + h):
iach = self.IAch(xz, yzT)
for xzT in range(w):
self.rgach[iach] = ach
iach = iach + 1
#self.mpyzxz_ach[yzT][xz:xz + w] = ach
cdef PutAscr(self, AscrI ascr, int x=1, int y=1):
if x > self.w or y > self.h:
return
cdef int xz = max(x - 1, 0)
cdef int yz = max(y - 1, 0)
cdef int w = min(self.w - xz, ascr.w)
cdef int h = min(self.h - yz, ascr.h)
cdef int yzOther = 0
cdef int iach, iachOther, ach
for yzT in range(yz, yz + h):
iach = self.IAch(xz, yzT)
iachOther = ascr.IAch(0, yzOther)
for xzT in range(w):
ach = ascr.rgach[iachOther]
if ach != achBlankI:
self.rgach[iach] = ach
iach = iach + 1
iachOther = iachOther + 1
yzOther = yzOther + 1
cdef AstDiff(self, AscrI ascr):
assert self.w == ascr.w and self.h == ascr.h
cdef int xz = 0
cdef int yz = 0
cdef int xzPred = -1
cdef int achPrev = achInvdI
cdef int achBeforeEOL = achInvdI
cdef int achOld, achNew, achNewRaw
cdef int achSpace = MkAch(' ')
rgast = []
for iach in range(self.w * self.h):
achOld = self.rgach[iach]
achNewRaw = ascr.rgach[iach]
if achNewRaw == achBlankI:
achNew = achSpace
else:
achNew = achNewRaw
if xz == self.w - 2:
achBeforeEOL = achNew
if achOld != achNewRaw:
if xz == self.w - 1:
# Linewrap avoidance algorithm:
# when drawing the last character on a line, draw it in the space occupied by the character before.
rgast.append("%s%d;%dH" % (esc, yz + 1, xz))
rgast.append(AstFromAch(achNew, achInvdI))
# then, move the cursor back onto the character we just drew, and perform an insert.
rgast.append("%sD%s@" % (esc, esc))
# finally, draw the character before the last character in the line.
rgast.append(AstFromAch(achBeforeEOL, achNew))
achPrev = achBeforeEOL
else:
if xz != xzPred:
xzPred = xz
rgast.append("%s%d;%dH" % (esc, yz + 1, xz + 1))
achPrev = achInvdI
rgast.append(AstFromAch(achNew, achPrev))
achPrev = achNew
xzPred = xzPred + 1
xz = xz + 1
if xz == self.w:
xz = 0
xzPred = -1
yz = yz + 1
return "".join(rgast)
cdef Hst(self):
rgst = [""]
cdef int achPrev = achInvdI
cdef int xz = 0
cdef int ach
for iach in range(self.w * self.h):
ach = self.rgach[iach]
rgst.append(HstFromAch(ach, achPrev))
achPrev = ach
xz = xz + 1
if xz == self.w:
xz = 0
rgst.append("
")
rgst.append("