[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