[uim-commit] r852 - in trunk: . m4 scm xim

ekato at freedesktop.org ekato at freedesktop.org
Wed Jun 1 07:06:54 PDT 2005


Author: ekato
Date: 2005-06-01 07:06:52 -0700 (Wed, 01 Jun 2005)
New Revision: 852

Added:
   trunk/m4/xft.m4
Modified:
   trunk/configure.ac
   trunk/scm/im-custom.scm
   trunk/xim/Makefile.am
   trunk/xim/convdisp.cpp
   trunk/xim/convdisp.h
   trunk/xim/main.cpp
   trunk/xim/xim.h
   trunk/xim/ximic.cpp
   trunk/xim/ximserver.cpp
   trunk/xim/ximserver.h
Log:
* configure.ac : Add Xft support for uim-xim.
* m4/xft.m4 : New file.
* scm/im-custom.scm : Add xim custom group.  Add new symbols
  uim-xim-use-xft-font? (default is #f) and uim-xim-xft-font-name.
* xim/xim.h (class icxatr) : Add new public member use_xft().
  Make font_set_name public.  Add new private member m_use_xft.
* xim/ximic.cpp : Include uim-compat-scm.h for using u
  uim_scm_symbol_value_bool().
(get_font_set) : Add sanity check.
(icxatr::icxatr) : Check whether to use xft fonts.
(icxatr::~icxatr) : Ditto.
(icxatr::set_atr) : Ditto.
(icxatr::use_xft) : New function.
* xim/ximserver.cpp (customContext) : Add hack to update xft
  fontname with custom.
* xim/main.cpp : Include uim-compat-scm.h.
(clear_uim_info) : New function.
(reload_uim) : Plug leak while clearing uim_info.
(main) : Setup xft fonts.
* xim/convdisp.cpp : Include Xft.h if defined
  #HAVE_XFT_UTF8_STRING.  Include uim-compat.scm.h.  Define
  DEFAULT_FONT_SIZE.
(gXftFont) : New variable.
(gXftFontName) : Ditto.
(init_default_xftfont) : New function.
(dequote) : New function to remove double quotation.
(update_default_xft_font) : New function.
(class PeWin) : Add new public member set_xftfont().  Add new
  public members mXftFont, mXftFontSize, mXftFontName.  Add new
  protected member get_fontsize(), mXftDraw, mXftColorFg,
  mXftColorFgRev.  Remove unused member mHilitGC.
(class ConvdispOv) : Add new public member use_xft().  Remove
  unused members m_initial_fontset, m_initial_lang,
  m_lang_changed.
(class ConvdispRw) : Add new public member use_xft().
(class ConvdispOs) : Ditto.
(PeWin::PeWin) : Don't create mHilitGC.  Create Xft font if
  use_xft() if true.
(PeWin::~PeWin) : Clear Xft fonts.
(PeWin::draw_char) : Draw string with Xft fonts if use_xft().
(PeWin::set_back) : Set reverse color of Xft font.
(PeWin::set_fore) : Set forground color of Xft font.
(PeWin::set_fontset) : Add sanity check.
(PeWin::set_xftfont) : New function to create Xft font according
  to requested font size.
(PeWin::get_fontsize) : New function.  Retrieve font size from
  fontset name.
(PeWin::set_size) : Change parent pixmap of mXftDraw.
(PeLineWin::draw_segment) : Set glyph width appropriately.
(ConvdispRw::use_xft) : New function.
(ConvdispOv::ConvdispOv) : Remove unused variables.
(ConvdispOv::~ConvdispOv) : Ditto.
(ConvdispOv::set_im_lang) : Ditto.
(ConvdispOv::update_icxatr) : Set Xft font.
(ConvdispOv::check_win) : Ditto.
(ConvdispOv::check_atr) : Remove unused procedure.
(ConvdispOv::layoutCharEnt) : Setup Xft glyph width if use_xft().
(ConvdispOv::use_xft) : New function.
(ConvdispOs::use_xft) : New dummy function.
* xim/ximserver.h : Add new prototypes init_default_fontset() and
  update_default_xftfont().
(UIMInfo) : Remove const.
* xim/convdisp.h (class Convdisp) : Add new virtual member
  use_xft().
* xim/Makefile.am : Add Xft flags.


Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/configure.ac	2005-06-01 14:06:52 UTC (rev 852)
@@ -130,6 +130,37 @@
    if test $ac_cv_cxx_have_stl = no; then
      use_xim="no"
    fi
+   AC_MSG_CHECKING([whether to have Xft support])
+   AM_PATH_XFT(yes, XFT=true, XFT=false)
+   if test x"$XFT" = "xtrue" ; then
+     saved_CFLAGS=$CFLAGS
+     saved_LIBS=$LIBS
+     CFLAGS="$CFLAGS $XFT_CFLAGS"
+     LIBS="$LIBS $XFT_LIBS"
+     AC_TRY_LINK([
+#include <X11/Xft/Xft.h>], [ XftFontClose(0, 0); return 1; ], 
+       [
+         AC_DEFINE(WITH_XFT, 1, [font antialiasing support])
+         AC_MSG_CHECKING([Xft UTF-8 support])
+         AC_TRY_LINK([
+#include <X11/Xft/Xft.h>
+           ], [ 
+XftDrawStringUtf8(0, 0, 0, 0, 0, 0, 0); return 0; 
+           ],
+             AC_DEFINE(HAVE_XFT_UTF8_STRING, 1, "Xft UTF8 support")
+             AC_MSG_RESULT(yes),
+             AC_MSG_RESULT(no)) 
+       ],
+       [
+         AC_MSG_RESULT([***Could not link with Xft. Install Xft if you want support for it***])
+         XFT=false
+         XFT_CFLAGS=
+         XFT_LIBS=
+       ])
+     CFLAGS=$saved_CFLAGS
+     LIBS=$saved_LIBS
+   fi
+   AM_CONDITIONAL(WITH_XFT, test x"$XFT" = "xtrue")
 fi
 
 

Added: trunk/m4/xft.m4
===================================================================
--- trunk/m4/xft.m4	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/m4/xft.m4	2005-06-01 14:06:52 UTC (rev 852)
@@ -0,0 +1,70 @@
+dnl xft.m4
+dnl Copyright (c) 2002 Henrik Kinnunen (fluxgen at linuxmail.org)
+dnl Large changes for xine-ui usage: 2004 Daniel Caujolle-Bert (f1rmb at users.sourceforge.net)
+
+dnl Permission is hereby granted, free of charge, to any person obtaining a
+dnl copy of this software and associated documentation files (the "Software"),
+dnl to deal in the Software without restriction, including without limitation
+dnl the rights to use, copy, modify, merge, publish, distribute, sublicense,
+dnl and/or sell copies of the Software, and to permit persons to whom the 
+dnl Software is furnished to do so, subject to the following conditions:
+
+dnl The above copyright notice and this permission notice shall be included in 
+dnl all copies or substantial portions of the Software. 
+
+dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+dnl DEALINGS IN THE SOFTWARE.
+
+dnl AM_PATH_XFT2([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+AC_DEFUN([AM_PATH_XFT2],
+[
+
+  if test "x$PKG_CONFIG" = "xno" ; then
+    AC_PATH_PROG(XFT_CONFIG, xft-config, no)
+    if test "x$XFT_CONFIG" = "xno" ; then
+      ifelse([$2], , :, [$2])
+    else
+      XFT_CFLAGS=`$XFT_CONFIG --cflags`
+      XFT_LIBS=`$XFT_CONFIG --libs`
+      ifelse([$1], , :, [$1])
+    fi
+  else
+    XFT_CFLAGS=`$PKG_CONFIG --cflags xft`
+    XFT_LIBS=`$PKG_CONFIG --libs xft`
+    ifelse([$1], , :, [$1])
+  fi
+
+])
+
+dnl AM_PATH_XFT(default-value, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for Xft, and define XFT_CFLAGS and XFT_LIBS
+AC_DEFUN([AM_PATH_XFT],
+[
+  AC_ARG_ENABLE(xft, [  --enable-xft            Xft (antialias) support (default=$1)],
+    [ if test "x$enableval" = "xyes"; then
+        TRY_XFT=yes
+      else
+	TRY_XFT=no
+      fi
+    ],
+      TRY_XFT=$1
+  )
+
+  if test "x$TRY_XFT" = "xyes"; then
+    AC_MSG_RESULT(yes)
+    AM_PATH_XFT2([$2],
+		 [$3]
+		 AC_MSG_RESULT([Cant find Xft libraries! Disabling Xft]))
+  else
+    AC_MSG_RESULT(no)
+	[$3]
+  fi
+
+  AC_SUBST(XFT_CFLAGS)
+  AC_SUBST(XFT_LIBS)
+])

Modified: trunk/scm/im-custom.scm
===================================================================
--- trunk/scm/im-custom.scm	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/scm/im-custom.scm	2005-06-01 14:06:52 UTC (rev 852)
@@ -362,3 +362,26 @@
   '(pathname)
   (_ "The directory which contains EB dictionary file")
   (_ "long description will be here."))
+
+
+;; uim-xim specific custom
+(define-custom-group 'xim
+		     (_ "XIM settings")
+		     (_ "long description will be here."))
+
+(define-custom 'uim-xim-use-xft-font? #f
+  '(xim preedit)
+  '(boolean)
+  (_ "Use anti-aliased fonts for Over-the-Spot/Root-Window preedit")
+  (_ "long description will be here."))
+
+(define-custom 'uim-xim-xft-font-name "Sans"
+  '(xim preedit)
+  '(string ".*")
+  (_ "Font name for preedit area (anti-aliased)")
+  (_ "long description will be here."))
+
+(custom-add-hook 'uim-xim-xft-font-name
+		 'custom-activity-hooks
+		 (lambda ()
+		   uim-xim-use-xft-font?))

Modified: trunk/xim/Makefile.am
===================================================================
--- trunk/xim/Makefile.am	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/Makefile.am	2005-06-01 14:06:52 UTC (rev 852)
@@ -14,6 +14,12 @@
 uim_xim_CPPFLAGS += -DUSE_QT_CANDWIN
 endif
 
+if WITH_XFT
+uim_xim_CFLAGS += @XFT_CFLAGS@
+uim_xim_CXXFLAGS += @XFT_CFLAGS@
+uim_xim_LDADD += @XFT_LIBS@
+endif
+
 uim_xim_SOURCES = \
 	main.cpp convdisp.cpp \
         connection.cpp ximic.cpp \

Modified: trunk/xim/convdisp.cpp
===================================================================
--- trunk/xim/convdisp.cpp	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/convdisp.cpp	2005-06-01 14:06:52 UTC (rev 852)
@@ -39,6 +39,9 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/shape.h>
+#if HAVE_XFT_UTF8_STRING
+#include <X11/Xft/Xft.h>
+#endif
 #include <stdlib.h>
 #include <locale.h>
 #include "xim.h"
@@ -48,7 +51,10 @@
 #include "xdispatch.h"
 #include "util.h"
 
+#include "uim/uim-compat-scm.h"
+
 #define UNDERLINE_HEIGHT	2
+#define DEFAULT_FONT_SIZE	16
 // Temporal hack for flashplayer plugin's broken over-the-spot XIM style
 #define FLASHPLAYER_WORKAROUND
 
@@ -67,6 +73,65 @@
 const char *fontset_ko = "-sony-fixed-medium-r-normal--16-*-*-*-c-80-iso8859-1, -daewoo-gothic-medium-r-normal--16-120-100-100-c-160-ksc5601.1987-0";
 
 
+#if HAVE_XFT_UTF8_STRING
+XftFont *gXftFont;
+char *gXftFontName;
+
+void
+init_default_xftfont() {
+    char *fontname = uim_scm_symbol_value_str("uim-xim-xft-font-name");
+    gXftFontName = fontname;
+
+    gXftFont = XftFontOpen(XimServer::gDpy, DefaultScreen(XimServer::gDpy),
+		    XFT_FAMILY, XftTypeString, fontname,
+		    XFT_PIXEL_SIZE, XftTypeDouble, (double)DEFAULT_FONT_SIZE,
+		    NULL);
+    // maybe not needed, but in case it return NULL...
+    if (!gXftFont) {
+	gXftFont = XftFontOpen(XimServer::gDpy, DefaultScreen(XimServer::gDpy),
+			XFT_FAMILY, XftTypeString, "Sans",
+			XFT_PIXEL_SIZE, XftTypeDouble, (double)DEFAULT_FONT_SIZE,
+			NULL);
+    }
+}
+
+static char *
+dequote(const char *str)
+{
+   char *ret = NULL;
+
+   if (str) {
+	int len = strlen(str);
+	if (str[0] == '"' && str[len - 1] == '"') {
+	    ret = strdup(++str);
+	    ret[len - 2] = '\0';
+	} else
+	    ret = strdup(str);
+   }
+
+   return ret;
+}
+
+void
+update_default_xftfont(const char *s) {
+    char *fontname = dequote(s);
+
+    if (fontname) {
+	XftFont *xftfont = XftFontOpen(XimServer::gDpy,
+			DefaultScreen(XimServer::gDpy),
+			XFT_FAMILY, XftTypeString, fontname,
+			XFT_PIXEL_SIZE, XftTypeDouble, (double)DEFAULT_FONT_SIZE,
+			NULL);
+	if (xftfont) {
+	    XftFontClose(XimServer::gDpy, gXftFont);
+	    free(gXftFontName);
+	    gXftFont = xftfont;
+	    gXftFontName = fontname;
+	}
+    }
+}
+#endif
+
 static XFontSet
 create_default_fontset(const char *im_lang, const char *locale) {
     char *orig_locale;
@@ -125,6 +190,9 @@
     void draw_char(int x, int y, uchar ch, int stat);
     void set_back(unsigned long p);
     void set_fore(unsigned long p);
+#if HAVE_XFT_UTF8_STRING
+    void set_xftfont(const char *xfld);
+#endif
     void set_fontset(XFontSet f);
     
     virtual void set_size(int w, int h);
@@ -135,13 +203,27 @@
     void clear();
     void draw();
     void unmap();
+
+#if HAVE_XFT_UTF8_STRING
+    XftFont *mXftFont;
+    int mXftFontSize;
+    char *mXftFontName;
+#endif
 protected:
+#if HAVE_XFT_UTF8_STRING
+    int get_fontsize(const char *xfld);
+#endif
     Window mParentWin;
     Window mWin;
     Pixmap mPixmap;
     GC mGC, mClearGC;
-    GC mHilitGC;
     unsigned int mFore, mBack;
+#if HAVE_XFT_UTF8_STRING
+    XftDraw *mXftDraw;
+    XftColor mXftColorFg;
+    XftColor mXftColorFgRev;
+    int mGlyphWidth;
+#endif
     XFontSet mFontset;
     const char *mEncoding;
     int mWidth, mHeight;
@@ -188,6 +270,7 @@
     virtual void update_icxatr();
     virtual void move_candwin();
     virtual void set_im_lang(const char *im_lang);
+    virtual bool use_xft();
 private:
     bool check_win();
     bool check_atr();
@@ -206,9 +289,6 @@
     char_ent *m_ce;
     int m_ce_len;
     PeOvWin *m_ov_win;
-    XFontSet m_initial_fontset;
-    char *m_initial_lang;
-    bool m_lang_changed;
 };
 
 // Preedit window for RootWindowStyle
@@ -221,6 +301,7 @@
     virtual void clear_preedit();
     virtual void update_icxatr();
     virtual void move_candwin();
+    virtual bool use_xft();
 private:
     PeLineWin *mPeWin;
 };
@@ -233,6 +314,7 @@
     virtual void clear_preedit();
     virtual void update_icxatr();
     virtual void move_candwin();
+    virtual bool use_xft();
 
 private:
     void compose_preedit_array(TxPacket *);
@@ -284,7 +366,6 @@
     
     mGC = XCreateGC(XimServer::gDpy, mPixmap, 0, 0);
     mClearGC = XCreateGC(XimServer::gDpy, mPixmap, 0, 0);
-    mHilitGC = XCreateGC(XimServer::gDpy, mPixmap, 0, 0);
     
     XSetBackground(XimServer::gDpy, mGC, WhitePixel(XimServer::gDpy, scr_num));
     XSetForeground(XimServer::gDpy, mGC, BlackPixel(XimServer::gDpy, scr_num));
@@ -294,7 +375,33 @@
     add_window_watch(mWin, this, EXPOSE_MASK|STRUCTURE_NOTIFY_MASK);
     mIsMapped = false; //not mapped now
     
-    mFontset = choose_default_fontset(im_lang, locale);
+    if (mConvdisp->use_xft() == true) {
+#if HAVE_XFT_UTF8_STRING
+	mXftFontSize = DEFAULT_FONT_SIZE;
+	mXftFont = gXftFont;
+	mXftFontName = gXftFontName;
+	mXftDraw = XftDrawCreate(XimServer::gDpy, mPixmap,
+			DefaultVisual(XimServer::gDpy, scr_num),
+			DefaultColormap(XimServer::gDpy, scr_num));
+	XColor dummyc, fg;
+	XAllocNamedColor(XimServer::gDpy, DefaultColormap(XimServer::gDpy, scr_num),"black", &fg, &dummyc);
+	mXftColorFg.color.red = dummyc.red;
+	mXftColorFg.color.green = dummyc.green;
+	mXftColorFg.color.blue = dummyc.blue;
+	mXftColorFg.color.alpha = 0xffff;
+	mXftColorFg.pixel = fg.pixel;
+
+	XAllocNamedColor(XimServer::gDpy, DefaultColormap(XimServer::gDpy, scr_num),"white", &fg, &dummyc);
+	mXftColorFgRev.color.red = dummyc.red;
+	mXftColorFgRev.color.green = dummyc.green;
+	mXftColorFgRev.color.blue = dummyc.blue;
+	mXftColorFgRev.color.alpha = 0xffff;
+	mXftColorFgRev.pixel = fg.pixel;
+#endif
+    } else {
+	mFontset = choose_default_fontset(im_lang, locale);
+    }
+
     mEncoding = encoding;
     
     XFlush(XimServer::gDpy);
@@ -309,7 +416,13 @@
     
     XFreeGC(XimServer::gDpy, mGC);
     XFreeGC(XimServer::gDpy, mClearGC);
-    XFreeGC(XimServer::gDpy, mHilitGC);
+#if HAVE_XFT_UTF8_STRING 
+    if (mConvdisp->use_xft() == true) {
+	XftDrawDestroy(mXftDraw);
+	if (mXftFont != gXftFont)
+	    XftFontClose(XimServer::gDpy, mXftFont);
+    }
+#endif
 
     XFlush(XimServer::gDpy);
 }
@@ -341,28 +454,38 @@
     if (stat & PE_REVERSE)
 	gc = mClearGC;
 
-#if 0
-    if (stat & PE_HILIGHT)
-	gc = mHilitGC;
-#endif
     char utf8[6];
     int len = utf8_wctomb((unsigned char *)utf8, ch);
     utf8[len] = '\0';
 
-    if (!strcmp(mEncoding, "UTF-8"))
-    	XwcDrawImageString(XimServer::gDpy, mPixmap, mFontset,
+    if (mConvdisp->use_xft() == true) {
+#ifdef HAVE_XFT_UTF8_STRING
+	XGlyphInfo ginfo;
+	XftTextExtentsUtf8(XimServer::gDpy, mXftFont, (unsigned char *)utf8, len, &ginfo);
+	mGlyphWidth = ginfo.xOff;
+	if (stat & PE_REVERSE) {
+	    XftDrawRect(mXftDraw, &mXftColorFg, x, y - (mXftFontSize - 2), ginfo.xOff, mXftFontSize);
+	    XftDrawStringUtf8(mXftDraw, &mXftColorFgRev, mXftFont, x, y, (unsigned char *)utf8, len);
+	} else {
+	    XftDrawStringUtf8(mXftDraw, &mXftColorFg, mXftFont, x, y, (unsigned char *)utf8, len);
+	}
+#endif
+    } else {
+	if (!strcmp(mEncoding, "UTF-8")) {
+    	    XwcDrawImageString(XimServer::gDpy, mPixmap, mFontset,
 			gc, x, y, &ch, 1);
-    else {
-	char *native_str;
-	XimIM *im = get_im_by_id(mConvdisp->get_context()->get_ic()->get_imid());
+	} else {
+	    char *native_str;
+	    XimIM *im = get_im_by_id(mConvdisp->get_context()->get_ic()->get_imid());
 	
-	native_str = im->utf8_to_native_str(utf8);
-	if (!native_str)
-	    return;
-	int len = strlen(native_str);
-	XmbDrawImageString(XimServer::gDpy, mPixmap, mFontset,
+	    native_str = im->utf8_to_native_str(utf8);
+	    if (!native_str)
+		return;
+	    len = strlen(native_str);
+	    XmbDrawImageString(XimServer::gDpy, mPixmap, mFontset,
 			   gc, x, y, native_str, len);
-	free(native_str);
+	    free(native_str);
+	}
     }
 }
 
@@ -371,6 +494,18 @@
     mBack = p;
     XSetBackground(XimServer::gDpy, mGC, p);
     XSetForeground(XimServer::gDpy, mClearGC, p);
+#if HAVE_XFT_UTF8_STRING
+    if (mConvdisp->use_xft() == true) {
+	XColor xcolor;
+	xcolor.pixel = p;
+	XQueryColor(XimServer::gDpy, DefaultColormap(XimServer::gDpy, DefaultScreen(XimServer::gDpy)), &xcolor);
+	mXftColorFgRev.pixel = p;
+	mXftColorFgRev.color.red = xcolor.red;
+	mXftColorFgRev.color.green = xcolor.green;
+	mXftColorFgRev.color.blue = xcolor.blue;
+	mXftColorFgRev.color.alpha = 0xffff;
+    }
+#endif
 }
 
 void PeWin::set_fore(unsigned long p)
@@ -378,13 +513,72 @@
     mFore = p;
     XSetForeground(XimServer::gDpy, mGC, p);
     XSetBackground(XimServer::gDpy, mClearGC, p);
+#if HAVE_XFT_UTF8_STRING
+    if (mConvdisp->use_xft() == true) {
+	XColor xcolor;
+	xcolor.pixel = p;
+	XQueryColor(XimServer::gDpy, DefaultColormap(XimServer::gDpy, DefaultScreen(XimServer::gDpy)), &xcolor);
+	mXftColorFg.pixel = p;
+	mXftColorFg.color.red = xcolor.red;
+	mXftColorFg.color.green = xcolor.green;
+	mXftColorFg.color.blue = xcolor.blue;
+	mXftColorFg.color.alpha = 0xffff;
+    }
+#endif
 }
 
 void PeWin::set_fontset(XFontSet f)
 {
-    mFontset = f;
+    if (f)
+	mFontset = f;
 }
 
+#if HAVE_XFT_UTF8_STRING
+void PeWin::set_xftfont(const char *xfld)
+{
+	int size = get_fontsize(xfld);
+	if (size != -1 && (mXftFontSize != size || strcmp(mXftFontName, gXftFontName))) {
+	    if (mXftFont != gXftFont)
+		XftFontClose(XimServer::gDpy, mXftFont);
+
+	    mXftFont = XftFontOpen(XimServer::gDpy,
+			    DefaultScreen(XimServer::gDpy),
+			    XFT_FAMILY, XftTypeString, gXftFontName,
+			    XFT_SIZE, XftTypeDouble, (double)size,
+			    NULL);
+	    mXftFontSize = size;
+	    mXftFontName = gXftFontName;
+	}
+}
+
+int PeWin::get_fontsize(const char *xfld)
+{
+    int size;
+    char str[3];
+    const char *p = xfld;
+    int count = 0;
+    int i, j = 0;
+
+    for (i = 0; i < (int)strlen(xfld); i++) {
+	if (p[i] == '-')
+	    count++;
+	if (count == 7) {
+	    i++;
+	    while (p[i] != '-' && p[i] != '\0') {
+		str[j] = p[i];
+		i++;
+		j++;
+	    }
+	    str[j] = '\0';
+	    break;
+	}
+    }
+    if (!sscanf(str, "%d", &size))
+	return -1;
+    return size;
+}
+#endif
+
 void PeWin::set_size(int w, int h)
 {
     if (w == mWidth && h == mHeight)
@@ -394,6 +588,10 @@
     XFreePixmap(XimServer::gDpy, mPixmap);
     mPixmap = XCreatePixmap(XimServer::gDpy, DefaultRootWindow(XimServer::gDpy), w, h,
 			    DefaultDepth(XimServer::gDpy, DefaultScreen(XimServer::gDpy)));
+#if HAVE_XFT_UTF8_STRING 
+    if (mConvdisp->use_xft() == true)
+	XftDrawChange(mXftDraw, mPixmap);
+#endif
     mWidth = w;
     mHeight = h;
     clear();
@@ -469,13 +667,22 @@
     for (i = s->s.begin(); i != s->s.end(); i++) {
 	uchar ch = *i;
 	draw_char(m_x, 20, ch, s->stat);
+
+	int width;
+
+#if HAVE_XFT_UTF8_STRING
+	if (mConvdisp->use_xft() == true)
+	    width = mGlyphWidth;
+	else
+#endif
+	    width = 16;
+
 	if (s->stat & PE_UNDERLINE) {
 	    XDrawLine(XimServer::gDpy, mPixmap, mGC,
 			    m_x, 20 + UNDERLINE_HEIGHT,
-			    m_x + 16, 20 + UNDERLINE_HEIGHT);
-
+			    m_x + width, 20 + UNDERLINE_HEIGHT);
 	}
-	m_x += 16; // XXX font width
+	m_x += width;
     }
 }
 
@@ -685,13 +892,15 @@
     }
 }
 
