This library add lot of draw methods for kandinsky library.
Go to GitHub page to read doc about avalaible methods
Note: if you read the code you risk not understanding anything, it’s normal the library has been designed to be as optimized and small as possible, hence this somewhat strange syntax.
from kandinsky import get_pixel as gp,set_pixel as sp,fill_rect as fr,draw_string as ds,color def DEC(v,o,m=-1,r=0): l,x=[],MASK(o) while v and m: l.append(v&x) v>>=o m-=1 if not r:l.reverse() return l,v def ENC(l,o,d=0,r=0): s=len(l) for i in range(s-1,-1,-1)if r else range(s):d=(d<<o)|l[i] return d def BITS(v): c=0 while v: c+=1 v>>=1 return c HEX=lambda v,l=2:("%0"+"%dx"%l)%v MASK=lambda b:(1<<b)-1 CHARSET=''.join([chr(c+48+(c>9)*39-(c>35)*58)for c in range(62)]) def b62c(v): o=(v==0)*"0" while v>0:o,v=CHARSET[v%62]+o,v//62 return o def b62d(v): o,s=0,len(v) for i,l in enumerate(v):o+=CHARSET.index(l)*(62**(s-(i+1))) return o get_hpixel=lambda x,y,to_int=False:ENC(gp(x,y),8) if to_int else '#%02x%02x%02x'%gp(x,y) def draw_circle(x,y,radius,color,back=None,spader=1,semi=False,reverse=False): ra,s=radius,spader r,rr,s=ra**2,ra*2,(s>0)*(s+9)**2 for i in range(r<<(2-semi)): tx,ty=(i%rr)-ra,(i//rr)-ra if r-s<=tx**2+ty**2<=r if reverse else r-s>=tx**2+ty**2>=r:sp(x+tx,y+ty,color) elif back!=None:sp(x+tx,y+ty,back) def fill_circle(x,y,radius,color,back=None,semi=False,reverse=False): draw_circle(x,y,radius,color,back,radius,semi,reverse) def draw_rect(x,y,w,h,color,spader=1): c,s=color,spader fr(x,y,w,s,c) fr(x,y,s,h,c) fr(x+w,y,s,h,c) fr(x,y+h,w,s,c) def draw_line(x1,y1,x2,y2,color,spader=1): c,ss=color,spader if ss<1:return s=abs(y2-y1)>abs(x2-x1) if s:x1,y1,x2,y2=y1,x1,y2,x2 if x1>x2:x1,x2,y1,y2=x2,x1,y2,y1 g=1 if x2==x1 else(y2-y1)/(x2-x1) for x in range(x1,x2): y2=int(y1+g*(x-x1)) fr(y2,x,ss,ss,c)if s else fr(x,y2,ss,ss,c) def copy_screen(x,y,w,h,compress=False,a=False): if any([not -1<i<4096 for i in(x,y,w,h)]):return 0 c,t,p,o,mh,r=0,[],[],ENC(gp(x,y),8),BITS(w),range(w) z,p=o,[o] rr=[random.randint(0,255) for _ in(0,1,2)] for ty in range(h): _,c=t.append((p.index(o)<<mh)|c),0 rr=[random.randint(0,255) for _ in(0,1,2)] for tx in r: z,c=ENC(gp(x+tx,y+ty),8),c+1 time.sleep(0.01) if z not in p:p.append(z) if z!=o or a: _,c,o=t.append((p.index(z)<<mh)|c),0,z # ds(f"{t[-1]:b} ",200,30) rr=[random.randint(0,255) for _ in(0,1,2)] # z,c=ENC(gp(x+tx,y+ty),8),c+1 sp(x+tx,y+ty,rr) # ds(f"{c},#{o:06x} ",200,10) # if c>0: # _,c=t.append((p.index(o)<<mh)|c),0 # rr=[random.randint(0,255) for _ in(0,1,2)] mp=BITS(len(p)) d=ENC((x,y,w,h),12,ENC((mh,mp),6,ENC([len(p)]+p,24,ENC(t,mh+mp,0,1),1),1),1) return b62c(d)if compress else d import time,random def parse_screen(x,y,d,z=1): if type(d)==str:d=b62d(d) v,d=DEC(d,12,4,1) o,d=DEC(d,6,2,1) p,d=DEC(d>>24,24,d&MASK(24),1) tx=ty=c=0 w,h,mh,mp,m,p=v[2],v[3],MASK(o[0]),MASK(o[1]),sum(o),["#%06x"%i for i in p] while d: if c>0: fr(x+tx*z,y+ty*z,min(c,w-tx)*z,z,p[(d>>o[0])&mp]) time.sleep(0.5) tx,c=tx+c,0 # ds(f"{tx}<{w},{ty}<{h},{c}",10,200,"w") if tx>=w:tx,ty,c=0,ty+1,tx-w if ty>=h and d>>m!=0: print("parse_screen(): lost data: %x"%d) break continue d>>=m c=d&mh print(c,mh) def draw_text(text,x,y,size=1,color_=(0,0,0),bg=(248,252,248),hideModel=True): s,l,c,hm,ss=10*len(text.replace('\t'," ")),18*(text.count('\n')+1),color_,hideModel,size hc,hbg=c==None,bg==None if hc and hbg:return if hm: o=copy_screen(0,0,s,l,True) ds(text,0,0,**({"color":c} if hc else {})+({"background":bg} if hbg else {})) e=color(c) if hc else color(bg) if hbg else False [[fr(x+xx*(ss+1)-xx,y+yy*(ss+1)-yy,ss,ss,gp(xx,yy)) for yy in range(l)if gp(xx,yy)!=e]for xx in range(s)] if hm:parse_screen(0,0,o)