static void gtk_plot_canvas_text_size_allocate(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child) { GtkPlotCanvasText *text = GTK_PLOT_CANVAS_TEXT(child); gint tx, ty, x, y, width, height; gdouble m = canvas->magnification; text->text.x = child->rx1; text->text.y = child->ry1; x = roundint(text->text.x * canvas->pixmap_width); y = roundint(text->text.y * canvas->pixmap_height); gtk_plot_text_get_area(text->text.text, text->text.angle, text->text.justification, text->text.font, roundint(m * text->text.height), &tx, &ty, &width, &height); if(text->text.border != GTK_PLOT_BORDER_NONE){ tx -= text->text.border_space; ty -= text->text.border_space; width += 2 * text->text.border_space; height += 2 * text->text.border_space; } tx += x; ty += y; child->allocation.x = tx; child->allocation.y = ty; child->allocation.width = width; child->allocation.height = height; gtk_plot_canvas_get_position(canvas, tx + width, ty + height, &child->rx2, &child->ry2); }
static void psdrawstring (GtkPlotPC *pc, gint x, gint y, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font, gint font_height, GtkJustification justification, const gchar *text) { const gchar *c; GtkPSFont *psfont, *base_psfont, *latin_psfont = NULL; gint curcnt = 0, offset = 0; gint numf; gdouble scale; gboolean italic, bold; gboolean special = FALSE; GList *family; FILE *psout; gint twidth, theight, tdescent, tascent; gint tx, ty, width, height; gint i; const gchar *aux, *xaux, *wtext, *lastchar = NULL; gchar *curstr, bkspchar[3]; gchar num[4]; if (text == NULL || text[0] == '\0') return; psout = GTK_PLOT_PS(pc)->psfile; gtk_psfont_get_families(&family, &numf); base_psfont = psfont = gtk_psfont_get_by_name(font); italic = psfont->italic; bold = psfont->bold; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); } gtk_plot_text_get_area(text, angle, justification, font, font_height, &tx, &ty, &width, &height); tx += x; ty += y; if(!transparent){ pssetcolor(pc, bg); gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); } /* border */ pssetcolor(pc, fg); pssetdash(pc, 0, NULL, 0); pssetlineattr(pc, border_width, 0, 0, 0); switch(border){ case GTK_PLOT_BORDER_SHADOW: psdrawrectangle(pc, TRUE, tx - border_space + shadow_width, ty + height + border_space, width + 2 * border_space, shadow_width); psdrawrectangle(pc, TRUE, tx + width + border_space, ty - border_space + shadow_width, shadow_width, height + 2 * border_space); case GTK_PLOT_BORDER_LINE: psdrawrectangle(pc, FALSE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); case GTK_PLOT_BORDER_NONE: default: break; } gtk_plot_text_get_size(text, angle, psfont->psname, font_height, &twidth, &theight, &tascent, &tdescent); if(angle == 90 || angle == 270) angle = 360 - angle; psgsave(pc); fprintf(psout, "%d %d translate\n", x, y); fprintf(psout, "%d rotate\n", angle); fprintf(psout, "0 0 m\n"); fprintf(psout, "1 -1 sc\n"); if (psfont->i18n_latinfamily) special = TRUE; c = text; while(c && *c != '\0' && *c != '\n') { if(*c == '\\'){ c = g_utf8_next_char(c); switch(*c){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': case '8': case'g': case 'B': case 'b': case 'x': case 'N': case 's': case 'S': case 'i': case '-': case '+': case '^': special = TRUE; break; default: break; } } else { c = g_utf8_next_char(c); } } if(special){ switch (justification) { case GTK_JUSTIFY_LEFT: break; case GTK_JUSTIFY_RIGHT: if(angle == 0 || angle == 180) fprintf(psout, "%d JR\n", twidth); else fprintf(psout, "%d JR\n", theight); break; case GTK_JUSTIFY_CENTER: default: if(angle == 0 || angle == 180) fprintf(psout, "%d JC\n", twidth); else fprintf(psout, "%d JC\n", theight); break; } } else { pssetfont(pc, psfont, font_height); switch (justification) { case GTK_JUSTIFY_LEFT: break; case GTK_JUSTIFY_RIGHT: fprintf(psout, "(%s) sw JR\n", text); break; case GTK_JUSTIFY_CENTER: default: fprintf(psout, "(%s) sw JC\n", text); break; } fprintf(psout, "(%s) show\n", text); psgrestore(pc); fprintf(psout, "n\n"); return; } i = g_utf8_strlen(text, -1) + 2; curstr = g_malloc0(sizeof(gchar) * i); aux = wtext = text; scale = font_height; curcnt = 0; while(aux && *aux != '\0' && *aux != '\n') { if(*aux == '\\'){ aux = g_utf8_next_char(aux); switch(*aux){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; psfont = gtk_psfont_get_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold); aux = g_utf8_next_char(aux); break; case '8':case 'g': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; psfont = gtk_psfont_get_by_family("Symbol", italic, bold); aux = g_utf8_next_char(aux); break; case 'B': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; bold = TRUE; psfont = gtk_psfont_get_by_family(psfont->family, italic, bold); if (psfont->i18n_latinfamily) latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); aux = g_utf8_next_char(aux); break; case 'x': xaux = aux + 1; for (i=0; i<3; i++){ if (xaux[i] >= '0' && xaux[i] <= '9') num[i] = xaux[i]; else break; } if (i < 3){ aux = g_utf8_next_char(aux); break; } num[3] = '\0'; i = atoi(num); g_snprintf(num, 4, "%o", i % (64 * 8)); curstr[curcnt++] = '\\'; i = 0; while (num[i]) { curstr[curcnt++] = num[i++]; } aux += 4; break; case 'i': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; italic = TRUE; psfont = gtk_psfont_get_by_family(psfont->family, italic, bold); if (psfont->i18n_latinfamily) latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); aux = g_utf8_next_char(aux); break; case 's':case '_': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; scale = 0.6 * font_height; offset -= (gint)scale / 2; fprintf(psout, "0 %d rmoveto\n", -((gint)scale / 2)); aux = g_utf8_next_char(aux); break; case 'S':case '^': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; scale = 0.6 * font_height; offset += 0.5*font_height; fprintf(psout, "0 %d rmoveto\n", (gint)(0.5*font_height)); aux = g_utf8_next_char(aux); break; case 'N': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; psfont = base_psfont; italic = psfont->italic; bold = psfont->bold; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_get_by_family(psfont->i18n_latinfamily, italic, bold); } scale = font_height; fprintf(psout, "0 %d rmoveto\n", -offset); offset = 0; aux = g_utf8_next_char(aux); break; case 'b': curstr[curcnt] = '\0'; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; if (lastchar) { const gchar *aux2 = lastchar; bkspchar[0] = *lastchar; lastchar = g_utf8_prev_char(lastchar); bkspchar[1] = 0; if(--aux2 != lastchar){ bkspchar[1] = *lastchar; lastchar = g_utf8_prev_char(lastchar); bkspchar[2] = 0; } } else { bkspchar[0] = 'X'; lastchar = NULL; } psoutputstring(pc, psfont, latin_psfont, (gint)scale, bkspchar, "stringwidth pop 0 exch neg exch rmoveto"); aux = g_utf8_next_char(aux); break; case '-': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; scale -= 3; if (scale < 6) { scale = 6; } aux = g_utf8_next_char(aux); break; case '+': curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); curcnt = 0; scale += 3; aux = g_utf8_next_char(aux); break; default: if(aux && *aux != '\0' && *aux != '\n'){ curstr[curcnt++] = *aux; aux = g_utf8_next_char(aux); } break; } } else { if(aux && *aux != '\0' && *aux != '\n'){ const gchar *aux2 = aux; if(g_utf8_next_char(aux) != ++aux2){ curstr[curcnt++] = *aux++; // aux = g_utf8_next_char(aux); curstr[curcnt++] = *aux++; } else { curstr[curcnt++] = *aux; lastchar = aux; aux = g_utf8_next_char(aux); } } } } curstr[curcnt] = 0; psoutputstring(pc, psfont, latin_psfont, (gint)scale, curstr, "show"); psgrestore(pc); fprintf(psout, "n\n"); g_free(curstr); }
static void gtk_plot_gdk_draw_string (GtkPlotPC *pc, gint tx, gint ty, gint angle, const GdkColor *fg, const GdkColor *bg, gboolean transparent, gint border, gint border_space, gint border_width, gint shadow_width, const gchar *font_name, gint font_height, GtkJustification just, const gchar *text) { GdkBitmap *text_bitmap; GdkPixmap *text_pixmap; GdkBitmap *text_mask; GdkImage *image; GdkGC *gc, *bitmap_gc; GdkColormap *colormap; GdkColor white, black, mask_color; GList *family = NULL; gint y0; gint old_width, old_height; gboolean bold, italic; gint fontsize; gint ascent, descent; gint numf; gint xp = 0, yp = 0; gint width, height; gint x, y; gint i; GdkFont *font, *latin_font, *dfont; GtkPSFont *psfont, *base_psfont, *latin_psfont; gchar subs[2], insert_char; GdkWChar *aux, *wtext, *lastchar = NULL, *xaux; gchar num[4]; if(!GTK_PLOT_GDK(pc)->drawable) return; if(!GTK_PLOT_GDK(pc)->window) return; if(!GTK_PLOT_GDK(pc)->gc) return; if(!text || strlen(text) == 0) return; colormap = gdk_colormap_get_system (); gc = GTK_PLOT_GDK(pc)->gc; if(!gc) return; gtk_plot_text_get_size(text, angle, font_name, font_height, &width, &height, &ascent, &descent); if(height == 0 || width == 0) return; old_width = width; old_height = height; if(angle == 90 || angle == 270) { old_width = height; old_height = width; } gtk_psfont_get_families(&family, &numf); font = gtk_psfont_get_gdkfont(font_name, font_height); base_psfont = psfont = gtk_psfont_get_font(font_name); italic = psfont->italic; bold = psfont->bold; fontsize = font_height; x = 0; y0 = y = ascent; if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } else { latin_psfont = NULL; latin_font = NULL; } i = strlen(text) + 2; aux = wtext = g_malloc0(sizeof(GdkWChar) * i); gdk_mbstowcs(wtext, text, i - 1); /* initializing text bitmap - ajd */ text_bitmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, old_width, old_height, 1); bitmap_gc = gdk_gc_new(text_bitmap); gdk_color_white (colormap, &white); gdk_gc_set_foreground(bitmap_gc, &white); gdk_draw_rectangle(text_bitmap, bitmap_gc, TRUE, 0, 0, -1, -1); gdk_color_black (colormap, &black); gdk_gc_set_foreground(bitmap_gc, &black); while(aux && *aux != '\0' && *aux != '\n'){ if(*aux == '\\'){ aux++; switch(*aux){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '9': psfont = gtk_psfont_find_by_family((gchar *)g_list_nth_data(family, *aux-'0'), italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } aux++; break; case '8': case 'g': psfont = gtk_psfont_find_by_family("Symbol", italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } aux++; break; case 'B': bold = TRUE; psfont = gtk_psfont_find_by_family(psfont->family, italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'x': xaux = aux + 1; for (i=0; i<3; i++){ if (xaux[i] >= '0' && xaux[i] <= '9') num[i] = xaux[i]; else break; } if (i < 3){ aux++; break; } num[3] = '\0'; insert_char = (gchar)atoi(num); subs[0] = insert_char; subs[1] = '\0'; /* \xNNN is always outputted with latin fonts. */ dfont = (psfont->i18n_latinfamily != NULL) ? latin_font : font; gdk_draw_string (text_bitmap, dfont, bitmap_gc, x, y, subs); x += gdk_char_width(font, insert_char); aux += 4; lastchar = aux - 1; break; case 'i': italic = TRUE; psfont = gtk_psfont_find_by_family(psfont->family, italic, bold); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'S': case '^': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y -= font->ascent; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 's': case '_': fontsize = (int)((gdouble)fontsize * 0.6 + 0.5); gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y += font->descent; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case '+': fontsize += 3; gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case '-': fontsize -= 3; gdk_font_unref(font); font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'N': psfont = base_psfont; gdk_font_unref(font); fontsize = font_height; font = gtk_psfont_get_gdkfont(psfont->psname, fontsize); y = y0; italic = psfont->italic; bold = psfont->bold; if (latin_font) { gdk_font_unref(latin_font); latin_font = NULL; } if (psfont->i18n_latinfamily) { latin_psfont = gtk_psfont_find_by_family(psfont->i18n_latinfamily, italic, bold); latin_font = gtk_psfont_get_gdkfont(latin_psfont->psname, fontsize); } aux++; break; case 'b': if (lastchar) { gtk_psfont_get_char_size(psfont, font, latin_font, *lastchar, &i, NULL, NULL); x -= i; if (lastchar == wtext) lastchar = NULL; else lastchar--; } else { gtk_psfont_get_char_size(psfont, font, latin_font, 'X', &i, NULL, NULL); x -= i; } aux++; break; default: if(aux && *aux != '\0' && *aux !='\n'){ x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y, psfont, font, latin_font, *aux); lastchar = aux; aux++; } break; } } else { if(aux && *aux != '\0' && *aux !='\n'){ x += drawstring(pc, text_bitmap, bitmap_gc, &black, &white, x, y, psfont, font, latin_font, *aux); lastchar = aux; aux++; } } } g_free(wtext); /* initializing clip mask bitmap - ajd */ text_mask = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, 1); mask_color = white; mask_color.pixel = 0; gdk_gc_set_foreground(bitmap_gc, &mask_color); gdk_draw_rectangle(text_mask, bitmap_gc, TRUE, 0, 0, -1, -1); mask_color = black; mask_color.pixel = 1; gdk_gc_set_foreground(bitmap_gc, &mask_color); /* performing text rotation and saving it onto clip mask bitmap - ajd */ image = gdk_image_get(text_bitmap, 0, 0, old_width, old_height); for(y = 0; y < old_height; y++) for(x = 0; x < old_width; x++) { if( black.pixel == gdk_image_get_pixel(image, x, y) ){ switch(angle){ case 0: xp = x; yp = y; break; case 90: xp = y; yp = old_width - x; break; case 180: xp = old_width - x; yp = old_height - y; break; case 270: xp = old_height - y; yp = x; break; } gdk_draw_point(text_mask, bitmap_gc, xp, yp); } } gdk_image_destroy(image); /* initializing text pixmap - ajd */ text_pixmap = gdk_pixmap_new(GTK_PLOT_GDK(pc)->window, width, height, -1); gdk_gc_set_foreground(gc, (GdkColor *) bg); gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1); gdk_gc_set_foreground(gc, (GdkColor *) fg); /* copying clip mask bitmap onto text pixmap - ajd */ gdk_gc_set_clip_mask(gc, text_mask); gdk_gc_set_clip_origin(gc, 0, 0); gdk_draw_rectangle(text_pixmap, gc, TRUE, 0, 0, -1, -1); gdk_gc_set_clip_mask(gc, NULL); gtk_plot_text_get_area(text, angle, just, font_name, font_height, &x, &y, &width, &height); tx += x; ty += y; if(transparent){ gdk_gc_set_clip_mask (gc, text_mask); gdk_gc_set_clip_origin (gc, tx, ty); } else { gdk_gc_set_foreground(gc, (GdkColor *) bg); gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); } gdk_draw_pixmap(GTK_PLOT_GDK(pc)->drawable, gc, text_pixmap, 0, 0, tx, ty, -1, -1); gdk_gc_set_clip_mask(gc, NULL); gdk_pixmap_unref(text_pixmap); gdk_bitmap_unref(text_mask); gdk_font_unref(font); if (latin_font) gdk_font_unref(latin_font); gdk_gc_unref(bitmap_gc); gdk_pixmap_unref(text_bitmap); /* border */ gdk_gc_set_foreground(gc, (GdkColor *) fg); gtk_plot_pc_set_dash(pc, 0, NULL, 0); gtk_plot_pc_set_lineattr(pc, border_width, 0, 0, 0); switch(border){ case GTK_PLOT_BORDER_SHADOW: gtk_plot_pc_draw_rectangle(pc, TRUE, tx - border_space + shadow_width, ty + height + border_space, width + 2 * border_space, shadow_width); gtk_plot_pc_draw_rectangle(pc, TRUE, tx + width + border_space, ty - border_space + shadow_width, shadow_width, height + 2 * border_space); case GTK_PLOT_BORDER_LINE: gtk_plot_pc_draw_rectangle(pc, FALSE, tx - border_space, ty - border_space, width + 2*border_space, height + 2*border_space); case GTK_PLOT_BORDER_NONE: default: break; } return; }