[uim-commit] r1085 - trunk/xim

ekato at freedesktop.org ekato at freedesktop.org
Sun Jul 31 23:34:35 EST 2005


Author: ekato
Date: 2005-07-31 06:34:32 -0700 (Sun, 31 Jul 2005)
New Revision: 1085

Modified:
   trunk/xim/convdisp.cpp
   trunk/xim/convdisp.h
Log:
* xim/convdisp.cpp : Draw cursor even with over-the-spot and
  root-window style.
(class PeWin) : Remove mGlyphWidth and add mCharPos member.
(class PeLineWin) : Move draw_segment() from public to private.
  Add draw_cursor() and get_char_width().
(class PeOvWin) : Add draw_cursor() member.
(PeWin::PeWin) : Add sanity check for gXftFont.
(PeWin::set_xftfont) : Ditto.
(PeLineWin::draw_cursor) : New.
(PeLineWin::get_char_width) : New.
(PeLinwWin::draw_segment) : Draw cursor.
(PeLineWin::calc_segment_extent) : New.
(PeLineWin::calc_extent) : Properly calculate a needed length of
  the window.
(PeOvWin::draw_a_ce) : Draw cursor.
(PeOvWin::draw_cursor) : New.
(Convdisp::get_caret_pos) : New.
* xim/convdisp.h (class Convdisp) : Add get_caret_pos() member.


Modified: trunk/xim/convdisp.cpp
===================================================================
--- trunk/xim/convdisp.cpp	2005-07-31 07:17:49 UTC (rev 1084)
+++ trunk/xim/convdisp.cpp	2005-07-31 13:34:32 UTC (rev 1085)
@@ -214,13 +214,13 @@
     XftDraw *mXftDraw;
     XftColor mXftColorFg;
     XftColor mXftColorFgRev;
-    int mGlyphWidth;
 #endif
     XFontSet mFontset;
     const char *mEncoding;
     int mWidth, mHeight;
     bool mIsMapped;
     Convdisp *mConvdisp;
+    int mCharPos;
 };
 
 // one line preedit window for RootWindowStyle
@@ -231,10 +231,12 @@
 
     void draw_pe(pe_stat *p);
 
-    void draw_segment(pe_ustring *s);
-
 private:
     void calc_extent(pe_stat *p);
+    int calc_segment_extent(pe_ustring *s);
+    void draw_segment(pe_ustring *s);
+    void draw_cursor();
+    int get_char_width(uchar ch);
 
     int m_x;
 };
@@ -249,6 +251,7 @@
     virtual ~PeOvWin();
 private:
     void draw_a_ce(char_ent *ce);
+    void draw_cursor(char_ent *ce);
     Pixmap m_mask_pix;
     GC m_mask_pix_gc;
 };