+bool ConvdispRw::use_xft()
+{
+    return m_atr->use_xft();
+}
+
 // Over the spot style
 ConvdispOv::ConvdispOv(InputContext *k, icxatr *a) : Convdisp(k, a)
 {
     m_ov_win = 0;
-    m_initial_lang = strdup(mIMLang);
-    m_initial_fontset = NULL;
-    m_lang_changed = false;
 #ifdef FLASHPLAYER_WORKAROUND
     revised_spot_y = -1;
 #endif
@@ -701,27 +910,11 @@
 {
     if (m_ov_win)
 	delete m_ov_win;
-
-    free(m_initial_lang);
 }
 
 void ConvdispOv::set_im_lang(const char *im_lang)
 {
     mIMLang = im_lang;
-
-    if (!strcmp(m_initial_lang, im_lang)) {
-#if 0
-	if (m_initial_fontset)
-	    m_atr->font_set = m_initial_fontset;
-	else
-	    m_atr->font_set = choose_default_fontset(mLang);
-#endif
-    } else {
-#if 0
-	m_atr->font_set = choose_default_fontset(mLang);
-#endif
-	m_lang_changed = true;
-    }
 }
 
 
@@ -834,7 +1027,13 @@
 	m_atr->unset_change_mask(ICA_Background);
     }
     if (m_atr->is_changed(ICA_FontSet)) {
-	m_ov_win->set_fontset(m_atr->font_set);
+	if (use_xft() == true) {
+#if HAVE_XFT_UTF8_STRING
+	    m_ov_win->set_xftfont(m_atr->font_set_name);
+#endif
+	} else {
+	    m_ov_win->set_fontset(m_atr->font_set);
+	}
 	m_atr->unset_change_mask(ICA_FontSet);
     }
   
