9fans.net/go@v0.0.5/draw/memdraw/ldraw.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 type _Draw struct { 14 deltas draw.Point 15 deltam draw.Point 16 dstlayer *Layer 17 src *Image 18 mask *Image 19 op draw.Op 20 } 21 22 func ldrawop(dst *Image, screenr draw.Rectangle, clipr draw.Rectangle, etc interface{}, insave int) { 23 d := etc.(*_Draw) 24 if insave != 0 && d.dstlayer.save == nil { 25 return 26 } 27 28 p0 := screenr.Min.Add(d.deltas) 29 p1 := screenr.Min.Add(d.deltam) 30 var r draw.Rectangle 31 32 if insave != 0 { 33 r = screenr.Sub(d.dstlayer.Delta) 34 clipr = clipr.Sub(d.dstlayer.Delta) 35 } else { 36 r = screenr 37 } 38 39 /* now in logical coordinates */ 40 41 /* clipr may have narrowed what we should draw on, so clip if necessary */ 42 if !draw.RectInRect(r, clipr) { 43 oclipr := dst.Clipr 44 dst.Clipr = clipr 45 var mr draw.Rectangle 46 var srcr draw.Rectangle 47 ok := drawclip(dst, &r, d.src, &p0, d.mask, &p1, &srcr, &mr) 48 dst.Clipr = oclipr 49 if ok == 0 { 50 return 51 } 52 } 53 Draw(dst, r, d.src, p0, d.mask, p1, d.op) 54 } 55 56 func Draw(dst *Image, r draw.Rectangle, src *Image, p0 draw.Point, mask *Image, p1 draw.Point, op draw.Op) { 57 if drawdebug != 0 { 58 iprint("memdraw %p %v %p %v %p %v\n", dst, r, src, p0, mask, p1) 59 } 60 61 if mask == nil { 62 mask = Opaque 63 } 64 65 if mask.Layer != nil { 66 if drawdebug != 0 { 67 iprint("mask->layer != nil\n") 68 } 69 return /* too hard, at least for now */ 70 } 71 72 Top: 73 if dst.Layer == nil && src.Layer == nil { 74 dst.Draw(r, src, p0, mask, p1, op) 75 return 76 } 77 var srcr draw.Rectangle 78 var mr draw.Rectangle 79 80 if drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0 { 81 if drawdebug != 0 { 82 iprint("drawclip dstcr %v srccr %v maskcr %v\n", dst.Clipr, src.Clipr, mask.Clipr) 83 } 84 return 85 } 86 87 /* 88 * Convert to screen coordinates. 89 */ 90 dl := dst.Layer 91 if dl != nil { 92 r.Min.X += dl.Delta.X 93 r.Min.Y += dl.Delta.Y 94 r.Max.X += dl.Delta.X 95 r.Max.Y += dl.Delta.Y 96 } 97 Clearlayer: 98 if dl != nil && dl.clear { 99 if src == dst { 100 p0.X += dl.Delta.X 101 p0.Y += dl.Delta.Y 102 src = dl.Screen.Image 103 } 104 dst = dl.Screen.Image 105 goto Top 106 } 107 108 sl := src.Layer 109 if sl != nil { 110 p0.X += sl.Delta.X 111 p0.Y += sl.Delta.Y 112 srcr.Min.X += sl.Delta.X 113 srcr.Min.Y += sl.Delta.Y 114 srcr.Max.X += sl.Delta.X 115 srcr.Max.Y += sl.Delta.Y 116 } 117 118 /* 119 * Now everything is in screen coordinates. 120 * mask is an image. dst and src are images or obscured layers. 121 */ 122 123 /* 124 * if dst and src are the same layer, just draw in save area and expose. 125 */ 126 if dl != nil && dst == src { 127 if dl.save == nil { 128 return /* refresh function makes this case unworkable */ 129 } 130 if draw.RectXRect(r, srcr) { 131 tr := r 132 if srcr.Min.X < tr.Min.X { 133 p1.X += tr.Min.X - srcr.Min.X 134 tr.Min.X = srcr.Min.X 135 } 136 if srcr.Min.Y < tr.Min.Y { 137 p1.Y += tr.Min.X - srcr.Min.X 138 tr.Min.Y = srcr.Min.Y 139 } 140 if srcr.Max.X > tr.Max.X { 141 tr.Max.X = srcr.Max.X 142 } 143 if srcr.Max.Y > tr.Max.Y { 144 tr.Max.Y = srcr.Max.Y 145 } 146 memlhide(dst, tr) 147 } else { 148 memlhide(dst, r) 149 memlhide(dst, srcr) 150 } 151 Draw(dl.save, r.Sub(dl.Delta), dl.save, srcr.Min.Sub(src.Layer.Delta), mask, p1, op) 152 memlexpose(dst, r) 153 return 154 } 155 156 if sl != nil { 157 if sl.clear { 158 src = sl.Screen.Image 159 if dl != nil { 160 r.Min.X -= dl.Delta.X 161 r.Min.Y -= dl.Delta.Y 162 r.Max.X -= dl.Delta.X 163 r.Max.Y -= dl.Delta.Y 164 } 165 goto Top 166 } 167 /* relatively rare case; use save area */ 168 if sl.save == nil { 169 return /* refresh function makes this case unworkable */ 170 } 171 memlhide(src, srcr) 172 /* convert back to logical coordinates */ 173 p0.X -= sl.Delta.X 174 p0.Y -= sl.Delta.Y 175 srcr.Min.X -= sl.Delta.X 176 srcr.Min.Y -= sl.Delta.Y 177 srcr.Max.X -= sl.Delta.X 178 srcr.Max.Y -= sl.Delta.Y 179 src = src.Layer.save 180 } 181 182 /* 183 * src is now an image. dst may be an image or a clear layer 184 */ 185 if dst.Layer == nil { 186 goto Top 187 } 188 if dst.Layer.clear { 189 goto Clearlayer 190 } 191 var d _Draw 192 193 /* 194 * dst is an obscured layer 195 */ 196 d.deltas = p0.Sub(r.Min) 197 d.deltam = p1.Sub(r.Min) 198 d.dstlayer = dl 199 d.src = src 200 d.op = op 201 d.mask = mask 202 _memlayerop(ldrawop, dst, r, r, &d) 203 }