static void add_letter(marqueestruct * mp, char * letter) { int width; int b = charBytes(letter[0]); int i; if (mp->t < 253 - b) { for (i = 0; i < b; i++) { mp->modwords[mp->t] = letter[i]; mp->t++; } mp->modwords[mp->t] = '\0'; (void) strcat(mp->modwords, " "); } mp->x -= charWidth(letter); width = charWidth(mp->modwords); if (mp->x <= -width) { mp->x += width; (void) memcpy(mp->modwords, &(mp->modwords[1]), mp->t); for (i = 0; i < b; i++) { mp->modwords[mp->t] = ' '; mp->t--; } } else mp->nonblanks = mp->t; }
static int charWidth(char * string) { #ifdef USE_MB XRectangle rect; int mb = charBytes(*string); XmbTextExtents(fontset, string, mb, NULL, &rect); return rect.width; #else return char_width[(int) (unsigned char) *string]; #endif }
CharType chstr[RICHSTRING_MAXLEN+1]; CharType* chptr; } RichString; }*/ #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif #define charBytes(n) (sizeof(CharType) * (n)) static inline void RichString_setLen(RichString* this, int len) { if (this->chlen <= RICHSTRING_MAXLEN) { if (len > RICHSTRING_MAXLEN) { this->chptr = malloc(charBytes(len+1)); memcpy(this->chptr, this->chstr, charBytes(this->chlen+1)); } } else { if (len <= RICHSTRING_MAXLEN) { memcpy(this->chstr, this->chptr, charBytes(this->chlen)); free(this->chptr); this->chptr = this->chstr; } else { this->chptr = realloc(this->chptr, charBytes(len+1)); } } RichString_setChar(this, len, 0); this->chlen = len; }
void draw_marquee(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); char *space = (char *) " "; unsigned char *ch; marqueestruct *mp = &marquees[MI_SCREEN(mi)]; if (marquees == NULL) return; mp = &marquees[MI_SCREEN(mi)]; if (mp->gc == None && mode_font != None) return; MI_IS_DRAWN(mi) = True; ch = (unsigned char*) mp->words; if (isRibbon()) { ch = (unsigned char*) mp->words; switch (*ch) { case '\0': if (add_blanks(mp)) { init_marquee(mi); return; } break; case '\b': case '\r': case '\n': case '\t': case '\v': case '\f': add_letter(mp, " "); mp->words++; break; default: add_letter(mp, (char *) ch); mp->words++; } if (MI_NPIXELS(mi) > 2) { XSetForeground(display, mp->gc, MI_PIXEL(mi, mp->color)); if (++mp->color == MI_NPIXELS(mi)) mp->color = 0; } else XSetForeground(display, mp->gc, MI_WHITE_PIXEL(mi)); (void) XDrawImageString(display, MI_WINDOW(mi), mp->gc, mp->x, mp->y + mp->ascent, mp->modwords, mp->t + 2); } else { switch (*ch) { case '\0': if (++mp->time > 16) init_marquee(mi); return; case '\b': if (mp->t) { /* see note in text_font_width */ mp->t--; mp->x -= char_width[(int) (' ')]; } break; case '\v': case '\f': case '\n': mp->x = mp->startx; mp->t = 0; mp->y += mp->height; if (mp->y + mp->height > mp->win_height) { XCopyArea(display, window, window, mp->gc, 0, mp->height, mp->win_width, mp->y - mp->height, 0, 0); XSetForeground(display, mp->gc, MI_BLACK_PIXEL(mi)); mp->y -= mp->height; XFillRectangle(display, window, mp->gc, 0, mp->y, mp->win_width, mp->height); } break; case '\t': (void) XDrawString(display, window, mp->gc, mp->x, mp->y + mp->ascent, space, 8 - (mp->t % 8)); mp->x += char_width[(int) (' ')] * (8 - (mp->t % 8)); mp->t = ((mp->t + 8) / 8) * 8; break; case '\r': break; default: if (MI_NPIXELS(mi) > 2) { XSetForeground(display, mp->gc, MI_PIXEL(mi, mp->color)); if (++mp->color == MI_NPIXELS(mi)) mp->color = 0; } else XSetForeground(display, mp->gc, MI_WHITE_PIXEL(mi)); if (is_char_back_char((char *) ch)) { int xmid = mp->x + (char_back_char_width((char *) ch) + 1) / 2; (void) XDrawString(display, window, mp->gc, xmid - char_width[(int) (const char) *ch] / 2, mp->y + mp->ascent, (char *) ch, 1); (void) XDrawString(display, window, mp->gc, xmid - char_width[(int) (const char) *(ch + 2)] / 2, mp->y + mp->ascent, (char *) ch + 2, 1); mp->x += char_back_char_width((char *) ch); mp->words += 2; } else { int mb = charBytes(*ch); (void) XDrawString(display, window, mp->gc, mp->x, mp->y + mp->ascent, (char *) ch, mb); mp->x += charWidth((char *) ch); } mp->t++; } mp->words += charBytes(*ch); } }