delete suggestions_popup;
suggestions->remove_all_objects();
delete suggestions;
- delete [] positions;
delete [] wtext;
if( size > 0 )
delete [] text;
wtext = 0;
wsize = 0;
wlen = 0;
- positions = 0;
- plen = 0;
keypress_draw = 1;
last_keypress = 0;
separators = 0;
wchar_t *ntext = new wchar_t[nsize+1];
memcpy(ntext, wtext, wsize*sizeof(wtext[0]));
delete [] wtext; wtext = ntext; wsize = nsize;
- int *npositions = new int[nsize+1];
- if( plen > 0 )
- memcpy(npositions, positions, (plen+1)*sizeof(positions[0]));
- else
- npositions[0] = 0;
- delete [] positions; positions = npositions; plen = nsize;
}
wlen = BC_Resources::encode(src_enc, dst_enc, text, strlen(text),
(char*)wtext, wsize*sizeof(wchar_t)) / sizeof(wchar_t);
if( col < 0 ) col = 0;
char *cur = current_suggestion + col;
tstrcat(cur);
- draw(0); // update positions
highlight_letter2 = wtext_update();
//printf("BC_TextBox::set_suggestions %d %d\n", __LINE__, suggestion_column);
set_color(color);
if(highlight_letter1 >= row_begin &&
highlight_letter1 <= row_end)
- highlight_x1 = positions[highlight_letter1];
+ highlight_x1 = get_x_position(highlight_letter1, row_begin);
else
highlight_x1 = 0;
if(highlight_letter2 > row_begin &&
highlight_letter2 <= row_end)
- highlight_x2 = positions[highlight_letter2];
+ highlight_x2 = get_x_position(highlight_letter2, row_begin);
else
highlight_x2 = get_w();
int len = row_end - row_begin;
if( len > 0 ) {
set_color(enabled ? resources->text_default : DMGREY);
- draw_wtext(text_x, k + text_ascent, wtext_row, len,
- 0, &positions[wtext_row - wtext]);
+ draw_wtext(text_x, k + text_ascent, wtext_row, len, 0);
}
- else
- positions[wtext_row - wtext] = 0;
// Get ibeam location
if(ibeam_letter >= row_begin && ibeam_letter <= row_end) {
need_ibeam = 0;
ibeam_y = k - text_y;
- ibeam_x = positions[ibeam_letter];
+ ibeam_x = get_x_position(ibeam_letter, row_begin);
}
}
}
}
}
+int BC_TextBox::get_x_position(int i, int start)
+{
+ return get_text_width(font, &wtext[start], i - start);
+}
+
void BC_TextBox::get_ibeam_position(int &x, int &y)
{
int i, row_begin, row_end;
row_end = i;
if( ibeam_letter >= row_begin && ibeam_letter <= row_end ) {
- x = get_text_width(font, &wtext[row_begin], ibeam_letter - row_begin);
+ x = get_x_position(ibeam_letter, row_begin);
//printf("BC_TextBox::get_ibeam_position %d %d %d %d %d\n", ibeam_letter, row_begin, row_end, x, y);
return;
}
// ibeam_left causes the ibeam to move left.
int is_separator(const char *txt, int i);
void do_separators(int ibeam_left);
+ int get_x_position(int i, int start=0);
void get_ibeam_position(int &x, int &y);
void find_ibeam(int dispatch_event);
void select_word(int &letter1, int &letter2, int ibeam_letter);
int high_color, back_color;
int background_color;
int size, tsize, dirty;
- int wlen, wsize, *positions, plen;
+ int wlen, wsize;
char temp_string[KEYPRESSLEN];
int is_utf8;
int active;
BC_Pixmap *pixmap = 0, int is_utf8 = 0);
void draw_xft_text(int x, int y, const wchar_t *text,
int length, BC_Pixmap *pixmap);
- void draw_wtext(int x, int y, const wchar_t *text, int length = -1,
- BC_Pixmap *pixmap = 0, int *charpos = 0);
+ void draw_wtext(int x, int y, const wchar_t *text, int length = -1, BC_Pixmap *pixmap = 0);
// truncate the text to a ... version that fits in the width, using the current_font
void truncate_text(char *result, const char *text, int w);
void draw_center_text(int x, int y, const char *text, int length = -1);
int64_t get_color_bgr24(int color);
XFontStruct* get_font_struct(int font);
XftFont* get_xft_struct(int font);
- int wcharpos(const wchar_t *text, XftFont *font, int length, int *charpos);
Cursor get_cursor_struct(int cursor);
XFontSet get_fontset(int font);
XFontSet get_curr_fontset(void);
}
}
-int BC_WindowBase::wcharpos(const wchar_t *text, XftFont *font, int length,
- int *charpos)
-{
- XGlyphInfo extents;
-
- if(charpos)
- {
- int bpos = charpos[-1];
-
- for(int i = 0; i < length; i++)
- {
- XftTextExtents32(top_level->display,
- font,
- (const FcChar32*)text,
- i + 1,
- &extents);
- charpos[i] = extents.xOff + bpos;
- }
- return charpos[length - 1] - bpos;
- }
- else
- {
- XftTextExtents32(top_level->display,
- font,
- (const FcChar32*)text,
- length,
- &extents);
- return extents.xOff;
- }
-}
-
void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font,
int x, int y, const FcChar32 *fc, int len, BC_Pixmap *pixmap)
{
}
void BC_WindowBase::draw_wtext(int x, int y,
- const wchar_t *text, int length, BC_Pixmap *pixmap, int *charpos)
+ const wchar_t *text, int length, BC_Pixmap *pixmap)
{
if( !get_resources()->use_xft ) {
if( !get_font_struct(current_font) ) return;
XRenderColor color;
XftColor xft_color;
const wchar_t *up, *ubp;
- int l, *cp;
+ int l;
FcPattern *newpat;
XftFont *curfont, *nextfont, *altfont, *basefont;
if(length < 0)
length = wcslen(text);
- if(charpos)
- charpos[0] = 0;
if(!length)
return;
curfont = nextfont = basefont;
altfont = 0;
- cp = 0;
ubp = text;
for(up = text; up < &text[length]; up++)
xft_draw_string(&xft_color, curfont, x, y,
(const FcChar32*)ubp, l, pixmap);
- if(charpos)
- cp = &charpos[ubp - text + 1];
+ XGlyphInfo extents;
+ XftTextExtents32(top_level->display, curfont,
+ (const FcChar32*)ubp, l, &extents);
+ x += extents.xOff;
- x += wcharpos(ubp, curfont, l, cp);
ubp = up;
curfont = nextfont;
}
{
xft_draw_string(&xft_color, curfont, x, y,
(const FcChar32*)ubp, up - ubp, pixmap);
- if(charpos)
- wcharpos(ubp, curfont, up - ubp, &charpos[ubp - text + 1]);
}
if(altfont)
output.tag.set_property("LOOP_PLAYBACK", config.loop_playback);
output.append_tag();
output.append_newline();
- char text[BCTEXTLEN];
+ char text[2*sizeof(config.wtext)];
int text_len = BC_Resources::encode(
BC_Resources::wide_encoding, DEFAULT_ENCODING,
(char*)config.wtext, config.wlen*sizeof(wchar_t),
text, sizeof(text));
+ int len = output.length(), avail = MESSAGESIZE-16 - len;
+ if( text_len >= avail ) { // back off last utf8 char
+ text_len = avail;
+ while( text_len > 0 && (text[text_len-1] & 0xc0) == 0x80 )
+ text[--text_len] = 0;
+ if( text_len > 0 )
+ text[--text_len] = 0;
+ }
output.append_text(text, text_len);
output.tag.set_title("/TITLE");
output.append_tag();
double fade_in, fade_out;
float pixels_per_second; // Speed of motion
// Text to display
- wchar_t wtext[BCTEXTLEN];
+ wchar_t wtext[3*BCTEXTLEN];
int wlen;
// Position in frame relative to top left
float title_x, title_y;
fade_out = 0;
text_title = 0;
text = 0;
+ text_chars = 0;
+ text_bfrsz = 0;
justify_title = 0;
left = 0; center = 0; right = 0;
top = 0; mid = 0; bottom = 0;
x = 10;
add_tool(text_title = new BC_Title(x, y, _("Text:")));
+ x += text_title->get_w() + 20;
+ int wid = BC_Title::calculate_w(this,"0")*10;
+ add_tool(text_chars = new TitleTextChars(x,y,wid));
+ x += text_chars->get_w() + 20;
+ add_tool(text_bfrsz = new TitleTextBfrSz(x,y,wid));
+
y += text_title->get_h() + margin;
x = margin;
text = new TitleText(client, this, x, y, get_w()-margin - x, get_h() - y - 10);
bottom->update(client->config.vjustification == JUSTIFY_BOTTOM);
}
+void TitleWindow::update_stats()
+{
+ text_chars->update(client->config.wlen);
+ int len = MESSAGESIZE-16 - strlen(text->get_text());
+ if( len < 0 ) len = 0;
+ text_bfrsz->update(len);
+}
+
void TitleWindow::update()
{
title_x->update((int64_t)client->config.title_x);
}
}
update_justification();
+ update_stats();
update_color();
}
wcsncpy(client->config.wtext, get_wtext(), len);
client->config.wtext[len-1] = 0;
client->config.wlen = wcslen(client->config.wtext);
+ window->update_stats();
client->send_configure_change();
return 1;
}
+TitleTextChars::TitleTextChars(int x, int y, int w)
+ : BC_Title(x, y, "", MEDIUMFONT, -1, 0, w)
+{
+}
+TitleTextChars::~TitleTextChars()
+{
+}
+int TitleTextChars::update(int n)
+{
+ char text[BCSTRLEN];
+ sprintf(text, _("chars: %d "),n);
+ return BC_Title::update(text, 0);
+}
+
+TitleTextBfrSz::TitleTextBfrSz(int x, int y, int w)
+ : BC_Title(x, y, "", MEDIUMFONT, -1, 0, w)
+{
+}
+TitleTextBfrSz::~TitleTextBfrSz()
+{
+}
+int TitleTextBfrSz::update(int n)
+{
+ char text[BCSTRLEN];
+ sprintf(text, _("bfrsz: %d "),n);
+ return BC_Title::update(text, 0);
+}
TitleDropShadow::TitleDropShadow(TitleMain *client, TitleWindow *window, int x, int y)
class TitleFade;
class TitleFont;
class TitleText;
+class TitleTextChars;
+class TitleTextBfrSz;
class TitleX;
class TitleY;
class TitleW;
int grab_event(XEvent *event);
void update_color();
void update_justification();
+ void update_stats();
void update();
void previous_font();
void next_font();
TitleFade *fade_out;
BC_Title *text_title;
TitleText *text;
+ TitleTextChars *text_chars;
+ TitleTextBfrSz *text_bfrsz;
BC_Title *justify_title;
TitleLeft *left;
TitleCenter *center;
TitleMain *client;
TitleWindow *window;
};
+class TitleTextChars : public BC_Title
+{
+public:
+ int update(int n);
+ TitleTextChars(int x, int y, int w);
+ ~TitleTextChars();
+};
+class TitleTextBfrSz : public BC_Title
+{
+public:
+ int update(int n);
+ TitleTextBfrSz(int x, int y, int w);
+ ~TitleTextBfrSz();
+};
+
class TitleX : public BC_TumbleTextBox
{
public: