#include "xlib.h" #include "scheme48.h" #include extern XDrawText(), XDrawText16(); /* Calculation of text widths and extents should not be done using * the Xlib functions. For instance, the values returned by * XTextExtents() are only shorts and can therefore overflow for * long strings. */ s48_value scx_Text_Width(s48_value Xfontstruct, s48_value text, s48_value format){ char* s; XChar2b* s2; XFontStruct* font = SCX_EXTRACT_FONTSTRUCT(Xfontstruct); int len = (int)S48_VECTOR_LENGTH(text), i, tmp; if (s48_extract_integer(format) == 1){ for (i = 0; i < len; i++){ tmp = (int)s48_extract_integer(S48_VECTOR_REF(text, i)); s2[i].byte1 = (tmp >> 8) & 0xff; s2[i].byte2 = tmp & 0xff; } i = XTextWidth16(font, s2, len); } else{ for (i = 0; i < len; i++){ s[i] = (int)s48_extract_integer(S48_VECTOR_REF(text, i)); } i = XTextWidth(font, s, len); } return s48_enter_integer((long)i); } s48_value scx_Extents_Text (s48_value Xfontstruct, s48_value text, s48_value format, s48_value which){ char* s; XChar2b* s2; XFontStruct* font = SCX_EXTRACT_FONTSTRUCT(Xfontstruct); XCharStruct CI; int len = (int)S48_VECTOR_LENGTH(text), i, tmp, dir, fasc, fdesc; if (s48_extract_integer(format) == 1){ for (i = 0; i < len; i++){ tmp = (int)s48_extract_integer(S48_VECTOR_REF(text, i)); s2[i].byte1 = (tmp >> 8) & 0xff; s2[i].byte2 = tmp & 0xff; } XTextExtents16(font, s2, len, &dir, &fasc, &fdesc, &CI); }else{ for (i = 0; i < len; i++){ s[i] = (int)s48_extract_integer(S48_VECTOR_REF(text, i)); } XTextExtents(font, s, len, &dir, &fasc, &fdesc, &CI); } switch(s48_extract_integer(which)){ case 0: return s48_enter_integer((long) CI.lbearing); case 1: return s48_enter_integer((long) CI.rbearing); case 2: return s48_enter_integer((long) CI.width); case 3: return s48_enter_integer((long) CI.ascent); case 4: return s48_enter_integer((long) CI.descent); } return S48_FALSE; } s48_value scx_Draw_Image_Text (s48_value Xdisplay, s48_value Xdrawable, s48_value Xgcontext, s48_value x, s48_value y, s48_value text, s48_value is_twobyte){ int i, len, tmp; len = S48_VECTOR_LENGTH(text); if (!S48_FALSE_P(is_twobyte)) { XChar2b s2[len]; for (i = 0; i < len; i++) { tmp = (int)s48_extract_integer(S48_VECTOR_REF(text, i)); s2[i].byte1 = (tmp >> 8) & 0xff; s2[i].byte2 = tmp & 0xff; } XDrawImageString16 (SCX_EXTRACT_DISPLAY(Xdisplay), SCX_EXTRACT_DRAWABLE(Xdrawable), SCX_EXTRACT_GCONTEXT(Xgcontext), (int)s48_extract_integer(x), (int)s48_extract_integer(y), s2, len); } else { char s[len]; for (i = 0; i < len; i++) { s[i] = (int)s48_extract_integer(S48_VECTOR_REF(text, i)); } XDrawImageString (SCX_EXTRACT_DISPLAY(Xdisplay), SCX_EXTRACT_DRAWABLE(Xdrawable), SCX_EXTRACT_GCONTEXT(Xgcontext), (int)s48_extract_integer(x), (int)s48_extract_integer(y), s, len); } return S48_UNSPECIFIC; } // Draw_Poly_Text processes a vector like [[24 23 87 67] Xfont [12 0]] and // passes it to XDrawPolyText or XDrawPolyText16 s48_value scx_Draw_Poly_Text (s48_value Xdisplay, s48_value Xdrawable, s48_value Xgcontext, s48_value x, s48_value y, s48_value text, s48_value is_twobyte) { int i, len, nitems; s48_value temp_vec = S48_FALSE; char twobyte = !S48_FALSE_P(is_twobyte); len = S48_VECTOR_LENGTH(text); // Nothing to do with an empty vector. if (len == 0) return S48_UNSPECIFIC; // count the strings in text: nitems = 0; for (i = 0; i < len; i++) { if (S48_VECTOR_P(S48_VECTOR_REF(text, i))) nitems++; } { XTextItem item[nitems]; int set = 0, j, k, tmp; //Maybe no font as first Element of text? if (S48_VECTOR_P(S48_VECTOR_REF(text, 0))) { item[0].delta = 0; item[0].font = None; } // Generate the XTextItem{16} for (i = 0; i < len; i++) { if (S48_VECTOR_P(S48_VECTOR_REF(text,i))) { temp_vec = S48_VECTOR_REF(text,i); k = S48_VECTOR_LENGTH(temp_vec); item[set].nchars = k; if (twobyte) { XChar2b* s2 = (XChar2b*)malloc(sizeof(XChar2b)*k); for (j = 0; j < k; j++){ tmp = (int)s48_extract_integer(S48_VECTOR_REF(temp_vec, j)); s2[j].byte1 = (tmp >> 8) & 0xff; s2[j].byte2 = tmp & 0xff; } (XTextItem16*)item[set].chars = s2; } else { char* s = (char*)malloc(sizeof(char)*k); for (j = 0; j < k; j++) { s[j] = (int)s48_extract_integer(S48_VECTOR_REF(temp_vec, j)); } item[set].chars = s; } set++; } else { s48_value fontspec = S48_VECTOR_REF(text, i); s48_value font = S48_CAR(fontspec); item[set].font = S48_SYMBOL_P(font) ? None : SCX_EXTRACT_FONT(font); item[set].delta = s48_extract_integer(S48_CDR(fontspec)); } } // No pass it all to the Xlib if (twobyte) { XDrawText16(SCX_EXTRACT_DISPLAY(Xdisplay), SCX_EXTRACT_DRAWABLE(Xdrawable), SCX_EXTRACT_GCONTEXT(Xgcontext), (int)s48_extract_integer(x), (int)s48_extract_integer(y), (XTextItem16*) item, nitems); } else { XDrawText(SCX_EXTRACT_DISPLAY(Xdisplay), SCX_EXTRACT_DRAWABLE(Xdrawable), SCX_EXTRACT_GCONTEXT(Xgcontext), (int)s48_extract_integer(x), (int)s48_extract_integer(y), item, nitems); } // No free all character-arrays for (i = 0; i < nitems; i++) free(item[i].chars); } return S48_UNSPECIFIC; } void scx_init_text(void) { S48_EXPORT_FUNCTION(scx_Text_Width); S48_EXPORT_FUNCTION(scx_Extents_Text); S48_EXPORT_FUNCTION(scx_Draw_Image_Text); S48_EXPORT_FUNCTION(scx_Draw_Poly_Text); }