@@ -971,7 +1170,13 @@
     m_ov_win->set_size(m_atr->area.width, m_atr->area.height);
     m_ov_win->set_fore(m_atr->foreground_pixel);
     m_ov_win->set_back(m_atr->background_pixel);
-    m_ov_win->set_fontset(m_atr->font_set);
+    if (use_xft() == true) {
+#if HAVE_XFT_UTF8_STRING
+	m_ov_win->set_xftfont(m_atr->font_set_name);
+#endif
+    } else {
+	m_ov_win->set_fontset(m_atr->font_set);
+    }
   
     return true;
 }
@@ -993,11 +1198,9 @@
 	m_atr->area.x = 0;
 	m_atr->area.y = 0;
     }
-    if (!m_atr->has_atr(ICA_FontSet))
-	m_atr->font_set = choose_default_fontset(mIMLang, mLocaleName);
-    else {
-	if (!m_initial_fontset && !m_lang_changed)
-	    m_initial_fontset = m_atr->font_set;
+    if (!m_atr->has_atr(ICA_FontSet)) {
+	if (use_xft() == false)
+	    m_atr->font_set = choose_default_fontset(mIMLang, mLocaleName);
     }
     if (!m_atr->has_atr(ICA_LineSpace)) {
 	m_atr->line_space = 16;
@@ -1041,28 +1244,44 @@
 
     for (i = 0; i < m_ce_len; i++) {
 	uchar ch = m_ce[i].c;
-	XRectangle ink, logical;
 
-	if (!strcmp(mEncoding, "UTF-8"))
-	    XwcTextExtents(m_atr->font_set, &ch, 1, &ink, &logical);
-	else {
-	    char utf8[6];
-	    int len = utf8_wctomb((unsigned char *)utf8, ch);
+	char utf8[6];
+	int len;
+	if (use_xft() == true) {
+#if HAVE_XFT_UTF8_STRING
+	    len = utf8_wctomb((unsigned char *)utf8, ch);
 	    utf8[len] = '\0';
-	    XimIM *im = get_im_by_id(mKkContext->get_ic()->get_imid());
-	    char *str = im->utf8_to_native_str(utf8);
-	    if (!str) {
-		logical.width = 0;
-		logical.height = (i > 0) ? m_ce[i - 1].height : 0;
+
+	    XGlyphInfo ginfo;
+	    XftTextExtentsUtf8(XimServer::gDpy, m_ov_win->mXftFont, (unsigned char *)utf8, len, &ginfo);
+	    m_ce[i].width = ginfo.xOff;
+	    m_ce[i].height = m_ov_win->mXftFontSize;
+#endif
+	} else {
+	    XRectangle ink, logical;
+
+	    if (!strcmp(mEncoding, "UTF-8")) {
+		XwcTextExtents(m_atr->font_set, &ch, 1, &ink, &logical);
+		m_ce[i].width = logical.width;
+		m_ce[i].height = logical.height;
 	    } else {
-		len = strlen(str);
-		XmbTextExtents(m_atr->font_set, str, len, &ink, &logical);
-		free(str);
+		len = utf8_wctomb((unsigned char *)utf8, ch);
+		utf8[len] = '\0';
+		XimIM *im = get_im_by_id(mKkContext->get_ic()->get_imid());
+		char *str = im->utf8_to_native_str(utf8);
+		if (!str) {
+		    logical.width = 0;
+		    logical.height = (i > 0) ? m_ce[i - 1].height : 0;
+		} else {
+		    len = strlen(str);
+		    XmbTextExtents(m_atr->font_set, str, len, &ink, &logical);
+		    free(str);
+		}
+		m_ce[i].width = logical.width;
+		m_ce[i].height = logical.height;
 	    }
 	}
 
-	m_ce[i].width = logical.width;
-	m_ce[i].height = logical.height;
 	int right_limit = m_atr->area.width;
 	if (m_atr->has_atr(ICA_Area))
 	    right_limit += m_atr->area.x;
@@ -1111,6 +1330,11 @@
 }
 #endif
 
+bool ConvdispOv::use_xft()
+{
+    return m_atr->use_xft();
+}
+
 // On the spot style
 ConvdispOs::ConvdispOs(InputContext *k, icxatr *a, Connection *c)
     : Convdisp(k, a)
@@ -1276,6 +1500,11 @@
     }
 }
 
+bool ConvdispOs::use_xft()
+{
+    return true;
+}
+
 #ifdef FLASHPLAYER_WORKAROUND
 static Window getTopWindow(Display *d, Window w)
 {

Modified: trunk/xim/convdisp.h
===================================================================
--- trunk/xim/convdisp.h	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/convdisp.h	2005-06-01 14:06:52 UTC (rev 852)
@@ -54,6 +54,7 @@
     virtual void set_im_lang(const char *im_lang);
     virtual void set_locale_name(const char *locale);
     virtual InputContext *get_context();
+    virtual bool use_xft() = 0;
 
 protected:
     // Owner of mKkContext is XimIC. This is set at the time of

Modified: trunk/xim/main.cpp
===================================================================
--- trunk/xim/main.cpp	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/main.cpp	2005-06-01 14:06:52 UTC (rev 852)
@@ -57,6 +57,7 @@
 
 #include "uim/uim-util.h"
 #include "uim/uim-im-switcher.h"
+#include "uim/uim-compat-scm.h"
 
 Display *XimServer::gDpy;
 std::map<Window, XimServer *> XimServer::gServerMap;
@@ -397,6 +398,18 @@
 }
 
 static void
+clear_uim_info()
+{
+    std::list<UIMInfo>::iterator it;
+    for (it = uim_info.begin(); it != uim_info.end(); it++) {
+	free(it->name);
+	free(it->lang);
+	free(it->desc);
+    }
+    uim_info.clear();
+}
+
+static void
 init_supported_locales()
 {
     std::list<char *> locale_list;
@@ -513,7 +526,7 @@
     }
 
     uim_quit();
-    uim_info.clear();
+    clear_uim_info();
     get_uim_info();
     print_uim_info();
 
@@ -596,6 +609,11 @@
     if (pretrans_setup() == -1)
 	return 0;
 
+#if HAVE_XFT_UTF8_STRING
+    if (uim_scm_symbol_value_bool("uim-xim-use-xft-font?"))
+	init_default_xftfont(); // setup Xft fonts for Ov/Rw preedit
+#endif
+
     // Handle pending events to prevent hang just after startup
     check_pending_xevent();
 

Modified: trunk/xim/xim.h
===================================================================
--- trunk/xim/xim.h	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/xim.h	2005-06-01 14:06:52 UTC (rev 852)
@@ -241,6 +241,7 @@
     void print();
     int getSize(int id);
     void set_locale_name(const char *locale);
+    bool use_xft();
 
     unsigned long input_style;
     Window client_window;
@@ -253,13 +254,14 @@
     XRectangle area;
 
     XFontSet font_set;
+    char *font_set_name;
     C16 line_space;
 
 private:
-    char *font_set_name;
     char *m_locale;
     int atr_mask;
     int change_mask;
+    bool m_use_xft;
 };
 
 // definition of IC

Modified: trunk/xim/ximic.cpp
===================================================================
--- trunk/xim/ximic.cpp	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/ximic.cpp	2005-06-01 14:06:52 UTC (rev 852)
@@ -47,6 +47,8 @@
 #include "ximserver.h"
 #include "connection.h"
 #include "util.h"
+
+#include "uim-compat-scm.h"
  
 #ifdef HAVE_ALLOCA_H
 # include <alloca.h>
@@ -85,6 +87,11 @@
     if (missing)
 	XFreeStringList(missing);
 
+    if (fc.fs == NULL) {
+	fprintf(stderr, "Critical: XCreateFontSet failed!\n");
+	return NULL;
+    }
+
     fc.refc = 1;
     fc.name = strdup(name);
     fc.locale = strdup(locale);
@@ -158,16 +165,21 @@
     foreground_pixel = BlackPixel(XimServer::gDpy, DefaultScreen(XimServer::gDpy));
     background_pixel = WhitePixel(XimServer::gDpy, DefaultScreen(XimServer::gDpy));
     line_space = 0;
+#if HAVE_XFT_UTF8_STRING
+    m_use_xft = uim_scm_symbol_value_bool("uim-xim-use-xft-font?");
+#else
+    m_use_xft = false;
+#endif
 }
 
 icxatr::~icxatr()
 {
     if (font_set_name) {
-	release_font_set(font_set_name, m_locale);
+	if (use_xft() == false)
+	    release_font_set(font_set_name, m_locale);
 	free((void *)font_set_name);
     }
-    if (m_locale)
-	free(m_locale);
+    free(m_locale);
 }
 
 bool icxatr::has_atr(int id)
