/* dia-export-print.c * Copyright (C) 2002 Nik Kim , Arjan Molenaar * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "dia-export-print.h" #include "dia-canvas-groupable.h" #ifndef DIACANVAS2_HAS_GNOME_PRINT void dia_export_print (gpointer gpm, DiaCanvas *canvas) { } #else /* !DIACANVAS2_HAS_GNOME_PRINT */ #include #include #include #include #include #include /* used by print_path() to set the currentpath. Somehow using * gnome_print_vpath() doesn't give the desired result. */ static inline void _print_path(ArtVpath *vpath, GnomePrintContext *context) { gnome_print_newpath (context); while (vpath->code != ART_END) { switch (vpath->code) { case ART_MOVETO: gnome_print_moveto (context, vpath->x, vpath->y); break; case ART_LINETO: gnome_print_lineto (context, vpath->x, vpath->y); break; default: break; } vpath++; } } static void print_path (DiaShapePath *shape, GnomePrintContext *context) { if (!shape->vpath || shape->vpath->code == ART_END) return; /* First define the fill shape */ if (shape->fill != DIA_FILL_NONE && DIA_COLOR_ALPHA (shape->fill_color) > 0) { _print_path (shape->vpath, context); gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->fill_color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->fill_color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->fill_color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->fill_color)) /255.0); gnome_print_eofill (context); } _print_path (shape->vpath, context); if (shape->cyclic) gnome_print_closepath(context); gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->shape.color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->shape.color)) / 255.0); gnome_print_setlinewidth (context, shape->line_width); gnome_print_setlinejoin (context, shape->join); gnome_print_setlinecap (context, shape->cap); gnome_print_stroke (context); } static void print_bezier (DiaShapeBezier *shape, GnomePrintContext *context) { if (!shape->bpath || shape->bpath->code == ART_END) return; if (shape->fill != DIA_FILL_NONE && DIA_COLOR_ALPHA (shape->fill_color) > 0) { gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->fill_color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->fill_color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->fill_color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->fill_color)) /255.0); gnome_print_bpath (context, shape->bpath, FALSE); gnome_print_eofill (context); } gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->shape.color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->shape.color)) / 255.0); gnome_print_setlinewidth (context, shape->line_width); gnome_print_setlinejoin (context, shape->join); gnome_print_setlinecap (context, shape->cap); gnome_print_newpath (context); gnome_print_bpath (context, shape->bpath, FALSE); if (shape->cyclic) gnome_print_closepath(context); gnome_print_stroke (context); } static void print_ellipse (DiaShapeEllipse *shape, GnomePrintContext *context) { gdouble r = 0.0, zoom; if (shape->height > shape->width) { r = shape->height; zoom = shape->width/shape->height; gnome_print_translate (context, shape->center.y-shape->center.y*zoom,0); gnome_print_scale (context, zoom, 1); } else { r = shape->width; zoom = shape->height/shape->width; gnome_print_translate (context, 0,shape->center.x-shape->center.x*zoom); gnome_print_scale (context, 1, zoom); } if (shape->fill != DIA_FILL_NONE && DIA_COLOR_ALPHA (shape->fill_color) > 0) { gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->fill_color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->fill_color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->fill_color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->fill_color)) /255.0); gnome_print_arcto (context, shape->center.x, shape->center.y, r/2,0,359,0); gnome_print_fill (context); } gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->shape.color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->shape.color)) / 255.0); gnome_print_setlinewidth (context, shape->line_width); gnome_print_arcto (context, shape->center.x, shape->center.y, r/2,0,359,0); gnome_print_stroke (context); } static void print_text (DiaShapeText *shape, GnomePrintContext *context) { GnomeFont *font; GnomeFontFace *font_face; PangoFontDescription *font_desc; PangoLayout *layout = dia_shape_text_to_pango_layout ((DiaShape *)shape, TRUE); PangoLayoutLine *line; PangoLayoutIter *layout_iter; PangoRectangle irect, lrect; guchar *line_text; PangoStyle style; gboolean italic; if (!shape->text) return; gnome_print_concat (context, shape->affine); /* Set up a clipping rectangle */ if (shape->max_width < G_MAXINT && shape->max_height < G_MAXINT) { gnome_print_newpath (context); gnome_print_moveto (context, 0.0, 0.0); gnome_print_lineto (context, (gdouble) shape->max_width, 0.0); gnome_print_lineto (context, (gdouble) shape->max_width, (gdouble) shape->max_height); gnome_print_lineto (context, 0.0, (gdouble) shape->max_height); gnome_print_clip (context); } gnome_print_setrgbcolor (context, ((gdouble) DIA_COLOR_RED (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_GREEN (shape->shape.color)) /255.0, ((gdouble) DIA_COLOR_BLUE (shape->shape.color)) /255.0); gnome_print_setopacity (context, ((gdouble) DIA_COLOR_ALPHA (shape->shape.color)) / 255.0); /* set context font */ if (shape->font_desc) font_desc = shape->font_desc; else font_desc = pango_context_get_font_description ( pango_layout_get_context (layout)); style = pango_font_description_get_style (font_desc); italic = ((style == PANGO_STYLE_OBLIQUE) || (style == PANGO_STYLE_ITALIC)); font_face = gnome_font_face_find_closest_from_weight_slant ( pango_font_description_get_family (font_desc), pango_font_description_get_weight (font_desc), italic); font = gnome_font_face_get_font_default ( font_face, (pango_font_description_get_size (font_desc)/PANGO_SCALE+8/3)); gnome_print_setfont (context, font); /* iterate on lines*/ layout_iter = pango_layout_get_iter (layout); if (layout_iter) do { line = pango_layout_iter_get_line (layout_iter); pango_layout_iter_get_line_extents (layout_iter, &irect, &lrect); gnome_print_gsave (context); line_text = g_malloc0(line->length+1); g_strlcpy (line_text, &(shape->text[line->start_index]),line->length+1); //gnome_print_translate (context, 0, (lrect.height-irect.y)/PANGO_SCALE); gnome_print_moveto (context, ((gdouble)irect.x)/PANGO_SCALE, ((gdouble)irect.y + lrect.height/2)/PANGO_SCALE); gnome_print_scale (context, 1, -1); gnome_print_show (context, line_text); gnome_print_grestore (context); g_free (line_text); } while (pango_layout_iter_next_line (layout_iter)); pango_layout_iter_free (layout_iter); g_object_unref (font); g_object_unref (font_face); g_object_unref (layout); } static void print_image (DiaShapeImage *shape, GnomePrintContext *context) { if (!shape->pixbuf) return; gnome_print_concat (context, shape->affine); gnome_print_translate (context, 0.0, (gdouble) gdk_pixbuf_get_height (shape->pixbuf)); gnome_print_scale (context, (gdouble) gdk_pixbuf_get_width (shape->pixbuf), (gdouble) -gdk_pixbuf_get_height (shape->pixbuf)); gnome_print_setopacity (context, 1.0); if (gdk_pixbuf_get_has_alpha (shape->pixbuf)) { gnome_print_rgbaimage (context, gdk_pixbuf_get_pixels (shape->pixbuf), gdk_pixbuf_get_width (shape->pixbuf), gdk_pixbuf_get_height (shape->pixbuf), gdk_pixbuf_get_rowstride (shape->pixbuf)); } else { gnome_print_rgbimage (context, gdk_pixbuf_get_pixels (shape->pixbuf), gdk_pixbuf_get_width (shape->pixbuf), gdk_pixbuf_get_height (shape->pixbuf), gdk_pixbuf_get_rowstride (shape->pixbuf)); } } static void print_item (DiaCanvasItem *item, GnomePrintContext *context) { DiaCanvasIter iter; DiaShape *shape; gnome_print_gsave (context); gnome_print_concat (context, item->affine); if (dia_canvas_item_get_shape_iter (item, &iter)) do { shape = dia_canvas_item_shape_value (item, &iter); if (shape->visibility != DIA_SHAPE_VISIBLE) continue; gnome_print_gsave (context); switch (shape->type) { case DIA_SHAPE_PATH: print_path ((DiaShapePath *)shape, context); break; case DIA_SHAPE_BEZIER: print_bezier ((DiaShapeBezier *)shape, context); break; case DIA_SHAPE_ELLIPSE: print_ellipse ((DiaShapeEllipse *)shape, context); break; case DIA_SHAPE_TEXT: print_text ((DiaShapeText *)shape, context); break; case DIA_SHAPE_IMAGE: print_image ((DiaShapeImage *)shape, context); break; case DIA_SHAPE_WIDGET: g_message (G_STRLOC": Widget not yet implemented."); break; case DIA_SHAPE_CLIP: g_message (G_STRLOC": Clip not yet implemented."); break; default: g_message ("Shape with type %d is not (yet) implemented", shape->type); break; } gnome_print_grestore (context); } while (dia_canvas_item_shape_next (item, &iter)); if (DIA_IS_CANVAS_GROUPABLE (item) && dia_canvas_groupable_get_iter (DIA_CANVAS_GROUPABLE (item), &iter)) do { print_item (dia_canvas_groupable_value (DIA_CANVAS_GROUPABLE (item), &iter), context); } while (dia_canvas_groupable_next (DIA_CANVAS_GROUPABLE (item), &iter)); gnome_print_grestore (context); } void dia_export_print (GnomePrintJob *gpm, DiaCanvas *canvas) { gboolean old_state_requests; GnomePrintConfig *config = gnome_print_job_get_config (gpm); GnomePrintContext *context = gnome_print_job_get_context (gpm); gdouble height = 29.7 * (72.0 / 2.54); gdouble affine[6] = {1, 0, 0, -1, 0, height}; const GnomePrintUnit *unit; // calc page height in pt if (gnome_print_config_get_length ( config, GNOME_PRINT_KEY_PAPER_HEIGHT, &height, &unit)) { gnome_print_convert_distance (&height, unit, GNOME_PRINT_PS_UNIT); affine[5] = height; } gnome_print_gsave (context); gnome_print_concat (context, affine); /* Disable state requests... */ old_state_requests = canvas->allow_state_requests; g_object_set (canvas, "allow-state-requests", FALSE, NULL); print_item (canvas->root, context); g_object_set (canvas, "allow-state-requests", old_state_requests ? TRUE : FALSE, NULL); gnome_print_grestore (context); } #endif /* DIACANVAS2_HAS_GNOME_PRINT */