[mcclim-cvs] CVS mcclim/Backends/CLX

ahefner ahefner at common-lisp.net
Sun Jan 6 01:37:06 UTC 2008


Update of /project/mcclim/cvsroot/mcclim/Backends/CLX
In directory clnet:/tmp/cvs-serv601/Backends/CLX

Modified Files:
	medium.lisp 
Log Message:
Eliminate duplicated medium-gcontext method in freetype (it had fallen
behind in maintenance, anyway). Reduced or eliminated consing while
setting medium clipping region.



--- /project/mcclim/cvsroot/mcclim/Backends/CLX/medium.lisp	2007/07/19 06:55:39	1.82
+++ /project/mcclim/cvsroot/mcclim/Backends/CLX/medium.lisp	2008/01/06 01:37:06	1.83
@@ -37,6 +37,9 @@
 (defclass clx-medium (basic-medium)
   ((gc :initform nil)
    (picture :initform nil)
+   (clipping-region-tmp :initform (vector 0 0 0 0)
+     :documentation "This object is reused to avoid consing in the
+ most common case when configuring the clipping region.")
    (buffer :initform nil :accessor medium-buffer)))
 
 #+CLX-EXT-RENDER
@@ -100,25 +103,40 @@
 		  ((t nil) 3)
 		  (otherwise (line-style-dashes line-style)))))))))
 
+(defun %set-gc-clipping-region (medium gc)
+  (declare (type clx-medium medium))
+  (let ((clipping-region (medium-device-region medium))
+        (tmp (slot-value medium 'clipping-region-tmp))
+        (port (port medium)))
+    (cond 
+      ((region-equal clipping-region +nowhere+)
+       (setf (xlib:gcontext-clip-mask gc) #()))
+      ((typep clipping-region 'standard-rectangle)
+       (multiple-value-bind (x1 y1 width height)
+           (region->clipping-values clipping-region)
+         (setf (aref tmp 0) x1
+               (aref tmp 1) y1
+               (aref tmp 2) width
+               (aref tmp 3) height
+               (xlib:gcontext-clip-mask gc :unsorted) tmp)))
+      (t
+        (let ((rect-seq (clipping-region->rect-seq clipping-region)))
+          (when rect-seq
+            #+nil
+            ;; ok, what McCLIM is generating is not :yx-banded...
+            ;; (currently at least)
+            (setf (xlib:gcontext-clip-mask gc :yx-banded) rect-seq)
+            #-nil
+            ;; the region code doesn't support yx-banding...
+            ;; or does it? what does y-banding mean in this implementation?
+            ;; well, apparantly it doesn't mean what y-sorted means
+            ;; to clx :] we stick with :unsorted until that can be sorted out
+            (setf (xlib:gcontext-clip-mask gc :unsorted) rect-seq)))))))
+
 (defmethod (setf medium-clipping-region) :after (region (medium clx-medium))
   (declare (ignore region))
   (with-slots (gc) medium
-    (when gc
-      (let ((clipping-region (medium-device-region medium)))
-        (if (region-equal clipping-region +nowhere+)
-	    (setf (xlib:gcontext-clip-mask gc) #())
-	    (let ((rect-seq (clipping-region->rect-seq clipping-region)))
-	      (when rect-seq
-		#+nil
-		;; ok, what McCLIM is generating is not :yx-banded...
-		;; (currently at least)
-		(setf (xlib:gcontext-clip-mask gc :yx-banded) rect-seq)
-		#-nil
-		;; the region code doesn't support yx-banding...
-		;; or does it? what does y-banding mean in this implementation?
-		;; well, apparantly it doesn't mean what y-sorted means
-		;; to clx :] we stick with :unsorted until that can be sorted out
-		(setf (xlib:gcontext-clip-mask gc :unsorted) rect-seq))))))))
+    (when gc (%set-gc-clipping-region medium gc))))
   
 
 (defgeneric medium-gcontext (medium ink))
@@ -133,6 +151,7 @@
              (setf (xlib:gcontext-fill-style gc) :solid))))))
 
 (defmethod medium-gcontext ((medium clx-medium) (ink color))
+  (declare (optimize (debug 3)))
   (let* ((port (port medium))
 	 (mirror (port-lookup-mirror port (medium-sheet medium)))
 	 (line-style (medium-line-style medium)))
@@ -151,26 +170,12 @@
 		  (xlib:gcontext-dashes gc) (if (eq dashes t) 3
 						dashes)))))
       (setf (xlib:gcontext-function gc) boole-1)
