9fans.net/go@v0.0.5/draw/memdraw/load.go (about) 1 // #include <u.h> 2 // #include <libc.h> 3 // #include <draw.h> 4 // #include <memdraw.h> 5 6 package memdraw 7 8 import ( 9 "fmt" 10 11 "9fans.net/go/draw" 12 ) 13 14 func loadmemimage(i *Image, r draw.Rectangle, data []uint8) (int, error) { 15 if !draw.RectInRect(r, i.R) { 16 return 0, fmt.Errorf("invalid rectangle") 17 } 18 l := draw.BytesPerLine(r, i.Depth) 19 if len(data) < l*r.Dy() { 20 return 0, fmt.Errorf("buffer too small") 21 } 22 ndata := l * r.Dy() 23 q := byteaddr(i, r.Min) 24 mx := 7 / i.Depth 25 lpart := (r.Min.X & mx) * i.Depth 26 rpart := (r.Max.X & mx) * i.Depth 27 m := uint8(0xFF) >> lpart 28 var y int 29 /* may need to do bit insertion on edges */ 30 if l == 1 { /* all in one byte */ 31 if rpart != 0 { 32 m ^= 0xFF >> rpart 33 } 34 for y = r.Min.Y; y < r.Max.Y; y++ { 35 q[0] ^= (data[0] ^ q[0]) & m 36 q = q[i.Width*4:] 37 data = data[1:] 38 } 39 return ndata, nil 40 } 41 if lpart == 0 && rpart == 0 { /* easy case */ 42 for y = r.Min.Y; y < r.Max.Y; y++ { 43 copy(q[:l], data[:l]) 44 q = q[i.Width*4:] 45 data = data[l:] 46 } 47 return ndata, nil 48 } 49 mr := uint8(0xFF) ^ (0xFF >> rpart) 50 if lpart != 0 && rpart == 0 { 51 for y = r.Min.Y; y < r.Max.Y; y++ { 52 q[0] ^= (data[0] ^ q[0]) & m 53 if l > 1 { 54 copy(q[1:l], data[1:l]) 55 } 56 q = q[i.Width*4:] 57 data = data[l:] 58 } 59 return ndata, nil 60 } 61 if lpart == 0 && rpart != 0 { 62 for y = r.Min.Y; y < r.Max.Y; y++ { 63 if l > 1 { 64 copy(q[:l-1], data[:l-1]) 65 } 66 q[l-1] ^= (data[l-1] ^ q[l-1]) & mr 67 q = q[i.Width*4:] 68 data = data[l:] 69 } 70 return ndata, nil 71 } 72 for y = r.Min.Y; y < r.Max.Y; y++ { 73 q[0] ^= (data[0] ^ q[0]) & m 74 if l > 2 { 75 copy(q[1:l-1], data[1:l-1]) 76 } 77 q[l-1] ^= (data[l-1] ^ q[l-1]) & mr 78 q = q[i.Width*4:] 79 data = data[l:] 80 } 81 return ndata, nil 82 }