static void draw_string(DiaRenderer *self, const char *text, Point *pos, Alignment alignment, Color *color) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); Point pos_adj; gchar *buffer; if (1 > strlen(text)) return; lazy_setcolor(renderer,color); buffer = ps_convert_string(text, renderer->ctx); fprintf(renderer->file, "(%s) ", buffer); g_free(buffer); pos_adj.x = pos->x; pos_adj.y = pos->y - dia_font_descent("", self->font, self->font_height); put_text_alignment (renderer, alignment, &pos_adj); fprintf(renderer->file, " gs 1 -1 sc sh gr\n"); }
static void begin_render(DiaRenderer *self, const Rectangle *update) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); time_t time_now; g_assert (renderer->file != NULL); time_now = time(NULL); if (renderer_is_eps(renderer)) fprintf(renderer->file, "%%!PS-Adobe-2.0 EPSF-2.0\n"); else fprintf(renderer->file, "%%!PS-Adobe-2.0\n"); fprintf(renderer->file, "%%%%Title: %s\n" "%%%%Creator: Dia v%s\n" "%%%%CreationDate: %s" "%%%%For: %s\n" "%%%%Orientation: %s\n", renderer->title ? renderer->title : "(NULL)" , VERSION, ctime(&time_now), g_get_user_name(), renderer->is_portrait ? "Portrait" : "Landscape"); if (renderer_is_epsi(renderer)) { g_assert(!"Preview image not implmented"); /* but it *may* belong here ... */ } if (renderer_is_eps(renderer)) fprintf(renderer->file, "%%%%Magnification: 1.0000\n" "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil( (renderer->extent.right - renderer->extent.left) * renderer->scale), (int) ceil( (renderer->extent.bottom - renderer->extent.top) * renderer->scale) ); else fprintf(renderer->file, "%%%%DocumentPaperSizes: %s\n", renderer->paper ? renderer->paper : "(NULL)"); fprintf(renderer->file, "%%%%BeginSetup\n"); fprintf(renderer->file, "%%%%EndSetup\n" "%%%%EndComments\n"); DIA_PS_RENDERER_GET_CLASS(self)->begin_prolog(renderer); /* get our font definitions */ DIA_PS_RENDERER_GET_CLASS(self)->dump_fonts(renderer); /* done it */ DIA_PS_RENDERER_GET_CLASS(self)->end_prolog(renderer); }
static void draw_bezier(DiaRenderer *self, BezPoint *points, int numpoints, /* numpoints = 4+3*n, n=>0 */ Color *color) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); psrenderer_bezier(renderer, points, numpoints, color, FALSE); }
static void dia_ps_renderer_finalize (GObject *object) { DiaPsRenderer *renderer = DIA_PS_RENDERER (object); g_free(renderer->title); /* fclose(renderer->file);*/ G_OBJECT_CLASS (parent_class)->finalize (object); }
static void fill_arc(DiaRenderer *self, Point *center, real width, real height, real angle1, real angle2, Color *color) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); psrenderer_arc(renderer, center, width, height, angle1, angle2, color, TRUE); }
static void draw_polygon (DiaRenderer *self, Point *points, int num_points, Color *fill, Color *stroke) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); /* XXX: not optimized to fill and stroke at once */ if (fill) psrenderer_polygon(renderer, points, num_points, fill, TRUE); if (stroke) psrenderer_polygon(renderer, points, num_points, stroke, FALSE); }
static void draw_ellipse(DiaRenderer *self, Point *center, real width, real height, Color *fill, Color *stroke) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); if (fill) psrenderer_ellipse(renderer, center, width, height, fill, TRUE); if (stroke) psrenderer_ellipse(renderer, center, width, height, stroke, FALSE); }
static void set_linestyle(DiaRenderer *self, LineStyle mode, real dash_length) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); real hole_width; gchar dashl_buf[DTOSTR_BUF_SIZE]; gchar dotl_buf[DTOSTR_BUF_SIZE]; gchar holew_buf[DTOSTR_BUF_SIZE]; real dot_length; if (dash_length<0.001) dash_length = 0.001; dot_length = dash_length*0.2; /* dot = 20% of len */ switch(mode) { case LINESTYLE_SOLID: fprintf(renderer->file, "[] 0 sd\n"); break; case LINESTYLE_DASHED: fprintf(renderer->file, "[%s] 0 sd\n", psrenderer_dtostr(dashl_buf, dash_length) ); break; case LINESTYLE_DASH_DOT: hole_width = (dash_length - dot_length) / 2.0; psrenderer_dtostr(holew_buf, hole_width); psrenderer_dtostr(dashl_buf, dash_length); psrenderer_dtostr(dotl_buf, dot_length); fprintf(renderer->file, "[%s %s %s %s] 0 sd\n", dashl_buf, holew_buf, dotl_buf, holew_buf ); break; case LINESTYLE_DASH_DOT_DOT: hole_width = (dash_length - 2.0*dot_length) / 3.0; psrenderer_dtostr(holew_buf, hole_width); psrenderer_dtostr(dashl_buf, dash_length); psrenderer_dtostr(dotl_buf, dot_length); fprintf(renderer->file, "[%s %s %s %s %s %s] 0 sd\n", dashl_buf, holew_buf, dotl_buf, holew_buf, dotl_buf, holew_buf ); break; case LINESTYLE_DOTTED: fprintf(renderer->file, "[%s] 0 sd\n", psrenderer_dtostr(dotl_buf, dot_length) ); break; } }
static void set_linewidth(DiaRenderer *self, real linewidth) { /* 0 == hairline **/ DiaPsRenderer *renderer = DIA_PS_RENDERER(self); gchar lw_buf[DTOSTR_BUF_SIZE]; /* Adobe's advice: Set to very small but fixed size, to avoid changes * due to different resolution output. */ /* .01 cm becomes <5 dots on 1200 DPI */ if (linewidth == 0.0) linewidth=.01; fprintf(renderer->file, "%s slw\n", psrenderer_dtostr(lw_buf, (gdouble) linewidth) ); }
static void end_render(DiaRenderer *self) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); if (renderer_is_eps(renderer)) fprintf(renderer->file, "showpage\n"); if (self->font != NULL) { dia_font_unref(self->font); self->font = NULL; } }
/* constructor */ static void ps_renderer_init (GTypeInstance *instance, gpointer g_class) { DiaPsRenderer *renderer = DIA_PS_RENDERER (instance); renderer->file = NULL; renderer->lcolor.red = -1.0; renderer->is_portrait = TRUE; renderer->scale = 28.346; }
static void draw_beziergon (DiaRenderer *self, BezPoint *points, /* Last point must be same as first point */ int numpoints, Color *fill, Color *stroke) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); if (fill) psrenderer_bezier(renderer, points, numpoints, fill, TRUE); /* XXX: still not closing the path */ if (stroke) psrenderer_bezier(renderer, points, numpoints, stroke, TRUE); }
static void draw_line(DiaRenderer *self, Point *start, Point *end, Color *line_color) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); gchar sx_buf[DTOSTR_BUF_SIZE]; gchar sy_buf[DTOSTR_BUF_SIZE]; gchar ex_buf[DTOSTR_BUF_SIZE]; gchar ey_buf[DTOSTR_BUF_SIZE]; lazy_setcolor(renderer,line_color); fprintf(renderer->file, "n %s %s m %s %s l s\n", psrenderer_dtostr(sx_buf, start->x), psrenderer_dtostr(sy_buf, start->y), psrenderer_dtostr(ex_buf, end->x), psrenderer_dtostr(ey_buf, end->y) ); }
static void set_font(DiaRenderer *self, DiaFont *font, real height) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); gchar h_buf[DTOSTR_BUF_SIZE]; if (font != self->font || height != self->font_height) { DiaFont *old_font; fprintf(renderer->file, "/%s-latin1 ff %s scf sf\n", dia_font_get_psfontname(font), psrenderer_dtostr(h_buf, (gdouble) height*0.7) ); old_font = self->font; self->font = font; dia_font_ref(self->font); if (old_font != NULL) { dia_font_unref(old_font); } self->font_height = height; } }
static void set_linecaps(DiaRenderer *self, LineCaps mode) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); int ps_mode; switch(mode) { case LINECAPS_BUTT: ps_mode = 0; break; case LINECAPS_ROUND: ps_mode = 1; break; case LINECAPS_PROJECTING: ps_mode = 2; break; default: ps_mode = 0; } fprintf(renderer->file, "%d slc\n", ps_mode); }
static void set_linejoin(DiaRenderer *self, LineJoin mode) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); int ps_mode; switch(mode) { case LINEJOIN_MITER: ps_mode = 0; break; case LINEJOIN_ROUND: ps_mode = 1; break; case LINEJOIN_BEVEL: ps_mode = 2; break; default: ps_mode = 0; } fprintf(renderer->file, "%d slj\n", ps_mode); }
static void draw_polyline(DiaRenderer *self, Point *points, int num_points, Color *line_color) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); int i; gchar px_buf[DTOSTR_BUF_SIZE]; gchar py_buf[DTOSTR_BUF_SIZE]; lazy_setcolor(renderer,line_color); fprintf(renderer->file, "n %s %s m ", psrenderer_dtostr(px_buf, points[0].x), psrenderer_dtostr(py_buf, points[0].y) ); for (i=1;i<num_points;i++) { fprintf(renderer->file, "%s %s l ", psrenderer_dtostr(px_buf, points[i].x), psrenderer_dtostr(py_buf, points[i].y) ); } fprintf(renderer->file, "s\n"); }
static void draw_text_line(DiaRenderer *self, TextLine *text_line, Point *pos, Alignment alignment, Color *color) { DiaPsFt2Renderer *renderer = DIA_PS_FT2_RENDERER(self); PangoLayout *layout; int line, linecount; double xpos = pos->x, ypos = pos->y; char *text = text_line_get_string(text_line); /* TODO: we could probably pass the alignment down to the PS file? */ xpos -= text_line_get_alignment_adjustment (text_line, alignment); /* Using the global PangoContext does not allow to have renderer specific * different ones. Or it implies the push/pop _context mess. Anyway just * get rid of warnings for now. But the local code may be resurreted * sooner or later... --hb */ #define USE_GLOBAL_CONTEXT #ifndef USE_GLOBAL_CONTEXT PangoAttrList* list; PangoAttribute* attr; guint length; #endif if ((!text)||(text == (const char *)(1))) return; lazy_setcolor(DIA_PS_RENDERER(renderer),color); #define ANNOYING_SCALE_FACTOR 5.9 /* Make sure the letters aren't too wide. */ #ifdef USE_GLOBAL_CONTEXT layout = dia_font_build_layout(text, text_line_get_font(text_line), text_line_get_height(text_line)*ANNOYING_SCALE_FACTOR); #else /* approximately what would be required but w/o dia_font_get_context() */ dia_font_set_height(text_line_get_font(text_line), text_line_get_height(text_line)); layout = pango_layout_new(dia_font_get_context()); length = text ? strlen(text) : 0; pango_layout_set_text(layout,text,length); list = pango_attr_list_new(); attr = pango_attr_font_desc_new(dia_font_get_description(text_line_get_font(text_line))); attr->start_index = 0; attr->end_index = length; pango_attr_list_insert(list,attr); pango_layout_set_attributes(layout,list); pango_attr_list_unref(list); pango_layout_set_indent(layout,0); pango_layout_set_justify(layout,FALSE); #endif pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); linecount = pango_layout_get_line_count(layout); for (line = 0; line < linecount; line++) { PangoLayoutLine *layoutline = pango_layout_get_line(layout, line); /* Not sure scale is the right one here. */ text_line_adjust_layout_line(text_line, layoutline, ANNOYING_SCALE_FACTOR); postscript_draw_contour(DIA_PS_RENDERER(renderer), DPI, /* dpi_x */ layoutline, xpos, ypos); ypos += 10;/* Some line height thing??? */ } }
static void draw_image(DiaRenderer *self, Point *point, real width, real height, DiaImage *image) { DiaPsRenderer *renderer = DIA_PS_RENDERER(self); int img_width, img_height, img_rowstride; int x, y; guint8 *rgb_data; guint8 *mask_data; gchar d1_buf[DTOSTR_BUF_SIZE]; gchar d2_buf[DTOSTR_BUF_SIZE]; img_width = dia_image_width(image); img_rowstride = dia_image_rowstride(image); img_height = dia_image_height(image); rgb_data = dia_image_rgb_data(image); if (!rgb_data) { dia_context_add_message(renderer->ctx, _("Not enough memory for image drawing.")); return; } mask_data = dia_image_mask_data(image); fprintf(renderer->file, "gs\n"); /* color output only */ fprintf(renderer->file, "/pix %i string def\n", img_width * 3); fprintf(renderer->file, "%i %i 8\n", img_width, img_height); fprintf(renderer->file, "%s %s tr\n", psrenderer_dtostr(d1_buf, point->x), psrenderer_dtostr(d2_buf, point->y) ); fprintf(renderer->file, "%s %s sc\n", psrenderer_dtostr(d1_buf, width), psrenderer_dtostr(d2_buf, height) ); fprintf(renderer->file, "[%i 0 0 %i 0 0]\n", img_width, img_height); fprintf(renderer->file, "{currentfile pix readhexstring pop}\n"); fprintf(renderer->file, "false 3 colorimage\n"); fprintf(renderer->file, "\n"); if (mask_data) { for (y = 0; y < img_height; y++) { for (x = 0; x < img_width; x++) { int i = y*img_rowstride+x*3; int m = y*img_width+x; fprintf(renderer->file, "%02x", 255-(mask_data[m]*(255-rgb_data[i])/255)); fprintf(renderer->file, "%02x", 255-(mask_data[m]*(255-rgb_data[i+1])/255)); fprintf(renderer->file, "%02x", 255-(mask_data[m]*(255-rgb_data[i+2])/255)); } fprintf(renderer->file, "\n"); } } else { for (y = 0; y < img_height; y++) { for (x = 0; x < img_width; x++) { int i = y*img_rowstride+x*3; fprintf(renderer->file, "%02x", (int)(rgb_data[i])); fprintf(renderer->file, "%02x", (int)(rgb_data[i+1])); fprintf(renderer->file, "%02x", (int)(rgb_data[i+2])); } fprintf(renderer->file, "\n"); } } fprintf(renderer->file, "gr\n"); fprintf(renderer->file, "\n"); g_free(rgb_data); g_free(mask_data); }