@@ -370,6 +373,8 @@
     if (mConvdisp->use_xft() == true) {
 #if HAVE_XFT_UTF8_STRING
 	mXftFontSize = DEFAULT_FONT_SIZE;
+	if (!gXftFont)
+	    init_default_xftfont();
 	if (!strcmp(gXftFontLocale, locale)) {
 	    mXftFont = gXftFont;
 	} else {
@@ -461,7 +466,6 @@
 #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);
@@ -537,6 +541,9 @@
 {
 	int size = get_fontsize(xfld);
 	const char *locale = mConvdisp->get_locale_name();
+
+	if (!gXftFont)
+	    init_default_xftfont();
 	if (size != -1 && (mXftFontSize != size || strcmp(locale, gXftFontLocale))) {
 	    if (mXftFont != gXftFont)
 		XftFontClose(XimServer::gDpy, mXftFont);
@@ -642,9 +649,14 @@
 //
 // PeLineWin
 //
+#define PE_LINE_WIN_WIDTH	400
+#define PE_LINE_WIN_HEIGHT	28
+#define PE_LINE_WIN_FONT_POS_Y	20
+#define PE_LINE_WIN_MARGIN_X	2
+
 PeLineWin::PeLineWin(Window w, const char *im_lang, const char *encoding, const char *locale, Convdisp *cd) : PeWin(w, im_lang, encoding, locale, cd)
 {
-    set_size(400, 28); // set window height wider than its font height 16
+    set_size(PE_LINE_WIN_WIDTH, PE_LINE_WIN_HEIGHT);
     clear();
 }
 
@@ -656,43 +668,113 @@
 {
     clear();
     calc_extent(p);
-    m_x = 0;
+    m_x = PE_LINE_WIN_MARGIN_X;
+    mCharPos = 0;
     std::list<pe_ustring>::iterator i;
     for (i = p->ustrings.begin(); i != p->ustrings.end(); i++) {
 	draw_segment(&(*i));
     }
 }
 
+void PeLineWin::draw_cursor()
+{
+    int x;
+    int caret_pos = mConvdisp->get_caret_pos();
+
+    if (mCharPos == caret_pos || (mCharPos == 1 && caret_pos == 0)) {
+	if (caret_pos == 0)
+	    x = PE_LINE_WIN_MARGIN_X - 1;
+	else
+	    x = m_x - 1;
+
+	XDrawLine(XimServer::gDpy, mPixmap, mGC,
+			x,
+			(PE_LINE_WIN_HEIGHT - PE_LINE_WIN_FONT_POS_Y) / 2 + 1,
+			x,
+			PE_LINE_WIN_FONT_POS_Y + 1);
+    }
+}
+
+int PeLineWin::get_char_width(uchar ch)
+{
+    int width = 0;
+    char utf8[6];
+
+    int len = utf8_wctomb((unsigned char *)utf8, ch);
+    utf8[len] = '\0';
+
+    if (mConvdisp->use_xft() == true) {
+#ifdef HAVE_XFT_UTF8_STRING
+	XGlyphInfo ginfo;
+	XftTextExtentsUtf8(XimServer::gDpy, mXftFont, (unsigned char *)utf8,
+			len, &ginfo);
+	width = ginfo.xOff;
+#endif
+    } else {
+	XRectangle ink, logical;
+
+	if (!strcmp(mEncoding, "UTF-8")) {
+	    XwcTextExtents(mFontset, &ch, 1, &ink, &logical);
+	} 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 0;
+	    len = strlen(native_str);
+	    XmbTextExtents(mFontset, native_str, len, &ink, &logical);
+	    free(native_str);
+	}
+	width = logical.width;
+    }
+
+    return width;
+}
+
 void PeLineWin::draw_segment(pe_ustring *s)
 {
     uString::iterator i;
     for (i = s->s.begin(); i != s->s.end(); i++) {
 	uchar ch = *i;
-	draw_char(m_x, 20, ch, s->stat);
+	int width = get_char_width(ch);
+	draw_char(m_x, PE_LINE_WIN_FONT_POS_Y, ch, s->stat);
+	mCharPos++;
 
-	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 + width, 20 + UNDERLINE_HEIGHT);
+			    m_x, PE_LINE_WIN_FONT_POS_Y + UNDERLINE_HEIGHT,
+			    m_x + width, PE_LINE_WIN_FONT_POS_Y + UNDERLINE_HEIGHT);
 	}
 	m_x += width;
+	draw_cursor();
     }
 }
 
+int PeLineWin::calc_segment_extent(pe_ustring *s)
+{
+    int width = 0;
+    uString::iterator i;
+
+    for (i = s->s.begin(); i != s->s.end(); i++) {
+	uchar ch = *i;
+	width += get_char_width(ch);
+    }
+    return width;
+}
+
 void PeLineWin::calc_extent(pe_stat *p)
 {
-    int c;
-    c = p->get_char_count();
-    set_size(400, 28); // XXX need to extent
+    int width = 0;
+    std::list<pe_ustring>::iterator i;
+
+    for (i = p->ustrings.begin(); i != p->ustrings.end(); i++)
+	width += calc_segment_extent(&(*i));	
+
+    if (width < PE_LINE_WIN_WIDTH)
+	set_size(PE_LINE_WIN_WIDTH, PE_LINE_WIN_HEIGHT);
+    else
+	set_size(width + PE_LINE_WIN_MARGIN_X * 2, PE_LINE_WIN_HEIGHT);
 }
 
 