@@ -206,11 +218,10 @@
 	if (font_set_name && !strcmp(font_set_name, new_fsn))
 	    break;
 
-	if (font_set_name)
-	    free(font_set_name);
-
+	free(font_set_name);
 	font_set_name = strdup(new_fsn);
-	font_set = get_font_set(font_set_name, m_locale);
+	if (use_xft() == false)
+	    font_set = get_font_set(font_set_name, m_locale);
     }
     break;
     case ICA_Area:
@@ -317,6 +328,10 @@
     m_locale = strdup(locale);
 }
 
+bool icxatr::use_xft() {
+    return m_use_xft;
+}
+
 XimIC::XimIC(Connection *c, int imid, int icid, const char *engine)
 {
     mConn = c;

Modified: trunk/xim/ximserver.cpp
===================================================================
--- trunk/xim/ximserver.cpp	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/ximserver.cpp	2005-06-01 14:06:52 UTC (rev 852)
@@ -154,7 +154,11 @@
 	val++;
 	set_im(val);
     }
+#if HAVE_XFT_UTF8_STRING
+    if (!strcmp(custom, "uim-xim-xft-font-name"))
+	update_default_xftfont(val);
 #endif
+#endif
 
     std::list<InputContext *>::iterator it;
     for (it = ic_list.begin(); it != ic_list.end(); it++) {

Modified: trunk/xim/ximserver.h
===================================================================
--- trunk/xim/ximserver.h	2005-06-01 08:42:52 UTC (rev 851)
+++ trunk/xim/ximserver.h	2005-06-01 14:06:52 UTC (rev 852)
@@ -80,6 +80,10 @@
 // user interfaces
 void init_convdisp();
 void init_modifier_keys();
+#if HAVE_XFT_UTF8_STRING
+void init_default_xftfont();
+void update_default_xftfont(const char *s);
+#endif
 
 
 // for command line option
@@ -248,9 +252,9 @@
 };
 
 struct UIMInfo {
-    const char *lang;
-    const char *name;
-    const char *desc;
+    char *lang;
+    char *name;
+    char *desc;
 };
 extern std::list<UIMInfo> uim_info;
 



More information about the uim-commit mailing list