-      (setf (xlib:gcontext-font gc) (text-style-to-X-font port (medium-text-style medium)))
       (setf (xlib:gcontext-foreground gc) (X-pixel port ink)
 	    (xlib:gcontext-background gc) (X-pixel port (medium-background medium)))
-      ;; Here is a bug with regard to clipping ... ;-( --GB )
-      #-nil ; being fixed at the moment, a bit twitchy though -- BTS
-      (let ((clipping-region (medium-device-region medium)))
-        (if (region-equal clipping-region +nowhere+)
-	    (setf (xlib:gcontext-clip-mask gc) #())
-	    (let ((rect-seq (clipping-region->rect-seq clipping-region)))
-	      (when rect-seq
-		#+nil
-		;; ok, what McCLIM is generating is not :yx-banded...
-		;; (currently at least)
-		(setf (xlib:gcontext-clip-mask gc :yx-banded) rect-seq)
-		#-nil
-		;; the region code doesn't support yx-banding...
-		;; or does it? what does y-banding mean in this implementation?
-		;; well, apparantly it doesn't mean what y-sorted means
-		;; to clx :] we stick with :unsorted until that can be sorted out
-		(setf (xlib:gcontext-clip-mask gc :unsorted) rect-seq)))))
+      (let ((fn (text-style-to-X-font port (medium-text-style medium))))
+        (when (typep fn 'xlib:font)
+          (setf (xlib:gcontext-font gc) fn)))
+      (%set-gc-clipping-region medium gc)
       gc)))
 
 (defmethod medium-gcontext ((medium clx-medium) (ink (eql +transparent-ink+)))
@@ -569,22 +574,28 @@
                        (round (rectangle-width rectangle))
                        (round (rectangle-height rectangle)))))
 
+(defun region->clipping-values (region)
+  (with-bounding-rectangle* (min-x min-y max-x max-y) region
+    (let ((clip-x (round-coordinate min-x))
+          (clip-y (round-coordinate min-y)))
+      (values clip-x
+              clip-y
+              (- (round-coordinate max-x) clip-x)
+              (- (round-coordinate max-y) clip-y)))))
+
 ; this seems to work, but find out why all of these +nowhere+s are coming from
 ; and kill them at the source...
 #-nil
 (defun clipping-region->rect-seq (clipping-region)
-  (loop
-     for region in (nreverse (mapcan
-			      (lambda (v) (unless (eq v +nowhere+) (list v)))
-			      (region-set-regions clipping-region
-						  :normalize :y-banding)))
-     as rectangle = (bounding-rectangle region)
-     for clip-x = (round-coordinate (rectangle-min-x rectangle))
-     for clip-y = (round-coordinate (rectangle-min-y rectangle))
-     nconcing (list clip-x
-		    clip-y
-		    (- (round-coordinate (rectangle-max-x rectangle)) clip-x)
-		    (- (round-coordinate (rectangle-max-y rectangle)) clip-y))))
+  (typecase clipping-region 
+    (area (multiple-value-list (region->clipping-values clipping-region)))
+    (t (loop 
+          for region in (nreverse (mapcan
+                                   (lambda (v) (unless (eq v +nowhere+) (list v)))
+                                   (region-set-regions clipping-region
+                                                       :normalize :y-banding)))
+          nconcing (multiple-value-list (region->clipping-values region))))))
+    
 
 (defmacro with-clx-graphics ((medium) &body body)
   `(let* ((port (port ,medium))




More information about the Mcclim-cvs mailing list