diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/configure.in xemacs/configure.in --- xemacs.cvs.orig/configure.in Tue Jul 29 14:50:11 2003 +++ xemacs/configure.in Tue Jul 29 11:50:05 2003 @@ -528,6 +528,7 @@ with_hesiod | \ with_dnet | \ with_infodock | \ + with_xrender | \ with_netinstall | \ with_ipv6_cname | \ external_widget | \ @@ -2969,7 +2970,7 @@ fi libs_x="-lX11" test "$extra_verbose" = "yes" && echo " Setting libs_x to \"-lX11\"" - +p dnl Autodetect -lXext AC_CHECK_LIB(Xext, XShapeSelectInput, XE_PREPEND(-lXext, libs_x)) @@ -3037,6 +3038,19 @@ fi fi + dnl include xrender/ttf support? + + if test "$with_xrender" = "yes"; then + AC_CHECK_LIB(Xrender, XRenderQueryExtension, XE_PREPEND(-lXrender, libs_x), + [USAGE_ERROR(["Unable to find libXrender for --with-xrender"])]) + AC_CHECK_LIB(freetype, FT_Open_Face, XE_APPEND(-lfreetype, libs_x), + [USAGE_ERROR(["Unable to find libfreetype >= 2.0 for --with-xrender"])]) + AC_CHECK_LIB(Xft, XftFontOpen, XE_PREPEND(-lXft, libs_x), + [USAGE_ERROR(["Unable to find libXft for --with-xrender"])]) + AC_DEFINE(XRENDERFONT) + fi + + fi dnl $with_x11 = yes if test "$with_msw" != "no"; then @@ -5156,8 +5170,14 @@ if test "$with_xauth" != yes; then echo " - Xau (X authority) not available." fi + if test "$with_xrender" = "yes"; then + echo " Compiling in support for XRender/Xft antialiased fonts." + fi if test "$with_xmu" != yes; then echo " - Xmu library not available; substituting equivalent routines." + fi + if test "$with_xrender" != no; then + echo " - Using Xft and Xrender for antialiased font rendering." fi if test "$with_wmcommand" != no; then echo " - Handling WM_COMMAND properly." diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/lisp/dumped-lisp.el xemacs/lisp/dumped-lisp.el --- xemacs.cvs.orig/lisp/dumped-lisp.el Tue Jul 29 14:50:10 2003 +++ xemacs/lisp/dumped-lisp.el Tue Jul 29 11:50:05 2003 @@ -42,6 +42,7 @@ "obsolete" "specifier" "frame" ; needed by faces + (when (featurep 'x) "xft") ; needed by x-faces (when (featurep 'x) "x-faces") ; needed by faces (when (featurep 'gtk) "gtk-faces") (when (valid-console-type-p 'mswindows) "msw-faces") diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/lisp/font.el xemacs/lisp/font.el --- xemacs.cvs.orig/lisp/font.el Tue Jul 29 14:50:08 2003 +++ xemacs/lisp/font.el Tue Jul 29 11:50:05 2003 @@ -547,6 +547,33 @@ (defun x-font-create-object (fontname &optional device) "Return a font descriptor object for FONTNAME, appropriate for X devices." + (if (featurep 'xft-fonts) + (x-font-create-object-xft fontname device) + (x-font-create-object-core fontname device))) + +(defun x-font-create-object-xft (fontname &optional device) + (let* ((name (maybe-strip-xft-prefix fontname)) + (pattern (xft-name-parse name)) + (font-obj (make-font)) + (family (xft-pattern-get-family pattern 0)) + (size (xft-pattern-get-size pattern 0)) + (weight (xft-pattern-get-weight pattern 0)) + (enconding (xft-pattern-get-encoding pattern 0))) + (set-font-family font-obj + (and (not (equal family 'x-xft-result-no-match)) + family)) + (set-font-size font-obj + (and (not (equal size 'x-xft-result-no-match)) + size)) + (set-font-weight font-obj + (and (not (equal weight 'x-xft-result-no-match)) + (cdr (assq weight xft-font-name-weight-mapping)))) + (set-font-encoding font-obj + (and (not (equal enconding 'x-xft-result-no-match)) + enconding)) + font-obj)) + +(defun x-font-create-object-core (fontname &optional device) (let ((case-fold-search t)) (if (or (not (stringp fontname)) (not (string-match font-x-font-regexp fontname))) @@ -649,6 +676,21 @@ (font-size (font-default-object-for-device (or device (selected-device))))) (defun x-font-create-name (fontobj &optional device) + (if (featurep 'xft-fonts) + (x-font-create-name-xft fontobj device) + (x-font-create-name-core fontobj device))) + +(defun x-font-create-name-xft (fontobj &optional device) + (let* ((pattern (make-xft-pattern))) + (if (font-family fontobj) + (xft-pattern-add pattern xft-font-name-property-family + (font-family fontobj))) + (if (font-size fontobj) + (xft-pattern-add pattern xft-font-name-property-size + (font-size fontobj))) + (xft-name-unparse pattern))) + +(defun x-font-create-name-core (fontobj &optional device) "Return a font name constructed from FONTOBJ, appropriate for X devices." (if (and (not (or (font-family fontobj) (font-weight fontobj) diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/lisp/x-faces.el xemacs/lisp/x-faces.el --- xemacs.cvs.orig/lisp/x-faces.el Tue Jul 29 14:50:10 2003 +++ xemacs/lisp/x-faces.el Tue Jul 29 11:50:05 2003 @@ -66,6 +66,8 @@ '(x-get-resource-and-maybe-bogosity-check x-get-resource x-init-pointer-shape)) +(require 'xft) + (defconst x-font-regexp nil) (defconst x-font-regexp-head nil) (defconst x-font-regexp-head-2 nil) @@ -134,6 +136,11 @@ - registry - encoding "\\'")) ) +(defun x-font-xlfd-font-name-p (font) + "Check if FONT is an XLFD font name" + (and (stringp font) + (string-match x-font-regexp font))) + ;; A "loser font" is something like "8x13" -> "8x13bold". ;; These are supported only through extreme generosity. (defconst x-loser-font-regexp "\\`[0-9]+x[0-9]+\\'") @@ -167,6 +174,45 @@ (defun x-make-font-bold (font &optional device) "Given an X font specification, this attempts to make a `bold' font. If it fails, it returns nil." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-make-font-bold-core font device) + (x-make-font-bold-xft font device)) + (x-make-font-bold-core font device))) + +(defun x-make-font-bold-xft (font &optional device) + (let ((pattern (xft-font-real-pattern + font (or device (default-x-device))))) + (if pattern + (let ((size (xft-pattern-get-size pattern 0)) + (copy (xft-family-matchable-pattern pattern))) + (xft-pattern-del copy xft-font-name-property-weight) + (xft-pattern-del copy xft-font-name-property-style) + (when copy + (or + ;; try bold font + (let ((copy-2 (xft-pattern-duplicate copy))) + (xft-pattern-add copy-2 xft-font-name-property-weight + xft-font-name-weight-bold) + (when (xft-try-font copy-2 device) + (xft-pattern-add copy-2 xft-font-name-property-size size) + (xft-name-unparse copy-2))) + ;; try black font + (let ((copy-2 (xft-pattern-duplicate copy))) + (xft-pattern-add copy-2 xft-font-name-property-weight + xft-font-name-weight-black) + (when (xft-try-font copy-2 device) + (xft-pattern-add copy-2 xft-font-name-property-size size) + (xft-name-unparse copy-2))) + ;; try demibold font + (let ((copy-2 (xft-pattern-duplicate copy))) + (xft-pattern-add copy-2 xft-font-name-property-weight + xft-font-name-weight-demibold) + (when (xft-try-font copy-2 device) + (xft-pattern-add copy-2 xft-font-name-property-size size) + (xft-name-unparse copy-2))))))))) + +(defun x-make-font-bold-core (font &optional device) ;; Certain Type1 fonts know "bold" as "black"... (or (try-font-name (x-frob-font-weight font "bold") device) (try-font-name (x-frob-font-weight font "black") device) @@ -175,6 +221,23 @@ (defun x-make-font-unbold (font &optional device) "Given an X font specification, this attempts to make a non-bold font. If it fails, it returns nil." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-make-font-unbold-core font device) + (x-make-font-unbold-xft font device)) + (x-make-font-unbold-core font device))) + +(defun x-make-font-unbold-xft (font &optional device) + (let ((pattern (xft-font-real-pattern + font (or device (default-x-device))))) + (when pattern + (xft-pattern-del pattern xft-font-name-property-weight) + (xft-pattern-add pattern xft-font-name-property-weight + xft-font-name-weight-medium) + (if (xft-try-font pattern device) + (xft-name-unparse pattern))))) + +(defun x-make-font-unbold-core (font &optional device) (try-font-name (x-frob-font-weight font "medium") device)) (defcustom try-oblique-before-italic-fonts nil @@ -189,6 +252,52 @@ (defun x-make-font-italic (font &optional device) "Given an X font specification, this attempts to make an `italic' font. If it fails, it returns nil." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-make-font-italic-core font device) + (x-make-font-italic-xft font device)) + (x-make-font-italic-core font device))) + +(defun x-make-font-italic-xft (font &optional device) + (let ((pattern (xft-font-real-pattern + font (or device (default-x-device))))) + (if pattern + (let ((size (xft-pattern-get-size pattern 0)) + (copy (xft-family-matchable-pattern pattern))) + (when copy + (xft-pattern-del copy xft-font-name-property-slant) + (xft-pattern-del copy xft-font-name-property-style) + (let ((pattern-oblique (xft-pattern-duplicate copy)) + (pattern-italic (xft-pattern-duplicate copy))) + (xft-pattern-add pattern-oblique xft-font-name-property-slant + xft-font-name-slant-oblique) + (xft-pattern-add pattern-italic xft-font-name-property-slant + xft-font-name-slant-italic) + (let ((have-oblique (xft-try-font pattern-oblique device)) + (have-italic (xft-try-font pattern-italic device))) + (if try-oblique-before-italic-fonts + (if have-oblique + (progn + (if size + (xft-pattern-add pattern-oblique xft-font-name-property-size size)) + (xft-name-unparse pattern-oblique)) + (if have-italic + (progn + (if size + (xft-pattern-add pattern-italic xft-font-name-property-size size)) + (xft-name-unparse pattern-italic)))) + (if have-italic + (progn + (if size + (xft-pattern-add pattern-italic xft-font-name-property-size size)) + (xft-name-unparse pattern-italic)) + (if have-oblique + (progn + (if size + (xft-pattern-add pattern-oblique xft-font-name-property-size size)) + (xft-name-unparse pattern-oblique)))))))))))) + +(defun x-make-font-italic-core (font &optional device) (if try-oblique-before-italic-fonts (or (try-font-name (x-frob-font-slant font "o") device) (try-font-name (x-frob-font-slant font "i") device)) @@ -198,11 +307,40 @@ (defun x-make-font-unitalic (font &optional device) "Given an X font specification, this attempts to make a non-italic font. If it fails, it returns nil." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-make-font-unitalic-core font device) + (x-make-font-unitalic-xft font device)) + (x-make-font-unitalic-core font device))) + +(defun x-make-font-unitalic-xft (font &optional device) + (let ((pattern (xft-font-real-pattern + font (or device (default-x-device))))) + (when pattern + (xft-pattern-del pattern xft-font-name-property-slant) + (xft-pattern-add pattern xft-font-name-property-slant + xft-font-name-slant-roman) + (if (xft-try-font pattern device) + (xft-name-unparse pattern))))) + +(defun x-make-font-unitalic-core (font &optional device) (try-font-name (x-frob-font-slant font "r") device)) (defun x-make-font-bold-italic (font &optional device) "Given an X font specification, this attempts to make a `bold-italic' font. If it fails, it returns nil." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-make-font-bold-italic-core font device) + (x-make-font-bold-italic-xft font device)) + (x-make-font-bold-italic-core font device))) + +(defun x-make-font-bold-italic-xft (font &optional device) + (let ((italic (x-make-font-italic-xft font device))) + (if italic + (x-make-font-bold-xft italic device)))) + +(defun x-make-font-bold-italic-core (font &optional device) ;; This is haired up to avoid loading the "intermediate" fonts. (if try-oblique-before-italic-fonts (or (try-font-name @@ -236,6 +374,21 @@ X fonts can be specified (by the user) in either pixels or 10ths of points, and this returns the first one it finds, so you have to decide which units the returned value is measured in yourself..." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-font-size-core font) + (x-font-size-xft font)) + (x-font-size-core font))) + +;; this is unbelievable &*@# +(defun x-font-size-xft (font) + (let ((pattern (xft-font-real-pattern + font (default-x-device)))) + (when pattern + (let ((pixelsize (xft-pattern-get-pixelsize pattern 0))) + (if (floatp pixelsize) (round pixelsize)))))) + +(defun x-font-size-core (font) (if (font-instance-p font) (setq font (font-instance-name font))) (cond ((or (string-match x-font-regexp font) (string-match x-font-regexp-head-2 font)) @@ -354,6 +507,29 @@ Returns the font if it succeeds, nil otherwise. If scalable fonts are available, this returns a font which is 1 point smaller. Otherwise, it returns the next smaller version of this font that is defined." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-find-smaller-font-core font device) + (x-find-smaller-font-xft font device)) + (x-find-smaller-font-core font device))) + +(defun x-find-xft-font-of-size (font new-size-proc &optional device) + (let* ((pattern (xft-font-real-pattern + font (or device (default-x-device))))) + (when pattern + (let ((size (xft-pattern-get-size pattern 0))) + (if (floatp size) + (let ((copy (xft-pattern-duplicate pattern))) + (xft-pattern-del copy xft-font-name-property-size) + (xft-pattern-add copy xft-font-name-property-size + (funcall new-size-proc size)) + (if (xft-try-font font device) + (xft-name-unparse copy)))))))) + +(defun x-find-smaller-font-xft (font &optional device) + (x-find-xft-font-of-size font '(lambda (old-size) (- old-size 1.0)) device)) + +(defun x-find-smaller-font-core (font &optional device) (x-frob-font-size font nil device)) (defun x-find-larger-font (font &optional device) @@ -361,6 +537,16 @@ Returns the font if it succeeds, nil otherwise. If scalable fonts are available, this returns a font which is 1 point larger. Otherwise, it returns the next larger version of this font that is defined." + (if (featurep 'xft-fonts) + (if (x-font-xlfd-font-name-p font) + (x-find-larger-font-core font device) + (x-find-larger-font-xft font device)) + (x-find-larger-font-core font device))) + +(defun x-find-larger-font-xft (font &optional device) + (x-find-xft-font-of-size font '(lambda (old-size) (+ old-size 1.0)) device)) + +(defun x-find-larger-font-core (font &optional device) (x-frob-font-size font t device)) (defalias 'x-make-face-bold 'make-face-bold) diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/lisp/xft.el xemacs/lisp/xft.el --- xemacs.cvs.orig/lisp/xft.el Thu Jan 1 01:00:00 1970 +++ xemacs/lisp/xft.el Tue Jul 29 13:00:54 2003 @@ -0,0 +1,93 @@ + +(defconst xft-font-name-property-family "family") +(defconst xft-font-name-property-style "style") +(defconst xft-font-name-property-slant "slant") +(defconst xft-font-name-property-weight "weight") +(defconst xft-font-name-property-size "size") +(defconst xft-font-name-property-pixelsize "pixelsize") +(defconst xft-font-name-property-encoding "encoding") +(defconst xft-font-name-property-spacing "spacing") +(defconst xft-font-name-property-foundry "foundry") +(defconst xft-font-name-property-core "core") +(defconst xft-font-name-property-antialias "antialias") +(defconst xft-font-name-property-xlfd "xlfd") +(defconst xft-font-name-property-file "file") +(defconst xft-font-name-property-index "index") +(defconst xft-font-name-property-rasterizer "rasterizer") +(defconst xft-font-name-property-outline "outline") +(defconst xft-font-name-property-scalable "scalable") +(defconst xft-font-name-property-rgba "rgba") +(defconst xft-font-name-property-render "render") +(defconst xft-font-name-property-minspace "minspace") +(defconst xft-font-name-property-dpi "dpi") +(defconst xft-font-name-property-charwidth "charwidth") +(defconst xft-font-name-property-charheight "charheight") + +(defconst xft-font-name-slant-mapping + '((0 . :roman) + (100 . :italic) + (110 . :oblique))) + +(defconst xft-font-name-weight-light 0) +(defconst xft-font-name-weight-medium 110) +(defconst xft-font-name-weight-demibold 180) +(defconst xft-font-name-weight-bold 200) +(defconst xft-font-name-weight-black 210) + +(defconst xft-font-name-weight-mapping + '((0 . :light) + (110 . :medium) + (180 . :demibold) + (200 . :bold) + (210 . :black))) + +(defconst xft-font-name-slant-roman 0) +(defconst xft-font-name-slant-italic 100) +(defconst xft-font-name-slant-oblique 110) + +(defun make-xft-pattern () + "Make a Xft pattern record" + (let ((pattern (xft-pattern-create))) + (add-finalizer pattern 'xft-pattern-destroy) + pattern)) + +(defun make-xft-objectset () + "Make a Xft objectset record" + (let ((objectset (xft-objectset-create))) + (add-finalizer objectset 'xft-objectset-destroy) + objectset)) + +(defun xft-try-font (font device) + "See if there is a matching Xft font." + (let ((objectset (make-xft-objectset)) + (device (or device (default-x-device))) + (pattern (if (xft-pattern-p font) + font + (xft-name-parse fontname)))) + (not (zerop + (xft-fontset-count + (xft-list-fonts-pattern-objects device pattern objectset)))))) + +(defun xft-family-matchable-pattern (xft-pattern) + "Make a copy of XFT-PATTERN and strip all attribute that + are not needed for matching a font of same family" + (let ((copy (xft-pattern-duplicate xft-pattern))) + (xft-pattern-del copy xft-font-name-property-size) + (xft-pattern-del copy xft-font-name-property-pixelsize) + (xft-pattern-del copy xft-font-name-property-core) + (xft-pattern-del copy xft-font-name-property-antialias) + (xft-pattern-del copy xft-font-name-property-xlfd) + (xft-pattern-del copy xft-font-name-property-file) + (xft-pattern-del copy xft-font-name-property-index) + (xft-pattern-del copy xft-font-name-property-rasterizer) + (xft-pattern-del copy xft-font-name-property-scalable) + (xft-pattern-del copy xft-font-name-property-outline) + (xft-pattern-del copy xft-font-name-property-minspace) + (xft-pattern-del copy xft-font-name-property-rgba) + (xft-pattern-del copy xft-font-name-property-render) + (xft-pattern-del copy xft-font-name-property-dpi) + (xft-pattern-del copy xft-font-name-property-charwidth) + (xft-pattern-del copy xft-font-name-property-charheight) + copy)) + +(provide 'xft) \ No newline at end of file Binary files xemacs.cvs.orig/src/.__afs73D8 and xemacs/src/.__afs73D8 differ diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/Makefile.in.in xemacs/src/Makefile.in.in --- xemacs.cvs.orig/src/Makefile.in.in Tue Jul 29 14:49:42 2003 +++ xemacs/src/Makefile.in.in Tue Jul 29 11:50:05 2003 @@ -134,9 +134,14 @@ x_objs=console-x.o device-x.o event-Xt.o frame-x.o \ glyphs-x.o objects-x.o redisplay-x.o select-x.o xgccache.o intl-x.o x_gui_objs=$(gui_objs:.o=-x.o) +#ifdef XRENDERFONT +x_objs += xft-fonts.o +#endif #ifdef HAVE_TOOLBARS x_gui_objs += toolbar-common.o #endif + + #endif #ifdef HAVE_MS_WINDOWS diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/config.h.in xemacs/src/config.h.in --- xemacs.cvs.orig/src/config.h.in Tue Jul 29 14:49:40 2003 +++ xemacs/src/config.h.in Tue Jul 29 11:50:05 2003 @@ -169,6 +169,9 @@ /* Compile in support for the X window system? */ #undef HAVE_X_WINDOWS +/* Compile with support for Xft? */ +#undef XRENDERFONT + /* Defines for building X applications */ #ifdef HAVE_X_WINDOWS /* The following will be defined if xmkmf thinks they are necessary */ diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/console-x.h xemacs/src/console-x.h --- xemacs.cvs.orig/src/console-x.h Tue Jul 29 14:49:40 2003 +++ xemacs/src/console-x.h Tue Jul 29 11:50:05 2003 @@ -48,6 +48,11 @@ #include #endif +#ifdef XRENDERFONT +#include +#include +#endif + /* R5 defines the XPointer type, but R4 doesn't. R4 also doesn't define a version number, but R5 does. */ #if (XlibSpecificationRelease < 5) diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/emacs.c xemacs/src/emacs.c --- xemacs.cvs.orig/src/emacs.c Tue Jul 29 14:49:40 2003 +++ xemacs/src/emacs.c Tue Jul 29 11:50:05 2003 @@ -1395,6 +1395,9 @@ syms_of_input_method_xlib (); #endif #endif /* HAVE_XIM */ +#ifdef XRENDERFONT + syms_of_xft_fonts(); +#endif #endif /* HAVE_X_WINDOWS */ #ifdef HAVE_MS_WINDOWS @@ -1914,6 +1917,9 @@ #endif #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_X_DIALOGS) || defined (HAVE_TOOLBARS) vars_of_gui_x (); +#endif +#ifdef XRENDERFONT + vars_of_xft_fonts (); #endif #endif /* HAVE_X_WINDOWS */ diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/faces.c xemacs/src/faces.c --- xemacs.cvs.orig/src/faces.c Tue Jul 29 14:49:41 2003 +++ xemacs/src/faces.c Tue Jul 29 11:50:05 2003 @@ -1973,7 +1973,13 @@ Lisp_Object inst_list = Qnil; #if defined (HAVE_X_WINDOWS) || defined (HAVE_GTK) - + +#ifdef XRENDERFONT + const Char_ASCII *fonts[] = + { + "Courier" + }; +#else const Char_ASCII *fonts[] = { /************** ISO-8859 fonts *************/ @@ -2104,6 +2110,7 @@ "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", "*" }; +#endif /* XRENDERFONT */ const Char_ASCII **fontptr; #ifdef HAVE_X_WINDOWS diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/inline.c xemacs/src/inline.c --- xemacs.cvs.orig/src/inline.c Tue Jul 29 14:49:41 2003 +++ xemacs/src/inline.c Tue Jul 29 11:50:05 2003 @@ -89,6 +89,9 @@ #ifdef HAVE_X_WINDOWS #include "glyphs-x.h" +#ifdef XRENDERFONT +#include "xft-fonts.h" +#endif #endif #ifdef HAVE_MS_WINDOWS diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/lrecord.h xemacs/src/lrecord.h --- xemacs.cvs.orig/src/lrecord.h Tue Jul 29 14:49:42 2003 +++ xemacs/src/lrecord.h Tue Jul 29 11:50:05 2003 @@ -200,6 +200,9 @@ lrecord_type_glyph, lrecord_type_face, lrecord_type_database, + lrecord_type_x_xft_pattern, + lrecord_type_x_xft_objectset, + lrecord_type_x_xft_fontset, lrecord_type_tooltalk_message, lrecord_type_tooltalk_pattern, lrecord_type_ldap, diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/objects-x-impl.h xemacs/src/objects-x-impl.h --- xemacs.cvs.orig/src/objects-x-impl.h Tue Jul 29 14:49:42 2003 +++ xemacs/src/objects-x-impl.h Tue Jul 29 11:50:05 2003 @@ -53,7 +53,12 @@ struct x_font_instance_data { /* X-specific information */ - XFontStruct *font; +#ifdef XRENDERFONT + XftFont * +#else + XFontStruct * +#endif + font; }; #define X_FONT_INSTANCE_DATA(f) ((struct x_font_instance_data *) (f)->data) diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/objects-x.c xemacs/src/objects-x.c --- xemacs.cvs.orig/src/objects-x.c Tue Jul 29 14:49:42 2003 +++ xemacs/src/objects-x.c Tue Jul 29 11:50:05 2003 @@ -365,10 +365,59 @@ Lisp_Object device, Error_Behavior errb) { Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device)); - XFontStruct *xf; const Extbyte *extname; + XFontStruct *xf; +#ifdef XRENDERFONT + XftFont *renderFont; +#endif LISP_STRING_TO_EXTERNAL (f->name, extname, Qx_font_name_encoding); + +#ifdef XRENDERFONT + if (XRenderFindVisualFormat (dpy, DefaultVisual + (dpy, DefaultScreen (dpy)))) /* XXX: ? */ + { + const char *p = extname; + + if (Fxft_xlfd_font_name_p(make_string(extname, strlen(extname))) == Qnil) + { + renderFont = XftFontOpenName (dpy, DefaultScreen (dpy), p); + printf("XftFontOpenName '%s'\n", p); /* XXX */ + } + else + { + XftPattern *pat = XftPatternCreate (); + /* This is the magic pattern to open core fonts ... */ + /* Dudes, I love Xft!!! */ + XftPatternAddString (pat, XFT_XLFD, extname); + XftPatternAddBool (pat, XFT_CORE, True); + XftPatternAddBool (pat, XFT_SCALABLE, False); + + renderFont = XftFontOpenPattern (dpy, pat); + printf("XftFontOpenXlfd '%s'\n", extname); /* XXX */ + } + + if (renderFont) + { + /* Found one */ + f->data = xnew (struct x_font_instance_data); + FONT_INSTANCE_TRUENAME (f) = build_string (extname); + + FONT_INSTANCE_X_FONT (f) = renderFont; + f->ascent = renderFont->ascent; + f->descent = renderFont->descent; + /* XXX fixme -- use same hack with 'n' as used below */ + f->width = renderFont->max_advance_width; + f->height = renderFont->height; + f->proportional_p = 1; /* XXX: recognize monospaced fonts!*/ + + return 1; + } else { + maybe_signal_error (Qgui_error, "Couldn't load font", f->name, Qfont, errb); + return 0; + } + } +#else xf = XLoadQueryFont (dpy, extname); if (!xf) @@ -451,16 +500,19 @@ !xf->all_chars_exist)); return 1; +#endif } -static void -x_print_font_instance (Lisp_Font_Instance *f, - Lisp_Object printcharfun, - int escapeflag) -{ - write_fmt_string (printcharfun, " 0x%lx", - (unsigned long) FONT_INSTANCE_X_FONT (f)->fid); -} +/* XXX */ + +// static void +// x_print_font_instance (Lisp_Font_Instance *f, +// Lisp_Object printcharfun, +// int escapeflag) +// { +// write_fmt_string (printcharfun, " 0x%lx", +// (unsigned long) FONT_INSTANCE_X_FONT (f)->fid); +// } static void x_finalize_font_instance (Lisp_Font_Instance *f) @@ -472,7 +524,11 @@ { Display *dpy = DEVICE_X_DISPLAY (XDEVICE (f->device)); +#ifdef XRENDERFONT + XftFontClose (dpy, FONT_INSTANCE_X_FONT (f)); +#else XFreeFont (dpy, FONT_INSTANCE_X_FONT (f)); +#endif } xfree (f->data); f->data = 0; @@ -763,94 +819,102 @@ return Qnil; } -static Lisp_Object -x_font_instance_truename (Lisp_Font_Instance *f, Error_Behavior errb) -{ - struct device *d = XDEVICE (f->device); - - if (NILP (FONT_INSTANCE_TRUENAME (f))) - { - Display *dpy = DEVICE_X_DISPLAY (d); - { - Extbyte *nameext; - - LISP_STRING_TO_EXTERNAL (f->name, nameext, Qx_font_name_encoding); - FONT_INSTANCE_TRUENAME (f) = - x_font_truename (dpy, nameext, FONT_INSTANCE_X_FONT (f)); - } - if (NILP (FONT_INSTANCE_TRUENAME (f))) - { - Lisp_Object font_instance = wrap_font_instance (f); - - - maybe_signal_error (Qgui_error, "Couldn't determine font truename", - font_instance, Qfont, errb); - /* Ok, just this once, return the font name as the truename. - (This is only used by Fequal() right now.) */ - return f->name; - } - } - return FONT_INSTANCE_TRUENAME (f); -} - -static Lisp_Object -x_font_instance_properties (Lisp_Font_Instance *f) -{ - struct device *d = XDEVICE (f->device); - int i; - Lisp_Object result = Qnil; - Display *dpy = DEVICE_X_DISPLAY (d); - XFontProp *props = FONT_INSTANCE_X_FONT (f)->properties; - - for (i = FONT_INSTANCE_X_FONT (f)->n_properties - 1; i >= 0; i--) - { - Lisp_Object name, value; - Atom atom = props [i].name; - Ibyte *name_str = 0; - Bytecount name_len; - Extbyte *namestrext = XGetAtomName (dpy, atom); - - if (namestrext) - TO_INTERNAL_FORMAT (C_STRING, namestrext, - ALLOCA, (name_str, name_len), - Qx_atom_name_encoding); - - name = (name_str ? intern_int (name_str) : Qnil); - if (name_str && - (atom == XA_FONT || - atom == DEVICE_XATOM_FOUNDRY (d) || - atom == DEVICE_XATOM_FAMILY_NAME (d) || - atom == DEVICE_XATOM_WEIGHT_NAME (d) || - atom == DEVICE_XATOM_SLANT (d) || - atom == DEVICE_XATOM_SETWIDTH_NAME (d) || - atom == DEVICE_XATOM_ADD_STYLE_NAME (d) || - atom == DEVICE_XATOM_SPACING (d) || - atom == DEVICE_XATOM_CHARSET_REGISTRY (d) || - atom == DEVICE_XATOM_CHARSET_ENCODING (d) || - !qxestrcmp_c (name_str, "CHARSET_COLLECTIONS") || - !qxestrcmp_c (name_str, "FONTNAME_REGISTRY") || - !qxestrcmp_c (name_str, "CLASSIFICATION") || - !qxestrcmp_c (name_str, "COPYRIGHT") || - !qxestrcmp_c (name_str, "DEVICE_FONT_NAME") || - !qxestrcmp_c (name_str, "FULL_NAME") || - !qxestrcmp_c (name_str, "MONOSPACED") || - !qxestrcmp_c (name_str, "QUALITY") || - !qxestrcmp_c (name_str, "RELATIVE_SET") || - !qxestrcmp_c (name_str, "RELATIVE_WEIGHT") || - !qxestrcmp_c (name_str, "STYLE"))) - { - Extbyte *val_str = XGetAtomName (dpy, props [i].card32); - - value = (val_str ? build_ext_string (val_str, Qx_atom_name_encoding) - : Qnil); - } - else - value = make_int (props [i].card32); - if (namestrext) XFree (namestrext); - result = Fcons (Fcons (name, value), result); - } - return result; -} +// static Lisp_Object +// x_font_instance_truename (Lisp_Font_Instance *f, Error_Behavior errb) +// { +// struct device *d = XDEVICE (f->device); +// +// if (NILP (FONT_INSTANCE_TRUENAME (f))) +// { +// Display *dpy = DEVICE_X_DISPLAY (d); +// { +// Extbyte *nameext; +// +// LISP_STRING_TO_EXTERNAL (f->name, nameext, Qx_font_name_encoding); +// FONT_INSTANCE_TRUENAME (f) = +// x_font_truename (dpy, nameext, FONT_INSTANCE_X_FONT (f)); +// } +// if (NILP (FONT_INSTANCE_TRUENAME (f))) +// { +// Lisp_Object font_instance = wrap_font_instance (f); +// +// +// maybe_signal_error (Qgui_error, "Couldn't determine font truename", +// font_instance, Qfont, errb); +// /* Ok, just this once, return the font name as the truename. +// (This is only used by Fequal() right now.) */ +// return f->name; +// } +// } +// return FONT_INSTANCE_TRUENAME (f); +// } + +/* XXX */ +// static Lisp_Object +// x_font_instance_properties (Lisp_Font_Instance *f) +// { +// struct device *d = XDEVICE (f->device); +// int i; +// Lisp_Object result = Qnil; +// Display *dpy = DEVICE_X_DISPLAY (d); +// XFontProp *props = NULL; +// +// #ifdef XRENDERFONT +// /* XXX FIXME */ +// if (FONT_INSTANCE_X_RENDERFONT (f)) +// return Qnil; +// #endif +// +// props = FONT_INSTANCE_X_FONT (f)->properties; +// for (i = FONT_INSTANCE_X_FONT (f)->n_properties - 1; i >= 0; i--) +// { +// Lisp_Object name, value; +// Atom atom = props [i].name; +// Ibyte *name_str = 0; +// Bytecount name_len; +// Extbyte *namestrext = XGetAtomName (dpy, atom); +// +// if (namestrext) +// TO_INTERNAL_FORMAT (C_STRING, namestrext, +// ALLOCA, (name_str, name_len), +// Qx_atom_name_encoding); +// +// name = (name_str ? intern_int (name_str) : Qnil); +// if (name_str && +// (atom == XA_FONT || +// atom == DEVICE_XATOM_FOUNDRY (d) || +// atom == DEVICE_XATOM_FAMILY_NAME (d) || +// atom == DEVICE_XATOM_WEIGHT_NAME (d) || +// atom == DEVICE_XATOM_SLANT (d) || +// atom == DEVICE_XATOM_SETWIDTH_NAME (d) || +// atom == DEVICE_XATOM_ADD_STYLE_NAME (d) || +// atom == DEVICE_XATOM_SPACING (d) || +// atom == DEVICE_XATOM_CHARSET_REGISTRY (d) || +// atom == DEVICE_XATOM_CHARSET_ENCODING (d) || +// !qxestrcmp_c (name_str, "CHARSET_COLLECTIONS") || +// !qxestrcmp_c (name_str, "FONTNAME_REGISTRY") || +// !qxestrcmp_c (name_str, "CLASSIFICATION") || +// !qxestrcmp_c (name_str, "COPYRIGHT") || +// !qxestrcmp_c (name_str, "DEVICE_FONT_NAME") || +// !qxestrcmp_c (name_str, "FULL_NAME") || +// !qxestrcmp_c (name_str, "MONOSPACED") || +// !qxestrcmp_c (name_str, "QUALITY") || +// !qxestrcmp_c (name_str, "RELATIVE_SET") || +// !qxestrcmp_c (name_str, "RELATIVE_WEIGHT") || +// !qxestrcmp_c (name_str, "STYLE"))) +// { +// Extbyte *val_str = XGetAtomName (dpy, props [i].card32); +// +// value = (val_str ? build_ext_string (val_str, Qx_atom_name_encoding) +// : Qnil); +// } +// else +// value = make_int (props [i].card32); +// if (namestrext) XFree (namestrext); +// result = Fcons (Fcons (name, value), result); +// } +// return result; +// } static Lisp_Object x_list_fonts (Lisp_Object pattern, Lisp_Object device) @@ -1001,10 +1065,10 @@ CONSOLE_HAS_METHOD (x, valid_color_name_p); CONSOLE_HAS_METHOD (x, initialize_font_instance); - CONSOLE_HAS_METHOD (x, print_font_instance); + /* CONSOLE_HAS_METHOD (x, print_font_instance); XXX */ CONSOLE_HAS_METHOD (x, finalize_font_instance); - CONSOLE_HAS_METHOD (x, font_instance_truename); - CONSOLE_HAS_METHOD (x, font_instance_properties); + /* CONSOLE_HAS_METHOD (x, font_instance_truename); XXX */ + /* CONSOLE_HAS_METHOD (x, font_instance_properties); XXX */ CONSOLE_HAS_METHOD (x, list_fonts); #ifdef MULE CONSOLE_HAS_METHOD (x, find_charset_font); @@ -1028,6 +1092,10 @@ cause problems this is set to nil by default. */ ); x_handle_non_fully_specified_fonts = 0; + +#ifdef XRENDERFONT + Fprovide (intern ("xft-fonts")); +#endif } void diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/redisplay-x.c xemacs/src/redisplay-x.c --- xemacs.cvs.orig/src/redisplay-x.c Tue Jul 29 14:49:42 2003 +++ xemacs/src/redisplay-x.c Tue Jul 29 11:50:05 2003 @@ -72,6 +72,10 @@ int xpos, face_index findex); static void x_clear_frame (struct frame *f); static void x_clear_frame_windows (Lisp_Object window); +#ifdef XRENDERFONT +static void x_xft_convert_color(Display *dpy, Colormap cmap, Pixel pixel, + XftColor *result); +#endif /* Note: We do not use the Xmb*() functions and XFontSets. @@ -215,8 +219,28 @@ /* */ /****************************************************************************/ +#ifdef XRENDERFONT +static int +x_xft_text_width_single_run (Display *dpy, XftFont *xft_font, struct textual_run *run) +{ + static XGlyphInfo glyphinfo; + + if (run->dimension == 2) { + XftTextExtents16 (dpy, + xft_font, + (XftChar16 *) run->ptr, run->len, &glyphinfo); + } else { + XftTextExtents8 (dpy, + xft_font, + run->ptr, run->len, &glyphinfo); + } + + return glyphinfo.xOff; +} +#endif + static int -x_text_width_single_run (struct face_cachel *cachel, struct textual_run *run) +x_text_width_single_run (struct frame *f, struct face_cachel *cachel, struct textual_run *run) { Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); @@ -224,12 +248,19 @@ return fi->width * run->len; else { +#ifdef XRENDERFONT + struct device *d = XDEVICE (f->device); + Display *dpy = DEVICE_X_DISPLAY (d); + + return x_xft_text_width_single_run(dpy, FONT_INSTANCE_X_FONT (fi), run); +#else if (run->dimension == 2) return XTextWidth16 (FONT_INSTANCE_X_FONT (fi), (XChar2b *) run->ptr, run->len); else return XTextWidth (FONT_INSTANCE_X_FONT (fi), (char *) run->ptr, run->len); +#endif } } @@ -253,7 +284,7 @@ nruns = separate_textual_runs (text_storage, runs, str, len); for (i = 0; i < nruns; i++) - width_so_far += x_text_width_single_run (cachel, runs + i); + width_so_far += x_text_width_single_run (f, cachel, runs + i); return width_so_far; } @@ -661,11 +692,15 @@ mask = GCGraphicsExposures | GCClipMask | GCClipXOrigin | GCClipYOrigin; mask |= GCFillStyle; +#ifndef XRENDERFONT + /* Only set the font if it's a core font */ + /* the renderfont will be set elsewhere (not part of gc) */ if (!NILP (font)) { gcv.font = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font))->fid; mask |= GCFont; } +#endif /* evil kludge! */ if (!NILP (fg) && !COLOR_INSTANCEP (fg) && !INTP (fg)) @@ -773,8 +808,7 @@ /* General variables */ struct frame *f = XFRAME (w->frame); struct device *d = XDEVICE (f->device); - Lisp_Object device; - Lisp_Object window; + Lisp_Object window = wrap_window (w); Display *dpy = DEVICE_X_DISPLAY (d); Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); @@ -790,7 +824,8 @@ /* Text-related variables */ Lisp_Object bg_pmap; GC bgc, gc; - int height; + int height = DISPLAY_LINE_HEIGHT (dl); /* XXX */ + int ypos = DISPLAY_LINE_YPOS (dl); /* XXX */ int len = Dynarr_length (buf); unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); struct textual_run *runs = alloca_array (struct textual_run, len); @@ -798,12 +833,16 @@ int i; struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); - device = wrap_device (d); - window = wrap_window (w); +#ifdef XRENDERFONT + static XftColor xft_color; /* XXX: static? */ + Colormap cmap = DEVICE_X_COLORMAP (d); + /* We probably want to cache that, but how and where? */ + /* Move it to frame-impl.h, Dude! XXX */ + XftDraw *xftDraw = XftDrawCreate (dpy, x_win, DEVICE_X_VISUAL (d), cmap); +#endif if (width < 0) width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); - height = DISPLAY_LINE_HEIGHT (dl); /* Regularize the variables passed in. */ @@ -817,11 +856,8 @@ xpos -= xoffset; /* make sure the area we are about to display is subwindow free. */ - redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), - clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); - - nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), - Dynarr_length (buf)); + redisplay_unmap_subwindows_maybe (f, clip_start, ypos, + clip_end - clip_start, height); cursor_clip = (cursor_start >= clip_start && cursor_start < clip_end); @@ -864,9 +900,12 @@ if (bgc) XFillRectangle (dpy, x_win, bgc, clip_start, - DISPLAY_LINE_YPOS (dl), clip_end - clip_start, + ypos, clip_end - clip_start, height); + nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), + Dynarr_length (buf)); + for (i = 0; i < nruns; i++) { Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); @@ -877,10 +916,11 @@ if (EQ (font, Vthe_null_font_instance)) continue; - this_width = x_text_width_single_run (cachel, runs + i); + this_width = x_text_width_single_run (f, cachel, runs + i); need_clipping = (dl->clip || clip_start > xpos || clip_end < xpos + this_width); + /* XDrawImageString only clears the area equal to the height of the given font. It is possible that a font is being displayed on a line taller than it is, so this would cause us to fail to @@ -896,8 +936,8 @@ ypos1_string = dl->ypos - fi->ascent; ypos2_string = dl->ypos + fi->descent; - ypos1_line = DISPLAY_LINE_YPOS (dl); - ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl); + ypos1_line = ypos; + ypos2_line = ypos1_line + height; /* Make sure we don't clear below the real bottom of the line. */ @@ -923,7 +963,7 @@ else { redisplay_clear_region (window, findex, clear_start, - DISPLAY_LINE_YPOS (dl), clear_end - clear_start, + ypos, clear_end - clear_start, height); } } @@ -947,37 +987,79 @@ gc = x_get_gc (d, font, cachel->foreground, cachel->background, Qnil, Qnil); - if (need_clipping) - { - XRectangle clip_box[1]; +#ifdef XRENDERFONT + { + XftFont *renderFont = FONT_INSTANCE_X_FONT (fi); + XGCValues values; - clip_box[0].x = 0; - clip_box[0].y = 0; - clip_box[0].width = clip_end - clip_start; - clip_box[0].height = height; + if (need_clipping) + { + Region clip_reg = XCreateRegion(); + XRectangle clip_box = { clip_start, ypos, clip_end - clip_start, height }; - XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl), - clip_box, 1, Unsorted); - } + XUnionRectWithRegion (&clip_box, clip_reg, clip_reg); + XftDrawSetClip(xftDraw, clip_reg); + XDestroyRegion(clip_reg); + } - if (runs[i].dimension == 1) - (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, - dl->ypos, (char *) runs[i].ptr, - runs[i].len); - else - (bgc ? XDrawString16 : XDrawImageString16) (dpy, x_win, gc, xpos, - dl->ypos, - (XChar2b *) runs[i].ptr, - runs[i].len); + XGetGCValues (dpy, gc, GCForeground|GCBackground, &values); + if (!bgc) /* XXX */ + { + int rect_height = FONT_INSTANCE_ASCENT(fi) + FONT_INSTANCE_DESCENT(fi); + int rect_width = x_xft_text_width_single_run (dpy, renderFont, &runs[i]); + + x_xft_convert_color(dpy, cmap, values.background, &xft_color); + XftDrawRect (xftDraw, &xft_color, xpos, ypos, rect_width, rect_height); + } + + x_xft_convert_color(dpy, cmap, values.foreground, &xft_color); + if (runs[i].dimension == 1) + XftDrawString8 (xftDraw, + &xft_color, + renderFont, + xpos, dl->ypos, + runs[i].ptr, runs[i].len); + else + XftDrawString16 (xftDraw, + &xft_color, + renderFont, + xpos, dl->ypos, + (XftChar16 *) runs[i].ptr, runs[i].len); + } +#else + { + if (need_clipping) + { + XRectangle clip_box[1]; + + clip_box[0].x = 0; + clip_box[0].y = 0; + clip_box[0].width = clip_end - clip_start; + clip_box[0].height = height; + + XSetClipRectangles (dpy, gc, clip_start, ypos, /* XXX */ + clip_box, 1, YXBanded); + } + + if (runs[i].dimension == 1) + (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, + dl->ypos, (char *) runs[i].ptr, + runs[i].len); + else + (bgc ? XDrawString16 : XDrawImageString16) (dpy, x_win, gc, xpos, + dl->ypos, + (XChar2b *) runs[i].ptr, + runs[i].len); + } +#endif /* We draw underlines in the same color as the text. */ if (cachel->underline) { int upos, uthick; +#ifndef XRENDERFONT unsigned long upos_ext, uthick_ext; - XFontStruct *xfont; - - xfont = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)); + XFontStruct *xfont = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)); if (!XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &upos_ext)) upos = dl->descent / 2; else @@ -986,7 +1068,10 @@ uthick = 1; else uthick = (int) uthick_ext; - +#else + upos = dl->descent / 2; /* XXX */ + uthick = 1; +#endif if (dl->ypos + upos < dl->ypos + dl->descent - dl->clip) { if (dl->ypos + upos + uthick > dl->ypos + dl->descent - dl->clip) @@ -1008,10 +1093,9 @@ if (cachel->strikethru) { int ascent, descent, upos, uthick; +#ifndef XRENDERFONT unsigned long ascent_ext, descent_ext, uthick_ext; - XFontStruct *xfont; - - xfont = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)); + XFontStruct *xfont = FONT_INSTANCE_X_FONT (fi); if (!XGetFontProperty (xfont, XA_STRIKEOUT_ASCENT, &ascent_ext)) ascent = xfont->ascent; @@ -1025,6 +1109,11 @@ uthick = 1; else uthick = (int) uthick_ext; +#else + ascent = FONT_INSTANCE_ASCENT (fi); + descent = FONT_INSTANCE_DESCENT (fi); + uthick = 1; +#endif upos = ascent - ((ascent + descent) / 2) + 1; @@ -1046,39 +1135,86 @@ /* Restore the GC */ if (need_clipping) - { - XSetClipMask (dpy, gc, None); - XSetClipOrigin (dpy, gc, 0, 0); - } +#ifdef XRENDERFONT + XftDrawSetClip(xftDraw, 0); +#else + { + XSetClipMask (dpy, gc, None); /* XXX */ + XSetClipOrigin (dpy, gc, 0, 0); + } +#endif /* If we are actually superimposing the cursor then redraw with just the appropriate section highlighted. */ if (cursor_clip && !cursor && focus && cursor_cachel) +#ifdef XRENDERFONT { - GC cgc; - XRectangle clip_box[1]; - - cgc = x_get_gc (d, font, cursor_cachel->foreground, - cursor_cachel->background, Qnil, Qnil); - - clip_box[0].x = 0; - clip_box[0].y = 0; - clip_box[0].width = cursor_width; - clip_box[0].height = height; - - XSetClipRectangles (dpy, cgc, cursor_start, DISPLAY_LINE_YPOS (dl), - clip_box, 1, Unsorted); - - if (runs[i].dimension == 1) - XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, - (char *) runs[i].ptr, runs[i].len); - else - XDrawImageString16 (dpy, x_win, cgc, xpos, dl->ypos, - (XChar2b *) runs[i].ptr, runs[i].len); + XftFont *renderFont = FONT_INSTANCE_X_FONT (fi); + + { /* set up clipping */ + Region clip_reg = XCreateRegion(); + XRectangle clip_box = { cursor_start, ypos, cursor_width, height }; + + XUnionRectWithRegion (&clip_box, clip_reg, clip_reg); + XftDrawSetClip(xftDraw, clip_reg); + XDestroyRegion(clip_reg); + } + { /* draw background rectangle & draw text */ + int rect_height = FONT_INSTANCE_ASCENT(fi)+FONT_INSTANCE_DESCENT(fi); + int rect_width = x_xft_text_width_single_run(dpy, renderFont, &runs[i]); + + GC cgc = x_get_gc (d, font, cursor_cachel->foreground, + cursor_cachel->background, Qnil, Qnil); + XGCValues cvalues; + XGetGCValues (dpy, cgc, GCForeground|GCBackground, &cvalues); + + x_xft_convert_color(dpy, cmap, cvalues.background, &xft_color); + XftDrawRect (xftDraw, &xft_color, xpos, ypos, rect_width, rect_height); + + x_xft_convert_color(dpy, cmap, cvalues.foreground, &xft_color); + if (runs[i].dimension == 1) + XftDrawString8 (xftDraw, + &xft_color, + renderFont, + xpos, dl->ypos, + runs[i].ptr, runs[i].len); + else + XftDrawString16 (xftDraw, + &xft_color, + renderFont, + xpos, dl->ypos, + (XftChar16 *) runs[i].ptr, runs[i].len); + } + + XftDrawSetClip(xftDraw, 0); - XSetClipMask (dpy, cgc, None); - XSetClipOrigin (dpy, cgc, 0, 0); } +#else + { + GC cgc; + XRectangle clip_box[1]; + + cgc = x_get_gc (d, font, cursor_cachel->foreground, + cursor_cachel->background, Qnil, Qnil); + + clip_box[0].x = 0; + clip_box[0].y = 0; + clip_box[0].width = cursor_width; + clip_box[0].height = height; + + XSetClipRectangles (dpy, cgc, cursor_start, ypos, /* XXX */ + clip_box, 1, YXBanded); + if (runs[i].dimension == 1) + XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, + (char *) runs[i].ptr, runs[i].len); + else + XDrawImageString16 (dpy, x_win, cgc, xpos, dl->ypos, + (XChar2b *) runs[i].ptr, runs[i].len); + + XSetClipMask (dpy, cgc, None); /* XXX */ + XSetClipOrigin (dpy, cgc, 0, 0); + } +#endif xpos += this_width; } @@ -1126,12 +1262,12 @@ tmp_y = dl->ypos - bogusly_obtained_ascent_value; tmp_height = cursor_height; - if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height)) + if (tmp_y + tmp_height > (int) (ypos + height)) { - tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height; - if (tmp_y < (int) DISPLAY_LINE_YPOS (dl)) - tmp_y = DISPLAY_LINE_YPOS (dl); - tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y; + tmp_y = ypos + height - tmp_height; + if (tmp_y < (int) ypos) + tmp_y = ypos; + tmp_height = ypos + height - tmp_y; } if (need_clipping) @@ -1141,8 +1277,8 @@ clip_box[0].y = 0; clip_box[0].width = clip_end - clip_start; clip_box[0].height = tmp_height; - XSetClipRectangles (dpy, gc, clip_start, tmp_y, - clip_box, 1, Unsorted); + XSetClipRectangles (dpy, gc, clip_start, tmp_y, /* XXX */ + clip_box, 1, YXBanded); } if (!focus && NILP (bar_cursor_value)) @@ -1159,10 +1295,15 @@ /* Restore the GC */ if (need_clipping) { - XSetClipMask (dpy, gc, None); + XSetClipMask (dpy, gc, None); /* XXX */ XSetClipOrigin (dpy, gc, 0, 0); } } + +#ifdef XRENDERFONT + XftDrawDestroy (xftDraw); +#endif + } void @@ -1963,6 +2104,23 @@ XSync (display, 0); } } + +#ifdef XRENDERFONT +static void +x_xft_convert_color(Display *dpy, Colormap cmap, Pixel pixel, XftColor *result) +{ + static XColor color; + + color.pixel = pixel; + XQueryColor(dpy, cmap, &color); + + result->pixel = pixel; + result->color.red = color.red; + result->color.green = color.green; + result->color.blue = color.blue; + result->color.alpha = 0xffff; +} +#endif /************************************************************************/ diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/symsinit.h xemacs/src/symsinit.h --- xemacs.cvs.orig/src/symsinit.h Tue Jul 29 14:49:43 2003 +++ xemacs/src/symsinit.h Tue Jul 29 11:50:06 2003 @@ -155,6 +155,7 @@ void syms_of_objects_mswindows (void); void syms_of_objects_tty (void); void syms_of_objects_x (void); +void syms_of_xft_fonts (void); void syms_of_postgresql (void); void syms_of_print (void); void syms_of_process (void); @@ -392,6 +393,7 @@ void reinit_vars_of_mule_wnn (void); void vars_of_nt (void); void vars_of_objects (void); +void vars_of_xft_fonts (void); void reinit_vars_of_objects (void); void vars_of_objects_tty (void); void vars_of_objects_mswindows (void); diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/xft-fonts.c xemacs/src/xft-fonts.c --- xemacs.cvs.orig/src/xft-fonts.c Thu Jan 1 01:00:00 1970 +++ xemacs/src/xft-fonts.c Tue Jul 29 13:00:14 2003 @@ -0,0 +1,848 @@ +#include "xft-fonts.h" + +Lisp_Object Qx_xft_patternp; /* Do I really have to do this ??? */ +Lisp_Object Qx_xft_objectsetp; +Lisp_Object Qx_xft_fontsetp; +Lisp_Object Qx_xft_result_no_match; /* XftResultNoMatch */ +Lisp_Object Qx_xft_result_no_id; /* XftResultNoId */ +Lisp_Object Qx_xft_internal_error; +Lisp_Object Vxft_xlfd_font_regexp; + +static const struct memory_description xftpattern_description [] = { + { XD_END } +}; + +DEFINE_LRECORD_IMPLEMENTATION("xft-pattern", x_xft_pattern, + 0, 0, 0, 0, 0, 0, + xftpattern_description, + struct x_xft_pattern); + +static const struct memory_description xftobjset_description [] = { + { XD_END } +}; + +DEFINE_LRECORD_IMPLEMENTATION("xft-objectset", x_xft_objectset, + 0, 0, 0, 0, 0, 0, + xftobjset_description, + struct x_xft_objectset); + +static const struct memory_description xftfontset_description [] = { + { XD_END } +}; + +DEFINE_LRECORD_IMPLEMENTATION("xft-fontset", x_xft_fontset, + 0, 0, 0, 0, 0, 0, + xftfontset_description, + struct x_xft_fontset); + +DEFUN("xft-pattern-p", Fxft_pattern_p, 1, 1, 0, /* +Returns t if OBJECT is of type xft-pattern, nil otherwise. +*/ + (object)) +{ + return XFTPATTERNP(object) ? Qt : Qnil; +} + +DEFUN("xft-objectset-p", Fxft_objectset_p, 1, 1, 0, /* +Returns t if OBJECT is of type xft-objectset, nil otherwise. +*/ + (object)) +{ + return XFTOBJECTSETP(object) ? Qt : Qnil; +} + +DEFUN("xft-fontset-p", Fxft_fontset_p, 1, 1, 0, /* +Returns t if OBJECT is of type xft-fontset, nil otherwise. +*/ + (object)) +{ + return XFTFONTSETP(object) ? Qt : Qnil; +} + +DEFUN("xft-pattern-create", Fxft_pattern_create, 0, 0, 0, /* +Create a fresh and empty xft-pattern object. +*/ + ()) +{ + x_xft_pattern *xftpat = + alloc_lcrecord_type (struct x_xft_pattern, &lrecord_x_xft_pattern); + XXFTPATTERN_PTR(xftpat) = XftPatternCreate(); + XXFTPATTERN_CALL_FINALIZER(xftpat) = 1; + return wrap_xftpattern(xftpat); +} + +DEFUN("xft-name-parse", Fxft_name_parse, 1, 1, 0, /* +Parse an Xft font name an return its representation as a xft pattern object. +*/ + (name)) +{ + struct x_xft_pattern *xftpat = + alloc_lcrecord_type (struct x_xft_pattern, &lrecord_x_xft_pattern); + + CHECK_STRING(name); + + XXFTPATTERN_PTR(xftpat) = XftNameParse(XSTRING_DATA(name)); + XXFTPATTERN_CALL_FINALIZER(xftpat) = 1; + return wrap_xftpattern(xftpat); +} + +DEFUN("xft-name-unparse", Fxft_name_unparse, 1, 1, 0, /* +Unparse an xft pattern object to a string. +*/ + (xftpat)) +{ + char temp[XFTSTRLEN]; + Bool res; + + CHECK_XFTPATTERN(xftpat); + + res = XftNameUnparse(XXFTPATTERN_PTR(xftpat), temp, XFTSTRLEN-1); + return res ? make_string(temp, strlen(temp)) : Qnil; +} + +DEFUN("xft-pattern-duplicate", Fxft_pattern_duplicate, 1, 1, 0, /* +Make a copy of the xft pattern object XFTPAT an return it. +*/ + (xftpat)) +{ + struct x_xft_pattern *copy = NULL; + CHECK_XFTPATTERN(xftpat); + + copy = alloc_lcrecord_type (struct x_xft_pattern, &lrecord_x_xft_pattern); + XXFTPATTERN_PTR(copy) = XftPatternDuplicate(XXFTPATTERN(xftpat)->xftpatPtr); + XXFTPATTERN_CALL_FINALIZER(copy) = 1; + return wrap_xftpattern(copy); +} + +DEFUN("xft-pattern-add", Fxft_pattern_add, 3, 3, 0, /* +Add attributes to the xft pattern object XFTPAT. OBJECT is the name +of the attribute to add, VALUE the value for this attribute. +*/ + (xftpat, object, value)) +{ + Bool res; + + CHECK_XFTPATTERN(xftpat); + CHECK_STRING(object); + + if (STRINGP(value)) { + res = XftPatternAddString(XXFTPATTERN(xftpat)->xftpatPtr, + XSTRING_DATA(object), + XSTRING_DATA(value)); + return res ? Qt : Qnil; + } + + if (INTP(value)) { + res = XftPatternAddInteger(XXFTPATTERN(xftpat)->xftpatPtr, + XSTRING_DATA(object), + XINT(value)); + return res ? Qt : Qnil; + } + + if (FLOATP(value)) { + res = XftPatternAddDouble(XXFTPATTERN(xftpat)->xftpatPtr, + XSTRING_DATA(object), + (double) XFLOAT_DATA(value)); + return res ? Qt : Qnil; + } + + if (SYMBOLP(value)) { + res = XftPatternAddBool(XXFTPATTERN(xftpat)->xftpatPtr, + XSTRING_DATA(object), + !NILP(value)); + return res ? Qt : Qnil; + } + + return Fsignal(Qwrong_type_argument, "unsupported argument type"); +} + +DEFUN("xft-pattern-del", Fxft_pattern_del, 2, 2, 0, /* +Remove attribute OBJECT from xft pattern object OBJECT. +*/ + (xftpat, object)) +{ + Bool res; + + CHECK_XFTPATTERN(xftpat); + CHECK_STRING(object); + + res = XftPatternDel(XXFTPATTERN_PTR(xftpat), XSTRING_DATA(object)); + return res ? Qt : Qnil; +} + +/* primitives for XftPatternGet() -- returning strings */ +Lisp_Object +xft_get_pattern_string(Lisp_Object xftpat, Lisp_Object id, const char* objid) +{ + char *temp; + XftResult res; + + CHECK_XFTPATTERN(xftpat); + + res = XftPatternGetString(XXFTPATTERN_PTR(xftpat), + objid, XINT(id), &temp); + switch (res) { + case XftResultMatch: + return make_string(temp, strlen(temp)); + case XftResultNoMatch: + return Qx_xft_result_no_match; + case XftResultNoId: + return Qx_xft_result_no_id; + default: + return Qx_xft_internal_error; + } +} + +DEFUN("xft-pattern-get-family", Fxft_pattern_get_family, 2, 2, 0, /* +Return the family name stored in xft pattern object XFTPAT. Returns +either the family name as a string or an error code. Error codes are: +`x-xft-result-no-match' if there is no such attribute associated with +XFTPAT or `x-xft-result-no-id' if there is no value with number ID for +this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_FAMILY); +} + +DEFUN("xft-pattern-get-style", Fxft_pattern_get_style, 2, 2, 0, /* +Return the font style stored in xft pattern object XFTPAT. Returns +either the font style name as a string or an error code. Error codes +are: `x-xft-result-no-match' if there is no such attribute associated +with XFTPAT or `x-xft-result-no-id' if there is no value with number +ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_STYLE); +} + +DEFUN("xft-pattern-get-encoding", Fxft_pattern_get_encoding, 2, 2, 0, /* +Return the font encoding stored in xft pattern object XFTPAT. Returns +either the font encoding as a string or an error code. Error codes +are: `x-xft-result-no-match' if there is no such attribute associated +with XFTPAT or `x-xft-result-no-id' if there is no value with number +ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_ENCODING); +} + +DEFUN("xft-pattern-get-foundry", Fxft_pattern_get_foundry, 2, 2, 0, /* +Return the font foundry name stored in xft pattern object +XFTPAT. Returns either the font foundry name as a string or an error +code. Error codes are: `x-xft-result-no-match' if there is no such +attribute associated with XFTPAT or `x-xft-result-no-id' if there is +no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_FOUNDRY); +} + +DEFUN("xft-pattern-get-xlfd", Fxft_pattern_get_xlfd, 2, 2, 0, /* +Return the font XLFD font name stored in xft pattern object +XFTPAT. Returns either the font XLFD font name as a string or an error +code. Error codes are: `x-xft-result-no-match' if there is no such +attribute associated with XFTPAT or `x-xft-result-no-id' if there is +no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_XLFD); +} + +DEFUN("xft-pattern-get-file", Fxft_pattern_get_file, 2, 2, 0, /* +Return the font's file name stored in xft pattern object +XFTPAT. Returns either the font's file name as a string or an error +code. Error codes are: `x-xft-result-no-match' if there is no such +attribute associated with XFTPAT or `x-xft-result-no-id' if there is +no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_FILE); +} + +DEFUN("xft-pattern-get-rasterizer", Fxft_pattern_get_rasterizer, 2, 2, 0, /* +Return the name of rasterizer used to draw the font represented by xft +pattern object XFTPAT. Returns either the rasterizer name as a string +or an error code. Error codes are: `x-xft-result-no-match' if there is +no such attribute associated with XFTPAT or `x-xft-result-no-id' if +there is no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_string(xftpat, id, XFT_RASTERIZER); +} + +/* primitives for XftPatternGet() -- returning doubles */ +Lisp_Object +xft_get_pattern_double(Lisp_Object xftpat, Lisp_Object id, const char* objid) +{ + double d; + XftResult res; + + CHECK_XFTPATTERN(xftpat); + CHECK_INT(id); + + res = XftPatternGetDouble(XXFTPATTERN_PTR(xftpat), objid, XINT(id), &d); + + switch (res) { + case XftResultMatch: + return make_float(d); + case XftResultNoMatch: + return Qx_xft_result_no_match; + case XftResultNoId: + return Qx_xft_result_no_id; + default: + return Qx_xft_internal_error; + } +} + +DEFUN("xft-pattern-get-size", Fxft_pattern_get_size, 2, 2, 0, /* +Return the font size in points stored in xft pattern object +XFTPAT. Returns either the font size name as a float or an error +code. Error codes are: `x-xft-result-no-match' if there is no such +attribute associated with XFTPAT or `x-xft-result-no-id' if there is +no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_double(xftpat, id, XFT_SIZE); +} + +DEFUN("xft-pattern-get-pixelsize", Fxft_pattern_get_pixelsize, 2, 2, 0, /* +Return the font size in pixels stored in xft pattern object +XFTPAT. Returns either the font size name as a float or an error +code. Error codes are: `x-xft-result-no-match' if there is no such +attribute associated with XFTPAT or `x-xft-result-no-id' if there is +no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_double(xftpat, id, XFT_PIXEL_SIZE); +} + +DEFUN("xft-pattern-get-scale", Fxft_pattern_get_scale, 2, 2, 0, /* +Return the font scale stored in xft pattern object XFTPAT. Returns +either the font scale name as a float or an error code. Error codes +are: `x-xft-result-no-match' if there is no such attribute associated +with XFTPAT or `x-xft-result-no-id' if there is no value with number +ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_double(xftpat, id, XFT_SCALE); +} + +DEFUN("xft-pattern-get-dpi", Fxft_pattern_get_dpi, 2, 2, 0, /* +Return the font resolution in dpi stored in xft pattern object +XFTPAT. Returns either the font resolution as a float or an error +code. Error codes are: `x-xft-result-no-match' if there is no such +attribute associated with XFTPAT or `x-xft-result-no-id' if there is +no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_double(xftpat, id, XFT_DPI); +} + +/* primitives for XftPatternGet() -- returning integers */ +Lisp_Object +xft_get_pattern_integer(Lisp_Object xftpat, Lisp_Object id, const char* objid) +{ + int i; + XftResult res; + + CHECK_XFTPATTERN(xftpat); + CHECK_INT(id); + + res = XftPatternGetInteger(XXFTPATTERN_PTR(xftpat), objid, XINT(id), &i); + + switch (res) { + case XftResultMatch: + return make_int(i); + case XftResultNoMatch: + return Qx_xft_result_no_match; + case XftResultNoId: + return Qx_xft_result_no_id; + default: + return Qx_xft_internal_error; + } +} + +DEFUN("xft-pattern-get-slant", Fxft_pattern_get_slant, 2, 2, 0, /* +Return the font slant value in xft pattern object XFTPAT. Returns +either the font slant value as an integer or an error code. Error +codes are: `x-xft-result-no-match' if there is no such attribute +associated with XFTPAT or `x-xft-result-no-id' if there is no value +with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_SLANT); +} + +DEFUN("xft-pattern-get-weight", Fxft_pattern_get_weight, 2, 2, 0, /* +Return the font weight value in xft pattern object XFTPAT. Returns +either the font weight value as an integer or an error code. Error +codes are: `x-xft-result-no-match' if there is no such attribute +associated with XFTPAT or `x-xft-result-no-id' if there is no value +with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_WEIGHT); +} + +DEFUN("xft-pattern-get-spacing", Fxft_pattern_get_spacing, 2, 2, 0, /* +Return the font spacing value in xft pattern object XFTPAT. Returns +either the font spacing value as an integer or an error code. Error +codes are: `x-xft-result-no-match' if there is no such attribute +associated with XFTPAT or `x-xft-result-no-id' if there is no value +with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_SPACING); +} + +DEFUN("xft-pattern-get-index", Fxft_pattern_get_index, 2, 2, 0, /* +Return the font index value in xft pattern object XFTPAT. Returns +either the font index value as an integer or an error code. Error +codes are: `x-xft-result-no-match' if there is no such attribute +associated with XFTPAT or `x-xft-result-no-id' if there is no value +with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_INDEX); +} + +DEFUN("xft-pattern-get-rgba", Fxft_pattern_get_rgba, 2, 2, 0, /* +Return the font rgba value in xft pattern object XFTPAT. Returns +either the font rgba value as an integer or an error code. Error +codes are: `x-xft-result-no-match' if there is no such attribute +associated with XFTPAT or `x-xft-result-no-id' if there is no value +with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_RGBA); +} + +DEFUN("xft-pattern-get-char-width", Fxft_pattern_get_char_width, 2, 2, 0, /* +Return the font char width value in xft pattern object XFTPAT. Returns +either the font char width value as an integer or an error code. Error +codes are: `x-xft-result-no-match' if there is no such attribute +associated with XFTPAT or `x-xft-result-no-id' if there is no value +with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_CHAR_WIDTH); +} + +DEFUN("xft-pattern-get-char-height", Fxft_pattern_get_char_height, 2, 2, 0, /* +Return the font char height value in xft pattern object +XFTPAT. Returns either the font char height value as an integer or an +error code. Error codes are: `x-xft-result-no-match' if there is no +such attribute associated with XFTPAT or `x-xft-result-no-id' if there +is no value with number ID for this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_integer(xftpat, id, XFT_CHAR_HEIGHT); +} + +/* primitives for XftPatternGet() -- returning bools */ +Lisp_Object +xft_get_pattern_bool(Lisp_Object xftpat, Lisp_Object id, const char* objid) +{ + Bool b; + XftResult res; + + CHECK_XFTPATTERN(xftpat); + CHECK_INT(id); + + res = XftPatternGetBool(XXFTPATTERN_PTR(xftpat), objid, XINT(id), &b); + + switch (res) { + case XftResultMatch: + return b ? Qt : Qnil; + case XftResultNoMatch: + return Qx_xft_result_no_match; + case XftResultNoId: + return Qx_xft_result_no_id; + default: + /* FIXME */ + return Fsignal(Qwrong_type_argument, Qnil); + } +} + +DEFUN("xft-pattern-get-core", Fxft_pattern_get_core, 2, 2, 0, /* +Returns t if xft pattern object XFTPAT represents a core font, nil or +an error code otherwise. Error codes are: `x-xft-result-no-match' if +there is no such attribute associated with XFTPAT or +`x-xft-result-no-id' if there is no value with number ID for this +attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_bool(xftpat, id, XFT_CORE); +} + +DEFUN("xft-pattern-get-antialias", Fxft_pattern_get_antialias, 2, 2, 0, /* +Returns t if xft pattern object XFTPAT represents a antialiased font, +nil or an error code otherwise. Error codes are: +`x-xft-result-no-match' if there is no such attribute associated with +XFTPAT or `x-xft-result-no-id' if there is no value with number ID for +this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_bool(xftpat, id, XFT_ANTIALIAS); +} + +DEFUN("xft-pattern-get-outline", Fxft_pattern_get_outline, 2, 2, 0, /* +Returns t if xft pattern object XFTPAT represents an outline font, nil or +an error code otherwise. Error codes are: `x-xft-result-no-match' if +there is no such attribute associated with XFTPAT or +`x-xft-result-no-id' if there is no value with number ID for this +attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_bool(xftpat, id, XFT_OUTLINE); +} + +DEFUN("xft-pattern-get-scalable", Fxft_pattern_get_scalable, 2, 2, 0, /* +Returns t if xft pattern object XFTPAT represents a scalable font, nil or +an error code otherwise. Error codes are: `x-xft-result-no-match' if +there is no such attribute associated with XFTPAT or +`x-xft-result-no-id' if there is no value with number ID for this +attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_bool(xftpat, id, XFT_SCALABLE); +} + +DEFUN("xft-pattern-get-render", Fxft_pattern_get_render, 2, 2, 0, /* +Returns t if xft pattern object XFTPAT represents a render (Xft) font, +nil or an error code otherwise. Error codes are: +`x-xft-result-no-match' if there is no such attribute associated with +XFTPAT or `x-xft-result-no-id' if there is no value with number ID for +this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_bool(xftpat, id, XFT_RENDER); +} + +DEFUN("xft-pattern-get-minspace", Fxft_pattern_get_minspace, 2, 2, 0, /* +Returns t if xft pattern object XFTPAT represents a font with a +minspace, nil or an error code otherwise. Error codes are: +`x-xft-result-no-match' if there is no such attribute associated with +XFTPAT or `x-xft-result-no-id' if there is no value with number ID for +this attribute. */ + (xftpat, id)) +{ + return xft_get_pattern_bool(xftpat, id, XFT_MINSPACE); +} + +DEFUN("xft-pattern-destroy", Fxft_pattern_destroy, 1, 1, 0, /* +This function is used internally to deallocate a xft pattern +object. */ + (xftpat)) +{ + CHECK_XFTPATTERN(xftpat); + + if (XXFTPATTERN_CALL_FINALIZER(xftpat) != 0) + XftPatternDestroy(XXFTPATTERN_PTR(xftpat)); + + return Qnil; +} + +DEFUN("xft-font-match", Fxft_font_match, 2, 2, 0, /* +Check whether there are fonts available that match the xft pattern +XFTPAT. DEVICE is X Windows device. Returns a xft pattern object +representing the closest match to the given pattern or an error +code. Error codes are `x-xft-result-no-match' and +`x-xft-result-no-id'. */ + (device, xftpat)) +{ + Display *dpy; + XftResult res; + struct x_xft_pattern *res_xftpat = + alloc_lcrecord_type (struct x_xft_pattern, &lrecord_x_xft_pattern); + + CHECK_X_DEVICE(device); + CHECK_XFTPATTERN(xftpat); + + dpy = DEVICE_X_DISPLAY(XDEVICE(device)); + + XXFTPATTERN_CALL_FINALIZER(res_xftpat) = 1; + XXFTPATTERN_PTR(res_xftpat) = XftFontMatch(dpy, DefaultScreen (dpy), + XXFTPATTERN_PTR(xftpat), + &res); + + if (XXFTPATTERN_PTR(res_xftpat) == NULL) + switch (res) { + case XftResultNoMatch: + return Qx_xft_result_no_match; + case XftResultNoId: + return Qx_xft_result_no_id; + default: + return Qx_xft_internal_error; + } + else + return wrap_xftpattern(res_xftpat); +} + +DEFUN("xft-objectset-create", Fxft_objectset_create, 0, 0, 0, /* +Create a fresh and empty xft object set object. */ + ()) +{ + struct x_xft_objectset *objset = + alloc_lcrecord_type(struct x_xft_objectset, &lrecord_x_xft_objectset); + + XXFTOBJECTSET_PTR(objset) = XftObjectSetCreate(); + return wrap_xftobjset(objset); +} + +DEFUN("xft-objectset-add", Fxft_objectset_add, 2, 2, 0, /* +Add OBJECT (a string) to the xft object set XFTOBJECTSET. Returns t on +success, nil on failure. */ + (xftobjset, object)) +{ + Bool r; + + CHECK_XFTOBJECTSET(xftobjset); + CHECK_STRING(object); + + r = XftObjectSetAdd(XXFTOBJECTSET_PTR(xftobjset), + XSTRING_DATA(object)); + return r ? Qt : Qnil; +} + +DEFUN("xft-objectset-destroy", Fxft_objectset_destroy, 1, 1, 0, /* +Used internally to deallocate xft objectset objects. */ + (xftobjset)) +{ + CHECK_XFTOBJECTSET(xftobjset); + + XftObjectSetDestroy(XXFTOBJECTSET_PTR(xftobjset)); + return Qnil; +} + +DEFUN("xft-list-fonts-pattern-objects", Fxft_list_fonts_pattern_objects, + 3, 3, 0, /* +Given a xft pattern object XFTPAT, a xft object set object XFTOBJSET +and an X Windows device find all fonts that match XFTPAT. The result +is a xft fontset object. */ + (device, xftpat, xftobjset)) +{ + Display *dpy; + int screen; + struct x_xft_fontset *fontset = + alloc_lcrecord_type(struct x_xft_fontset, &lrecord_x_xft_fontset); + + CHECK_X_DEVICE(device); + CHECK_XFTPATTERN(xftpat); + CHECK_XFTOBJECTSET(xftobjset); + + dpy = DEVICE_X_DISPLAY(XDEVICE(device)); + screen = DefaultScreen(dpy); + + XXFTFONTSET_PTR(fontset) = + XftListFontsPatternObjects(dpy, screen, + XXFTPATTERN_PTR(xftpat), + XXFTOBJECTSET_PTR(xftobjset)); + return wrap_xftfontset(fontset); +} + +DEFUN("xft-fontset-count", Fxft_fontset_count, 1, 1, 0, /* +Counts the number of xft pattern objects stored in the xft fontset +object XFTFONTSET. */ + (xftfontset)) +{ + CHECK_XFTFONTSET(xftfontset); + + return make_int(XXFTFONTSET_PTR(xftfontset)->nfont); +} + +DEFUN("xft-fontset-ref", Fxft_fontset_ref, 2, 2, 0, /* +Return the xft pattern object at index I in xft fontset object +XFTFONTSET. Return nil if the index exceeds the bounds of +XFTFONTSET. */ + (xftfontset, i)) +{ + int idx; + x_xft_pattern *xftpat = + alloc_lcrecord_type (struct x_xft_pattern, &lrecord_x_xft_pattern); + + CHECK_XFTFONTSET(xftfontset); + CHECK_INT(i); + + idx = XINT(i); + XXFTPATTERN_CALL_FINALIZER(xftpat) = 0; + if ((idx >= 0) && (idx < XXFTFONTSET_PTR(xftfontset)->nfont)) + { + XXFTPATTERN_PTR(xftpat) = XXFTFONTSET_PTR(xftfontset)->fonts[idx]; + return wrap_xftpattern(xftpat); + } + else + return Qnil; +} + +DEFUN("xft-fontset-destroy", Fxft_fontset_destroy, 1, 1, 0, /* +Used internally to deallocate xft fontset objects. */ + (xftfontset)) +{ + CHECK_XFTFONTSET(xftfontset); + + XftFontSetDestroy(XXFTFONTSET_PTR(xftfontset)); + return Qnil; +} + +DEFUN("xft-font-real-pattern", Fxft_font_real_pattern, 2, 2, 0, /* +Open the fontname (a string) FONTNAME testwise an return the actual +xft pattern matched by the Xft library. */ + (fontname, xdevice)) +{ + Display *dpy; + XftFont *font; + struct x_xft_pattern *xftpat = + alloc_lcrecord_type (struct x_xft_pattern, &lrecord_x_xft_pattern); + XftPattern *copy; + + CHECK_STRING (fontname); + CHECK_X_DEVICE (xdevice); + + dpy = DEVICE_X_DISPLAY (XDEVICE (xdevice)); + font = XftFontOpenName (dpy, DefaultScreen(dpy), + XSTRING_DATA(fontname)); + if (font == NULL) + return Qnil; + copy = XftPatternDuplicate(font->pattern); + XftFontClose(dpy, font); + if (copy == NULL) + return Qnil; + XXFTPATTERN_PTR(xftpat) = copy; + XXFTPATTERN_CALL_FINALIZER(xftpat) = 1; + return wrap_xftpattern(xftpat); +} + + +DEFUN("xft-xlfd-font-name-p", Fxft_xlfd_font_name_p, 1, 1, 0, /* +Check whether the string FONTNAME is a XLFD font name. */ + (fontname)) +{ + CHECK_STRING(fontname); + return Fstring_match(Vxft_xlfd_font_regexp, fontname, Qnil, Qnil); +} + +Lisp_Object make_xlfd_font_regexp (void) +{ + struct gcpro gcpro1; + int i; + Lisp_Object reg = Qnil; + const char re[XFT_XLFD_RE_COUNT][XFTSTRLEN] = + { XFT_XLFD_RE_PREFIX, + XFT_XLFD_RE_FOUNDRY, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_FAMILY, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_WEIGHT, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_SLANT, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_SWIDTH, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_ADSTYLE, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_PIXELSIZE, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_POINTSIZE, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_RESX, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_RESY, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_SPACING, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_AVGWIDTH, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_REGISTRY, + XFT_XLFD_RE_MINUS, + XFT_XLFD_RE_ENCODING + }; + + GCPRO1 (reg); + for (i = 0; i <= XFT_XLFD_RE_COUNT; i++) + reg = concat2(reg, make_string(re[i], strlen((char *) re[i]))); + + RETURN_UNGCPRO (reg); +} + +/* for debugging purposes only */ +DEFUN("xft-pattern-print", Fxft_pattern_print, 1, 1, 0, /* +Print a xft pattern object to stdout. For debugging only. */ + (xftpat)) +{ + CHECK_XFTPATTERN(xftpat); + + XftPatternPrint(XXFTPATTERN_PTR(xftpat)); + return Qnil; +} + +void +syms_of_xft_fonts (void) +{ + INIT_LRECORD_IMPLEMENTATION(x_xft_pattern); + INIT_LRECORD_IMPLEMENTATION(x_xft_objectset); + INIT_LRECORD_IMPLEMENTATION(x_xft_fontset); + + DEFSYMBOL_MULTIWORD_PREDICATE(Qx_xft_patternp); + DEFSYMBOL_MULTIWORD_PREDICATE(Qx_xft_objectsetp); + DEFSYMBOL_MULTIWORD_PREDICATE(Qx_xft_fontsetp); + + DEFSYMBOL(Qx_xft_result_no_match); + DEFSYMBOL(Qx_xft_result_no_id); + DEFSYMBOL(Qx_xft_internal_error); + + DEFSUBR(Fxft_pattern_p); + DEFSUBR(Fxft_objectset_p); + DEFSUBR(Fxft_fontset_p); + DEFSUBR(Fxft_pattern_create); + DEFSUBR(Fxft_name_parse); + DEFSUBR(Fxft_name_unparse); + DEFSUBR(Fxft_pattern_duplicate); + DEFSUBR(Fxft_pattern_add); + DEFSUBR(Fxft_pattern_del); + DEFSUBR(Fxft_pattern_get_family); + DEFSUBR(Fxft_pattern_get_style); + DEFSUBR(Fxft_pattern_get_encoding); + DEFSUBR(Fxft_pattern_get_foundry); + DEFSUBR(Fxft_pattern_get_xlfd); + DEFSUBR(Fxft_pattern_get_file); + DEFSUBR(Fxft_pattern_get_rasterizer); + DEFSUBR(Fxft_pattern_get_size); + DEFSUBR(Fxft_pattern_get_pixelsize); + DEFSUBR(Fxft_pattern_get_scale); + DEFSUBR(Fxft_pattern_get_dpi); + DEFSUBR(Fxft_pattern_get_slant); + DEFSUBR(Fxft_pattern_get_weight); + DEFSUBR(Fxft_pattern_get_spacing); + DEFSUBR(Fxft_pattern_get_index); + DEFSUBR(Fxft_pattern_get_rgba); + DEFSUBR(Fxft_pattern_get_char_width); + DEFSUBR(Fxft_pattern_get_char_height); + DEFSUBR(Fxft_pattern_get_core); + DEFSUBR(Fxft_pattern_get_antialias); + DEFSUBR(Fxft_pattern_get_outline); + DEFSUBR(Fxft_pattern_get_scalable); + DEFSUBR(Fxft_pattern_get_render); + DEFSUBR(Fxft_pattern_get_minspace); + DEFSUBR(Fxft_pattern_destroy); + DEFSUBR(Fxft_objectset_create); + DEFSUBR(Fxft_objectset_add); + DEFSUBR(Fxft_objectset_destroy); + DEFSUBR(Fxft_list_fonts_pattern_objects); + DEFSUBR(Fxft_fontset_count); + DEFSUBR(Fxft_fontset_ref); + DEFSUBR(Fxft_fontset_destroy); + DEFSUBR(Fxft_font_match); + DEFSUBR(Fxft_font_real_pattern); + DEFSUBR(Fxft_pattern_print); + DEFSUBR(Fxft_xlfd_font_name_p); +} + +void +vars_of_xft_fonts (void) +{ + DEFVAR_LISP("xft-xlfd-font-regexp", &Vxft_xlfd_font_regexp /* +The regular expression used to match XLFD font names. */ + ); + Vxft_xlfd_font_regexp = make_xlfd_font_regexp(); +} diff --exclude-from=/afs/wsi/home/knauel/Library/diff-exclude -Nru xemacs.cvs.orig/src/xft-fonts.h xemacs/src/xft-fonts.h --- xemacs.cvs.orig/src/xft-fonts.h Thu Jan 1 01:00:00 1970 +++ xemacs/src/xft-fonts.h Tue Jul 29 12:56:21 2003 @@ -0,0 +1,89 @@ +#include +#include "lisp.h" +#include "device.h" +#include "device-impl.h" +#include "console-x-impl.h" + +#include + +#define XFTSTRLEN 512 + +#define XFT_XLFD_RE_COUNT 28 +#define XFT_XLFD_RE_PREFIX "\\`\\*?[-?*]" +#define XFT_XLFD_RE_MINUS "[-?]" +#define XFT_XLFD_RE_FOUNDRY "[^-]*" +#define XFT_XLFD_RE_FAMILY "[^-]*" +#define XFT_XLFD_RE_WEIGHT "\\([^-]*\\)" +#define XFT_XLFD_RE_SLANT "\\([^-]?\\)" +#define XFT_XLFD_RE_SWIDTH "\\([^-]*\\)" +#define XFT_XLFD_RE_ADSTYLE "\\([^-]*\\)" +#define XFT_XLFD_RE_PIXELSIZE "\\(\\*\\|[0-9]+\\)" +#define XFT_XLFD_RE_POINTSIZE "\\(\\*\\|0\\|[0-9][0-9]+\\)" +#define XFT_XLFD_RE_RESX "\\([*0]\\|[0-9][0-9]+\\)" +#define XFT_XLFD_RE_RESY "\\([*0]\\|[0-9][0-9]+\\)" +#define XFT_XLFD_RE_SPACING "[cmp?*]" +#define XFT_XLFD_RE_AVGWIDTH "\\(\\*\\|[0-9]+\\)" +#define XFT_XLFD_RE_REGISTRY "[^-]*" +#define XFT_XLFD_RE_ENCODING "[^-]+" + +#define XFT_XLFD_MAKE_LISP_STRING(s) (make_string(s, strlen(s))) + +struct x_xft_pattern +{ + struct lcrecord_header header; + + XftPattern *xftpatPtr; + int call_finalizer; +}; + +typedef struct x_xft_pattern x_xft_pattern; + +DECLARE_LRECORD(x_xft_pattern, struct x_xft_pattern); +#define XXFTPATTERN(x) XRECORD (x, x_xft_pattern, struct x_xft_pattern) +#define wrap_xftpattern(p) wrap_record (p, x_xft_pattern) +#define XFTPATTERNP(x) RECORDP (x, x_xft_pattern) +#define CHECK_XFTPATTERN(x) CHECK_RECORD (x, x_xft_pattern) +#define CONCHECK_XFTPATTERN(x) CONCHECK_RECORD (x, x_xft_pattern) +#define XXFTPATTERN_PTR(x) (XXFTPATTERN(x)->xftpatPtr) +#define XXFTPATTERN_CALL_FINALIZER(x) (XXFTPATTERN(x)->call_finalizer) + +struct x_xft_objectset +{ + struct lcrecord_header header; + + XftObjectSet *objsetPtr; +}; + +typedef struct x_xft_objectset x_xft_objectset; + +DECLARE_LRECORD(x_xft_objectset, struct x_xft_objectset); +#define XXFTOBJECTSET(x) XRECORD(x, x_xft_objectset, struct x_xft_objectset) +#define wrap_xftobjset(p) wrap_record (p, x_xft_objectset) +#define XFTOBJECTSETP(x) RECORDP(x, x_xft_objectset) +#define CHECK_XFTOBJECTSET(x) CHECK_RECORD(x, x_xft_objectset) +#define CONCHECK_XFTOBJECTSET(x) CONCHECK_RECORD(x, x_xft_objectset) +#define XXFTOBJECTSET_PTR(x) (XXFTOBJECTSET(x)->objsetPtr) + +struct x_xft_fontset +{ + struct lcrecord_header header; + + XftFontSet *fontsetPtr; +}; + +typedef struct x_xft_fontset x_xft_fontset; + +DECLARE_LRECORD(x_xft_fontset, struct x_xft_fontset); +#define XXFTFONTSET(x) XRECORD(x, x_xft_fontset, struct x_xft_fontset) +#define wrap_xftfontset(p) wrap_record (p, x_xft_fontset) +#define XFTFONTSETP(x) RECORDP(x, x_xft_fontset) +#define CHECK_XFTFONTSET(x) CHECK_RECORD(x, x_xft_fontset) +#define CONCHECK_XFTFONTSET(x) CONCHECK_RECORD(x, x_xft_fontset) +#define XXFTFONTSET_PTR(x) (XXFTFONTSET(x)->fontsetPtr) + +/* prototypes */ +Lisp_Object xft_get_pattern_double(Lisp_Object xftpat, Lisp_Object id, const char* objid); +Lisp_Object xft_get_pattern_integer(Lisp_Object xftpat, Lisp_Object id, const char* objid); +Lisp_Object xft_get_pattern_bool(Lisp_Object xftpat, Lisp_Object id, const char* objid); +Lisp_Object xft_get_pattern_string(Lisp_Object xftpat, Lisp_Object id, const char* objid); +Lisp_Object make_xlfd_font_regexp (void);