@@ -744,6 +826,7 @@
 		   WhitePixel(XimServer::gDpy,
 			      DefaultScreen(XimServer::gDpy)));
     int i;
+    mCharPos = 0;
     for (i = 0; i < len; i++) {
 	draw_a_ce(&ce[i]);
     }
@@ -755,6 +838,8 @@
 void PeOvWin::draw_a_ce(char_ent *ce)
 {
     draw_char(ce->x, ce->y, ce->c, ce->stat);
+    mCharPos++;
+
     XFillRectangle(XimServer::gDpy, m_mask_pix, m_mask_pix_gc,
 		   ce->x, ce->y - ce->height + 2,
 		   ce->width, ce->height + UNDERLINE_HEIGHT - 1);
@@ -763,8 +848,25 @@
 		  ce->x, ce->y + UNDERLINE_HEIGHT,
 		  ce->x + ce->width, ce->y + UNDERLINE_HEIGHT);
     }
+    draw_cursor(ce);
 }
 
+void PeOvWin::draw_cursor(char_ent *ce)
+{
+    int x;
+    int caret_pos = mConvdisp->get_caret_pos();
+
+    if (mCharPos == caret_pos || (mCharPos == 1 && caret_pos == 0)) {
+	if (caret_pos == 0)
+	    x = ce->x;
+	else
+	    x = ce->x + ce->width - 1;
+	XDrawLine(XimServer::gDpy, mPixmap, mGC,
+			x, ce->y - ce->height,
+			x, ce->y);
+    }
+}
+
 //
 //
 //
@@ -828,6 +930,13 @@
     return mKkContext;
 }
 
+int Convdisp::get_caret_pos()
+{
+    if (!m_pe)
+	return 0;
+    return m_pe->caret_pos;
+}
+
 // Root window style
 ConvdispRw::ConvdispRw(InputContext *k, icxatr *a) : Convdisp(k, a)
 {
@@ -1061,7 +1170,7 @@
     if (!check_win())
 	return;
 
-    m_ce = (char_ent *)malloc(sizeof(char_ent)*m_ce_len);
+    m_ce = (char_ent *)malloc(sizeof(char_ent) * m_ce_len);
     make_ce_array();
     layoutCharEnt();
     do_draw_preedit();
@@ -1210,7 +1319,7 @@
 	    m_atr->font_set = choose_default_fontset(mIMLang, mLocaleName);
     }
     if (!m_atr->has_atr(ICA_LineSpace)) {
-	m_atr->line_space = 16;
+	m_atr->line_space = DEFAULT_FONT_SIZE;
     }
 
     if (!m_atr->has_atr(ICA_Foreground))

Modified: trunk/xim/convdisp.h
===================================================================
--- trunk/xim/convdisp.h	2005-07-31 07:17:49 UTC (rev 1084)
+++ trunk/xim/convdisp.h	2005-07-31 13:34:32 UTC (rev 1085)
@@ -45,16 +45,17 @@
     virtual ~Convdisp();
     void set_pe(pe_stat *);
     uString get_pe();
+    void set_focus();
+    void unset_focus();
+    InputContext *get_context();
+    int get_caret_pos();
     virtual void update_preedit() = 0;
     virtual void clear_preedit() = 0;
     virtual void update_icxatr() = 0;
-    virtual void set_focus();
-    virtual void unset_focus();
     virtual void move_candwin() = 0;
     virtual void set_im_lang(const char *im_lang);
     virtual void set_locale_name(const char *locale);
     virtual const char *get_locale_name();
-    virtual InputContext *get_context();
     virtual bool use_xft() = 0;
 
 protected:



More information about the uim-commit mailing list