9fans.net/go@v0.0.5/draw/memdraw/lorigin.go (about) 1 // #include <u.h> 2 // #include <libc.h> 3 // #include <draw.h> 4 // #include <memdraw.h> 5 // #include <memlayer.h> 6 7 package memdraw 8 9 import ( 10 "9fans.net/go/draw" 11 ) 12 13 /* 14 * Place i so i->r.min = log, i->layer->screenr.min == scr. 15 */ 16 func LOrigin(i *Image, log draw.Point, scr draw.Point) (int, error) { 17 l := i.Layer 18 s := l.Screen 19 oldr := l.Screenr 20 newr := draw.Rect(scr.X, scr.Y, scr.X+oldr.Dx(), scr.Y+oldr.Dy()) 21 eqscr := scr == oldr.Min 22 eqlog := log == i.R.Min 23 if eqscr && eqlog { 24 return 0, nil 25 } 26 var nsave *Image 27 if !eqlog && l.save != nil { 28 var err error 29 nsave, err = AllocImage(draw.Rect(log.X, log.Y, log.X+oldr.Dx(), log.Y+oldr.Dy()), i.Pix) 30 if err != nil { 31 return 0, err 32 } 33 } 34 35 /* 36 * Bring it to front and move logical coordinate system. 37 */ 38 memltofront(i) 39 wasclear := l.clear 40 if nsave != nil { 41 if !wasclear { 42 nsave.Draw(nsave.R, l.save, l.save.R.Min, nil, draw.Pt(0, 0), draw.S) 43 } 44 Free(l.save) 45 l.save = nsave 46 } 47 delta := log.Sub(i.R.Min) 48 i.R = i.R.Add(delta) 49 i.Clipr = i.Clipr.Add(delta) 50 l.Delta = l.Screenr.Min.Sub(i.R.Min) 51 if eqscr { 52 return 0, nil 53 } 54 55 /* 56 * To clean up old position, make a shadow window there, don't paint it, 57 * push it behind this one, and (later) delete it. Because the refresh function 58 * for this fake window is a no-op, this will cause no graphics action except 59 * to restore the background and expose the windows previously hidden. 60 */ 61 shad, err := LAlloc(s, oldr, LNoRefresh, nil, draw.NoFill) 62 if err != nil { 63 return 0, err 64 } 65 s.Frontmost = i 66 if s.Rearmost == i { 67 s.Rearmost = shad 68 } else { 69 l.rear.Layer.front = shad 70 } 71 shad.Layer.front = i 72 shad.Layer.rear = l.rear 73 l.rear = shad 74 l.front = nil 75 shad.Layer.clear = false 76 77 /* 78 * Shadow is now holding down the fort at the old position. 79 * Move the window and hide things obscured by new position. 80 */ 81 for t := l.rear.Layer.rear; t != nil; t = t.Layer.rear { 82 x := newr 83 overlap := draw.RectClip(&x, t.Layer.Screenr) 84 if overlap { 85 memlhide(t, x) 86 t.Layer.clear = false 87 } 88 } 89 l.Screenr = newr 90 l.Delta = scr.Sub(i.R.Min) 91 l.clear = draw.RectInRect(newr, l.Screen.Image.Clipr) 92 93 /* 94 * Everything's covered. Copy to new position and delete shadow window. 95 */ 96 if wasclear { 97 Draw(s.Image, newr, s.Image, oldr.Min, nil, draw.Pt(0, 0), draw.S) 98 } else { 99 memlexpose(i, newr) 100 } 101 LDelete(shad) 102 103 return 1, nil 104 } 105 106 func LNoRefresh(l *Image, r draw.Rectangle, v interface{}) { 107 }