diff options
author | Cyrus Harmon <cyrus@bobobeach.com> | 2017-06-04 15:25:50 -0700 |
---|---|---|
committer | Cyrus Harmon <cyrus@bobobeach.com> | 2017-06-04 15:25:50 -0700 |
commit | 23285040ff998966fe63d3b081ae7f75d71b41a2 (patch) | |
tree | f7457652ecfd364c5694006fcb29eefd47c88cc3 | |
parent | 9bb28af6f6383b530f8471e42a9181384e6e0335 (diff) |
bezier drawing fixes
* use the newly fixed with-clx-graphics from the outer level of the
drawing loop to try to fix various drawing problems.
* avoid using two possbily different drawable/gc pairs.
* zero out the mask prior to use
* these fixes make it so that bezier-differences can be drawn in the
listener. They still do not draw correctly in drawing-tests with
CLXv3, but they do draw properly with CLXv3 in the listener, and
now work in both drawing-tests and the listener with the CLX
backend.
-rw-r--r-- | Extensions/bezier/bezier.lisp | 92 |
1 files changed, 47 insertions, 45 deletions
diff --git a/Extensions/bezier/bezier.lisp b/Extensions/bezier/bezier.lisp index 9ca51061..2fcd2279 100644 --- a/Extensions/bezier/bezier.lisp +++ b/Extensions/bezier/bezier.lisp @@ -883,54 +883,56 @@ second curve point, yielding (200 50)." (let ((tr (make-instance 'climi::standard-translation :dx (- imin-x) :dy (- imin-y)))) (let ((width (- imax-x imin-x)) (height (- imax-y imin-y))) - (let ((drawable (clim-clx::sheet-xmirror (medium-sheet medium)))) - (with-slots ((gc clim-clx::gc)) medium - ;; 1. save the clipmask, clip-x-origin, and clip-y-origin + (clim-clx::with-clx-graphics (drawable line-style ink gc) + medium + ;; 1. create mask pixmap and GC + (let* ((mask-pixmap (xlib:create-pixmap :drawable drawable + :width width + :height height + :depth 1)) + (mask-gc (xlib:create-gcontext :drawable mask-pixmap + :foreground 1 + :background 0))) + (setf (xlib:gcontext-foreground mask-gc) 0) + (xlib:draw-rectangle mask-pixmap mask-gc 0 0 width height t) + ;; 2. for each of the positive areas, draw 1's in the + ;; clip-pixmap for the corresponding shape + (setf (xlib:gcontext-foreground mask-gc) 1) + (dolist (area (positive-areas design)) + (let ((t-area (transform-region tr area))) + (let ((coord-vec (bezier-region-to-coord-vec t-area))) + (xlib:draw-lines mask-pixmap mask-gc coord-vec :fill-p t)))) + ;; 3. for each of the negative areas, draw 0s in the + ;; clip-pixmap for the corresponding shape + (setf (xlib:gcontext-foreground mask-gc) 0) + (dolist (area (negative-areas design)) + (let ((t-area (transform-region tr area))) + (let ((coord-vec (bezier-region-to-coord-vec t-area))) + (xlib:draw-lines mask-pixmap mask-gc coord-vec :fill-p t)))) + ;; 4. set the clipmask, clip-x-origin, and clip-y-origin + ;; 5. actually do the (masked) drawing (let ((old-clip-mask (xlib:gcontext-clip-mask gc)) (old-clip-x (xlib:gcontext-clip-x gc)) (old-clip-y (xlib:gcontext-clip-y gc))) - ;; 2. create a 1-bit region that is the size of the bezier - ;; difference (the clip-pixmap) - (let* ((mask-pixmap (xlib:create-pixmap :drawable drawable - :width width - :height height - :depth 1)) - (mask-gc (xlib:create-gcontext :drawable mask-pixmap - :foreground 1 - :background 0))) - ;; 3. for each of the positive areas, draw 1s in the - ;; clip-pixmap for the corresponding shape - (setf (xlib:gcontext-foreground mask-gc) 1) - (dolist (area (positive-areas design)) - (let ((t-area (transform-region tr area))) - (let ((coord-vec (bezier-region-to-coord-vec t-area))) - (xlib:draw-lines mask-pixmap mask-gc coord-vec :fill-p t)))) - ;; 4. for each of the negative areas, draw 0s in the - ;; clip-pixmap for the corresponding shape - (setf (xlib:gcontext-foreground mask-gc) 0) - (dolist (area (negative-areas design)) - (let ((t-area (transform-region tr area))) - (let ((coord-vec (bezier-region-to-coord-vec t-area))) - (xlib:draw-lines mask-pixmap mask-gc coord-vec :fill-p t)))) - ;; 5. set the clipmask, clip-x-origin, and clip-y-origin - (setf (xlib:gcontext-clip-mask gc :unsorted) mask-pixmap - (xlib:gcontext-clip-x gc) imin-x - (xlib:gcontext-clip-y gc) imin-y) - ;; 6. actually do the (masked) drawing - (dolist (area (positive-areas design)) - (let* ((tr (sheet-native-transformation (medium-sheet medium))) - (region (transform-region tr area)) - (coord-vec (bezier-region-to-coord-vec region))) - (clim-clx::with-clx-graphics () medium - (xlib:draw-lines clim-clx::mirror clim-clx::gc coord-vec :fill-p t)))) - ;; 7. restore things on the way back out - ;; reset the clipmask, clip-x-origin, and clip-y-origin to their original values - (setf (xlib:gcontext-clip-mask gc) old-clip-mask - (xlib:gcontext-clip-x gc) old-clip-x - (xlib:gcontext-clip-y gc) old-clip-y) - ;; 8. free the clipmask - (xlib:free-gcontext mask-gc) - (xlib:free-pixmap mask-pixmap)))))))))) + + (setf (xlib:gcontext-clip-mask gc) mask-pixmap + (xlib:gcontext-clip-x gc) imin-x + (xlib:gcontext-clip-y gc) imin-y) + + (dolist (area (positive-areas design)) + (let* ((tr (sheet-native-transformation (medium-sheet medium))) + (region (transform-region tr area)) + (coord-vec (bezier-region-to-coord-vec region))) + (xlib:draw-lines drawable gc coord-vec :fill-p t))) + + ;; 6. restore things on the way back out + ;; reset the clipmask, clip-x-origin, and clip-y-origin to their original values + (setf (xlib:gcontext-clip-mask gc) old-clip-mask + (xlib:gcontext-clip-x gc) old-clip-x + (xlib:gcontext-clip-y gc) old-clip-y)) + ;; 7. free the clipmask + (xlib:free-gcontext mask-gc) + (xlib:free-pixmap mask-pixmap)))))))) ;;; NULL backend support |