Print styles and colors

master
Yevgen Muntyan 2006-03-27 19:27:57 -06:00
parent c96a736465
commit 405a237c21
3 changed files with 381 additions and 29 deletions

View File

@ -36,7 +36,7 @@
<useconfiguration>gtk-print</useconfiguration>
</general>
<run>
<mainprogram>medit</mainprogram>
<mainprogram>./medit</mainprogram>
<directoryradio>executable</directoryradio>
<customdirectory>/</customdirectory>
<programargs></programargs>
@ -288,16 +288,16 @@
</kdevdoctreeview>
<kdevfilecreate>
<filetypes>
<type icon="source" ext="g" create="template" name="GAP source" >
<type icon="source" ext="g" name="GAP source" create="template" >
<descr>A new empty GAP source file</descr>
</type>
<type icon="source_cpp" ext="cpp" create="template" name="C++ Source" >
<type icon="source_cpp" ext="cpp" name="C++ Source" create="template" >
<descr>A new empty C++ file.</descr>
</type>
<type icon="source_h" ext="h" create="template" name="C/C++ Header" >
<type icon="source_h" ext="h" name="C/C++ Header" create="template" >
<descr>A new empty header file for C/C++.</descr>
</type>
<type icon="source_c" ext="c" create="template" name="C Source" >
<type icon="source_c" ext="c" name="C Source" create="template" >
<descr>A new empty C file.</descr>
</type>
</filetypes>

View File

