[mcclim-cvs] CVS mcclim/Backends/gtkairo

dlichteblau dlichteblau at common-lisp.net
Mon Apr 17 18:48:52 UTC 2006


Update of /project/mcclim/cvsroot/mcclim/Backends/gtkairo
In directory clnet:/tmp/cvs-serv16648

Modified Files:
	medium.lisp 
Log Message:
* Backends/gtkairo/medium.lisp (TEXT-STYLE-WIDTH): return max_x_advance
instead of computing 1 em.  Fixes the cursor position problem in
Climacs. (TEXT-SIZE): changed return values almost completely.  See
comments there.  (CLIMI::TEXT-BOUNDING-RECTANGLE*): Reimplemented to
look more like what CLIM-CLX does.  No real insight, but cannot be worse
than it was.


--- /project/mcclim/cvsroot/mcclim/Backends/gtkairo/medium.lisp	2006/04/17 18:40:27	1.1
+++ /project/mcclim/cvsroot/mcclim/Backends/gtkairo/medium.lisp	2006/04/17 18:48:52	1.2
@@ -590,6 +590,18 @@
 
 ;;; TEXT-STYLE-ASCENT
 
+;; FIXME: Cairo documentation states that these numbers, AIUI, are not
+;; exact measurements but rather values tweaked by the font designer for
+;; better visual effect.
+;;
+;; What this seems to mean in practise is that, say, ASCENT is nearly
+;; identical to text_extent.height in the tests I tried.
+;;
+;; So which one does CLIM want?  What are these function actually being
+;; used for?
+;;
+;;   --DFL
+
 (let ((hash (make-hash-table)))
   (defmethod text-style-ascent :around (text-style (medium gtkairo-medium))
     (or (gethash text-style hash)
@@ -653,6 +665,11 @@
 	 (cairo_font_extents cr res)
 	 ;; ### let's hope that cairo respects
 	 ;; height = ascent + descent.
+	 ;;
+	 ;; No, it expressly doesn't.  Cairo documentation states that
+	 ;; height includes additional space that is meant to give more
+	 ;; aesthetic line spacing than ascent+descent would.  Is that a
+	 ;; problem for us? --DFL
 	 (slot res 'cairo_font_extents 'height))))))
 
 
@@ -673,9 +690,13 @@
        (sync-sheet medium)
        (cairo_identity_matrix cr)
        (sync-text-style medium text-style t)
-       (cffi:with-foreign-object (res 'cairo_text_extents)
-	 (cairo_text_extents cr "m" res)
-	 (slot res 'cairo_text_extents 'width))))))
+       ;; This didn't work well for Climacs. --DFL
+;;;       (cffi:with-foreign-object (res 'cairo_text_extents)
+;;;         (cairo_text_extents cr "m" res)
+;;;         (slot res 'cairo_text_extents 'width))
+       (cffi:with-foreign-object (res 'cairo_font_extents)
+	 (cairo_font_extents cr res)
+	 (slot res 'cairo_font_extents 'max_x_advance))))))
 
 
 ;;; TEXT-STYLE-FIXED-WIDTH-P
@@ -717,6 +738,27 @@
 	       :start start
 	       :end (or end (length string)))))
 
+(defmethod climi::text-bounding-rectangle*
+    ((medium gtkairo-medium) string &key text-style (start 0) end)
+  (with-gtk ()
+    (when (characterp string) (setf string (string string)))
+    (setf text-style (or text-style (medium-text-style medium)))
+    (setf text-style
+	  (merge-text-styles text-style (medium-default-text-style medium)))
+    (climi::text-bounding-rectangle* (metrik-medium (port medium))
+				     string
+				     :text-style text-style
+				     :start start
+				     :end (or end (length string)))))
+
+;; FIXME: TEXT-SIZE [and presumably TEXT-BOUNDING-RECTANGLE*, too] are
+;; supposed to take newlines into account.  The CLX backend code was
+;; written to support that but does not -- T-B-R errors out and T-S
+;; doesn't return what WRITE-STRING on the sheet actually does.  So
+;; let's not steal code from CLIM-CLX when it's broken.  Doesn't
+;; actually look like anyone has been depending on this after all.
+;; -- DFL
+
 (defmethod text-size
     ((medium metrik-medium) string &key text-style (start 0) end)
   (with-cairo-medium (medium)
@@ -733,17 +775,46 @@
 			    (subseq string start (or end (length string)))
 			    res)
 	(cffi:with-foreign-slots
-	    ((width height x_advance y_advance) res cairo_text_extents)
-	  (values (ceiling width)
-		  (ceiling height)
-		  (ceiling x_advance)
-		  (ceiling y_advance)
-		  ;; baseline?
-		  (ceiling (text-style-ascent text-style medium))))))))
+	    ((x_advance height y_bearing) res cairo_text_extents)
+	  (values
+	   ;; use x_advance instead of width, since CLIM wants to trailing
+	   ;; spaces to be taken into account.
+	   (ceiling x_advance)
+	   (ceiling height)
+	   ;; Sames values again here: The CLIM spec states that these
+	   ;; values differ only for multi-line text.  And y_advance is 0
+	   ;; for european text, which is not what we want. --DFL
+	   (ceiling x_advance)
+	   (ceiling height)
+	   ;; This used to be TEXT-STYLE-ASCENT, but see comment there.
+	   (abs (ceiling y_bearing))))))))
 
 (defmethod climi::text-bounding-rectangle*
-    ((medium gtkairo-medium) string &key text-style (start 0) end)
-  (text-size medium string :text-style text-style :start start :end end))
+    ((medium metrik-medium) string &key text-style (start 0) end)
+  (with-cairo-medium (medium)
+    ;; -> left ascent right descent
+    (when (characterp string) (setf string (string string)))
+    (setf text-style (or text-style (make-text-style nil nil nil)))
+    (setf text-style
+	  (merge-text-styles text-style (medium-default-text-style medium)))
+    (with-slots (cr) medium
+      (cairo_identity_matrix cr)
+      (sync-text-style medium text-style t)
+      (cffi:with-foreign-object (res 'cairo_text_extents)
+	(cairo_text_extents cr
+			    (subseq string start (or end (length string)))
+			    res)
+	;; This used to be a straight call to TEXT-SIZE.  Looking at
+	;; what CLIM-CLX does, this looks better to me, but I'm not sure
+	;; whether it's 100% right:
+	;;   --DFL
+	(cffi:with-foreign-slots
+	    ((height x_advance y_advance x_bearing y_bearing)
+	     res cairo_text_extents)
+	  (values (ceiling x_bearing)
+		  (ceiling y_bearing)
+		  (ceiling x_advance)
+		  (ceiling (+ height y_bearing))))))))
 
 ;;;; ------------------------------------------------------------------------
 ;;;;  General Designs




More information about the Mcclim-cvs mailing list