9fans.net/go@v0.0.5/draw/memdraw/layerop.go (about) 1 package memdraw 2 3 import ( 4 "9fans.net/go/draw" 5 ) 6 7 func _layerop(fn func(*Image, draw.Rectangle, draw.Rectangle, interface{}, int), i *Image, r draw.Rectangle, clipr draw.Rectangle, etc interface{}, front *Image) { 8 RECUR := func(a, b, c, d draw.Point) { 9 _layerop(fn, i, draw.Rect(a.X, b.Y, c.X, d.Y), clipr, etc, front.Layer.rear) 10 } 11 12 Top: 13 if front == i { 14 /* no one is in front of this part of window; use the screen */ 15 fn(i.Layer.Screen.Image, r, clipr, etc, 0) 16 return 17 } 18 fr := front.Layer.Screenr 19 if !draw.RectXRect(r, fr) { 20 /* r doesn't touch this window; continue on next rearmost */ 21 /* assert(front && front->layer && front->layer->screen && front->layer->rear); */ 22 front = front.Layer.rear 23 goto Top 24 } 25 if fr.Max.Y < r.Max.Y { 26 RECUR(r.Min, fr.Max, r.Max, r.Max) 27 r.Max.Y = fr.Max.Y 28 } 29 if r.Min.Y < fr.Min.Y { 30 RECUR(r.Min, r.Min, r.Max, fr.Min) 31 r.Min.Y = fr.Min.Y 32 } 33 if fr.Max.X < r.Max.X { 34 RECUR(fr.Max, r.Min, r.Max, r.Max) 35 r.Max.X = fr.Max.X 36 } 37 if r.Min.X < fr.Min.X { 38 RECUR(r.Min, r.Min, fr.Min, r.Max) 39 r.Min.X = fr.Min.X 40 } 41 /* r is covered by front, so put in save area */ 42 fn(i.Layer.save, r, clipr, etc, 1) 43 } 44 45 /* 46 * Assumes incoming rectangle has already been clipped to i's logical r and clipr 47 */ 48 func _memlayerop(fn func(*Image, draw.Rectangle, draw.Rectangle, interface{}, int), i *Image, screenr draw.Rectangle, clipr draw.Rectangle, etc interface{}) { 49 l := i.Layer 50 if !draw.RectClip(&screenr, l.Screenr) { 51 return 52 } 53 if l.clear { 54 fn(l.Screen.Image, screenr, clipr, etc, 0) 55 return 56 } 57 r := screenr 58 scr := l.Screen.Image.Clipr 59 60 /* 61 * Do the piece on the screen 62 */ 63 if draw.RectClip(&screenr, scr) { 64 _layerop(fn, i, screenr, clipr, etc, l.Screen.Frontmost) 65 } 66 if draw.RectInRect(r, scr) { 67 return 68 } 69 70 /* 71 * Do the piece off the screen 72 */ 73 if !draw.RectXRect(r, scr) { 74 /* completely offscreen; easy */ 75 fn(l.save, r, clipr, etc, 1) 76 return 77 } 78 if r.Min.Y < scr.Min.Y { 79 /* above screen */ 80 fn(l.save, draw.Rect(r.Min.X, r.Min.Y, r.Max.X, scr.Min.Y), clipr, etc, 1) 81 r.Min.Y = scr.Min.Y 82 } 83 if r.Max.Y > scr.Max.Y { 84 /* below screen */ 85 fn(l.save, draw.Rect(r.Min.X, scr.Max.Y, r.Max.X, r.Max.Y), clipr, etc, 1) 86 r.Max.Y = scr.Max.Y 87 } 88 if r.Min.X < scr.Min.X { 89 /* left of screen */ 90 fn(l.save, draw.Rect(r.Min.X, r.Min.Y, scr.Min.X, r.Max.Y), clipr, etc, 1) 91 r.Min.X = scr.Min.X 92 } 93 if r.Max.X > scr.Max.X { 94 /* right of screen */ 95 fn(l.save, draw.Rect(scr.Max.X, r.Min.Y, r.Max.X, r.Max.Y), clipr, etc, 1) 96 } 97 }