@ -42,7 +42,13 @@ G_DEFINE_TYPE(MooPrintOperation, moo_print_operation, GTK_TYPE_PRINT_OPERATION)
enum {
PROP_0,
PROP_DOC
PROP_DOC,
PROP_BUFFER,
PROP_WRAP,
PROP_WRAP_MODE,
PROP_ELLIPSIZE,
PROP_FONT,
PROP_USE_STYLES
};
@ -74,6 +80,36 @@ moo_print_operation_set_property (GObject *object,
moo_print_operation_set_doc (print, g_value_get_object (value));
break;
case PROP_BUFFER:
moo_print_operation_set_buffer (print, g_value_get_object (value));
break;
case PROP_WRAP:
print->wrap = g_value_get_boolean (value) != 0;
g_object_notify (object, "wrap");
break;
case PROP_WRAP_MODE:
print->wrap_mode = g_value_get_enum (value);
g_object_notify (object, "wrap-mode");
break;
case PROP_ELLIPSIZE:
print->ellipsize = g_value_get_boolean (value) != 0;
g_object_notify (object, "ellipsize");
break;
case PROP_FONT:
g_free (print->font);
print->font = g_value_dup_string (value);
g_object_notify (object, "font");
break;
case PROP_USE_STYLES:
print->use_styles = g_value_get_boolean (value);
g_object_notify (object, "use-styles");
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -94,6 +130,30 @@ moo_print_operation_get_property (GObject *object,
g_value_set_object (value, print->doc);
break;
case PROP_BUFFER:
g_value_set_object (value, print->buffer);
break;
case PROP_WRAP:
g_value_set_boolean (value, print->wrap);
break;
case PROP_WRAP_MODE:
g_value_set_enum (value, print->wrap_mode);
break;
case PROP_ELLIPSIZE:
g_value_set_boolean (value, print->ellipsize);
break;
case PROP_FONT:
g_value_set_string (value, print->font);
break;
case PROP_USE_STYLES:
g_value_set_boolean (value, print->use_styles);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@ -120,7 +180,56 @@ moo_print_operation_class_init (MooPrintOperationClass *klass)
"doc",
"doc",
GTK_TYPE_TEXT_VIEW,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_BUFFER,
g_param_spec_object ("buffer",
"buffer",
"buffer",
GTK_TYPE_TEXT_BUFFER,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_FONT,
g_param_spec_string ("font",
"font",
"font",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_WRAP,
g_param_spec_boolean ("wrap",
"wrap",
"wrap",
TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_WRAP_MODE,
g_param_spec_enum ("wrap-mode",
"wrap-mode",
"wrap-mode",
PANGO_TYPE_WRAP_MODE,
PANGO_WRAP_WORD_CHAR,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_ELLIPSIZE,
g_param_spec_boolean ("ellipsize",
"ellipsize",
"ellipsize",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_USE_STYLES,
g_param_spec_boolean ("use-styles",
"use-styles",
"use-styles",
TRUE,
G_PARAM_READWRITE));
}
@ -128,6 +237,7 @@ static void
moo_print_operation_init (MooPrintOperation *print)
{
load_default_settings ();
gtk_print_operation_set_print_settings (GTK_PRINT_OPERATION (print),
print_settings);
@ -136,8 +246,10 @@ moo_print_operation_init (MooPrintOperation *print)
page_setup);
print->last_line = -1;
print->wrap = FALSE;
print->ellipsize = TRUE;
print->wrap = TRUE;
print->wrap_mode = PANGO_WRAP_WORD_CHAR;
print->ellipsize = FALSE;
print->use_styles = TRUE;
}
@ -148,6 +260,9 @@ moo_print_operation_set_doc (MooPrintOperation *print,
g_return_if_fail (MOO_IS_PRINT_OPERATION (print));
g_return_if_fail (!doc || GTK_IS_TEXT_VIEW (doc));
if (print->doc == doc)
return;
if (print->doc)
g_object_unref (print->doc);
if (print->buffer)
@ -165,6 +280,36 @@ moo_print_operation_set_doc (MooPrintOperation *print,
{
print->buffer = NULL;
}
g_object_freeze_notify (G_OBJECT (print));
g_object_notify (G_OBJECT (print), "doc");
g_object_notify (G_OBJECT (print), "buffer");
g_object_thaw_notify (G_OBJECT (print));
}
void
moo_print_operation_set_buffer (MooPrintOperation *print,
GtkTextBuffer *buffer)
{
g_return_if_fail (MOO_IS_PRINT_OPERATION (print));
g_return_if_fail (!buffer || GTK_IS_TEXT_BUFFER (buffer));
if (print->buffer == buffer)
return;
if (print->doc)
g_object_unref (print->doc);
if (print->buffer)
g_object_unref (print->buffer);
print->doc = NULL;
print->buffer = buffer;
if (print->buffer)
g_object_ref (print->buffer);
g_object_notify (G_OBJECT (print), "buffer");
}
@ -221,7 +366,7 @@ moo_print_operation_begin_print (GtkPrintOperation *operation,
GtkTextIter iter, print_end;
GTimer *timer;
g_return_if_fail (print->doc != NULL);
g_return_if_fail (print->buffer != NULL);
g_return_if_fail (print->first_line >= 0);
g_return_if_fail (print->last_line < 0 || print->last_line >= print->first_line);
g_return_if_fail (print->first_line < gtk_text_buffer_get_line_count (print->buffer));
@ -239,7 +384,7 @@ moo_print_operation_begin_print (GtkPrintOperation *operation,
if (print->font)
font = pango_font_description_from_string (print->font);
if (!font)
if (!font && print->doc)
{
PangoContext *widget_ctx;
@ -259,7 +404,7 @@ moo_print_operation_begin_print (GtkPrintOperation *operation,
if (print->wrap)
{
pango_layout_set_width (print->layout, print->page.width * PANGO_SCALE);
pango_layout_set_wrap (print->layout, PANGO_WRAP_CHAR);
pango_layout_set_wrap (print->layout, print->wrap_mode);
}
else if (print->ellipsize)
{
@ -355,6 +500,221 @@ moo_print_operation_begin_print (GtkPrintOperation *operation,
}
static GSList *
iter_get_attrs (GtkTextIter *iter,
const GtkTextIter *limit)
{
GtkTextIter end;
GtkTextAttributes values;
gboolean has_attributes = FALSE;
GSList *attrs = NULL, *tags;
PangoAttribute *bg = NULL, *fg = NULL, *style = NULL, *ul = NULL;
PangoAttribute *weight = NULL, *st = NULL;
tags = gtk_text_iter_get_tags (iter);
gtk_text_iter_forward_to_tag_toggle (iter, NULL);
if (gtk_text_iter_compare (iter, limit) > 0)
*iter = *limit;
while (tags)
{
GtkTextTag *tag = tags->data;
gboolean bg_set, fg_set, style_set, ul_set, weight_set, st_set;
g_object_get (tag,
"background-set", &bg_set,
"foreground-set", &fg_set,
"style-set", &style_set,
"underline-set", &ul_set,
"weight-set", &weight_set,
"strikethrough-set", &st_set,
NULL);
if (bg_set)
{
GdkColor *color = NULL;
if (bg) pango_attribute_destroy (bg);
g_object_get (tag, "background-gdk", &color, NULL);
bg = pango_attr_background_new (color->red, color->green, color->blue);
gdk_color_free (color);
}
if (fg_set)
{
GdkColor *color = NULL;
if (fg) pango_attribute_destroy (fg);
g_object_get (tag, "foreground-gdk", &color, NULL);
fg = pango_attr_foreground_new (color->red, color->green, color->blue);
gdk_color_free (color);
}
if (style_set)
{
PangoStyle style_value;
if (style) pango_attribute_destroy (style);
g_object_get (tag, "style", &style_value, NULL);
style = pango_attr_style_new (style_value);
}
if (ul_set)
{
PangoUnderline underline;
if (ul) pango_attribute_destroy (ul);
g_object_get (tag, "underline", &underline, NULL);
ul = pango_attr_underline_new (underline);
}
if (weight_set)
{
PangoWeight weight_value;
if (weight) pango_attribute_destroy (weight);
g_object_get (tag, "weight", &weight_value, NULL);
weight = pango_attr_weight_new (weight_value);
}
if (st_set)
{
gboolean strikethrough;
if (st) pango_attribute_destroy (st);
g_object_get (tag, "strikethrough", &strikethrough, NULL);
st = pango_attr_strikethrough_new (strikethrough);
}
tags = g_slist_delete_link (tags, tags);
}
if (bg)
attrs = g_slist_prepend (attrs, bg);
if (fg)
attrs = g_slist_prepend (attrs, fg);
if (style)
attrs = g_slist_prepend (attrs, style);
if (ul)
attrs = g_slist_prepend (attrs, ul);
if (weight)
attrs = g_slist_prepend (attrs, weight);
if (st)
attrs = g_slist_prepend (attrs, st);
return attrs;
}
static void
fill_layout (PangoLayout *layout,
const GtkTextIter *start,
const GtkTextIter *end)
{
char *text;
PangoAttrList *attr_list;
GtkTextIter segm_start, segm_end;
int start_index;
text = gtk_text_iter_get_text (start, end);
pango_layout_set_text (layout, text, -1);
attr_list = NULL;
segm_start = *start;
start_index = gtk_text_iter_get_line_index (start);
while (gtk_text_iter_compare (&segm_start, end) < 0)
{
GSList *attrs;
segm_end = segm_start;
attrs = iter_get_attrs (&segm_end, end);
if (attrs)
{
int si, ei;
si = gtk_text_iter_get_line_index (&segm_start) - start_index;
ei = gtk_text_iter_get_line_index (&segm_end) - start_index;
while (attrs)
{
PangoAttribute *a = attrs->data;
a->start_index = si;
a->end_index = ei;
if (!attr_list)
attr_list = pango_attr_list_new ();
pango_attr_list_insert (attr_list, a);
attrs = g_slist_delete_link (attrs, attrs);
}
}
segm_start = segm_end;
}
pango_layout_set_attributes (layout, attr_list);
if (attr_list)
pango_attr_list_unref (attr_list);
}
static void
print_page (MooPrintOperation *print,
const GtkTextIter *start,
const GtkTextIter *end,
cairo_t *cr)
{
char *text;
GtkTextIter line_start, line_end;
double offset;
cairo_set_source_rgb (cr, 0, 0, 0);
if (!print->use_styles)
{
text = gtk_text_buffer_get_text (print->buffer, start, end, FALSE);
pango_layout_set_text (print->layout, text, -1);
g_free (text);
cairo_move_to (cr, print->page.x, print->page.y);
pango_cairo_show_layout (cr, print->layout);
return;
}
line_start = *start;
offset = 0;
while (gtk_text_iter_compare (&line_start, end) < 0)
{
PangoRectangle line_rect;
if (gtk_text_iter_ends_line (&line_start))
{
pango_layout_set_text (print->layout, "", 0);
pango_layout_set_attributes (print->layout, NULL);
}
else
{
line_end = line_start;
gtk_text_iter_forward_to_line_end (&line_end);
if (gtk_text_iter_compare (&line_end, end) > 0)
line_end = *end;
fill_layout (print->layout,&line_start, &line_end);
}
cairo_move_to (cr, 0, offset);
pango_cairo_show_layout (cr, print->layout);
pango_layout_get_pixel_extents (print->layout, NULL, &line_rect);
offset += line_rect.height;
gtk_text_iter_forward_line (&line_start);
}
}
static void
moo_print_operation_draw_page (GtkPrintOperation *operation,
GtkPrintContext *context,
@ -366,7 +726,7 @@ moo_print_operation_draw_page (GtkPrintOperation *operation,
MooPrintOperation *print = MOO_PRINT_OPERATION (operation);
GTimer *timer;
g_return_if_fail (print->doc != NULL);
g_return_if_fail (print->buffer != NULL);
g_return_if_fail (print->pages != NULL);
g_return_if_fail (print->layout != NULL);
g_return_if_fail (page_nr < print->pages->len);
@ -374,7 +734,6 @@ moo_print_operation_draw_page (GtkPrintOperation *operation,
timer = g_timer_new ();
cr = gtk_print_context_get_cairo (context);
cairo_set_source_rgb (cr, 0, 0, 0);
start = g_array_index (print->pages, GtkTextIter, page_nr);
@ -383,12 +742,7 @@ moo_print_operation_draw_page (GtkPrintOperation *operation,
else
gtk_text_buffer_get_end_iter (print->buffer, &end);
text = gtk_text_buffer_get_text (print->buffer, &start, &end, FALSE);
pango_layout_set_text (print->layout, text, -1);
g_free (text);
cairo_move_to (cr, print->page.x, print->page.y);
pango_cairo_show_layout (cr, print->layout);
print_page (print, &start, &end, cr);
g_message ("page %d: %f s", page_nr, g_timer_elapsed (timer, NULL));
g_timer_destroy (timer);
@ -401,7 +755,7 @@ moo_print_operation_end_print (GtkPrintOperation *operation,
{
MooPrintOperation *print = MOO_PRINT_OPERATION (operation);
g_return_if_fail (print->doc != NULL);
g_return_if_fail (print->buffer != NULL);
g_object_unref (print->layout);
g_array_free (print->pages, TRUE);
@ -425,17 +779,11 @@ moo_edit_print (GtkTextView *view,
print = g_object_new (MOO_TYPE_PRINT_OPERATION, "doc", view, NULL);
{
GtkTextIter start, end;
GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
gtk_text_buffer_get_bounds (buffer, &start, &end);
g_assert (strlen (gtk_text_buffer_get_text (buffer, &start, &end, FALSE)) > 0);
g_assert (MOO_PRINT_OPERATION(print)->last_line < 0);
}
if (!parent)
parent = GTK_WIDGET (view);
parent = gtk_widget_get_toplevel (parent);
if (GTK_WIDGET_TOPLEVEL (parent))
parent_window = GTK_WINDOW (parent);

View File

@ -41,7 +41,9 @@ struct _MooPrintOperation
int last_line; /* -1 to print everything after first_line */
char *font; /* overrides font set in the doc */
gboolean wrap;
PangoWrapMode wrap_mode;
gboolean ellipsize;
gboolean use_styles;
/* aux stuff */
GArray *pages; /* GtkTextIter's pointing to pages start */
@ -65,6 +67,8 @@ GType moo_print_operation_get_type (void) G_GNUC_CONST;
void moo_print_operation_set_doc (MooPrintOperation *print,
GtkTextView *doc);
void moo_print_operation_set_buffer (MooPrintOperation *print,
GtkTextBuffer *buffer);
void moo_edit_page_setup (GtkTextView *view,
GtkWidget *parent);