X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Flabel-text.c;h=d9146c420aaa35c413ccd1c0dd5c01884a2ebc2b;hb=3943dd1240c9a6ef449fccfd52e7302baf9c5ae4;hp=aef20b8c565b641e7e5941b7020fafaf8ea4c4aa;hpb=4e81eb872bef66a6b76e9ffd74c09a83323f802e;p=glabels diff --git a/src/label-text.c b/src/label-text.c index aef20b8c..d9146c42 100644 --- a/src/label-text.c +++ b/src/label-text.c @@ -22,6 +22,7 @@ #include "label-text.h" +#include #include #include #include @@ -39,14 +40,20 @@ #define FONT_SCALE (72.0/96.0) +#define HANDLE_OUTLINE_RGBA_ARGS 0.5, 0.5, 0.5, 0.75 +#define HANDLE_OUTLINE_WIDTH_PIXELS 2.0 + +#define SELECTION_SLOP_PIXELS 4.0 + /*========================================================*/ /* Private types. */ /*========================================================*/ struct _glLabelTextPrivate { - GtkTextTagTable *tag_table; - GtkTextBuffer *buffer; + + GtkTextTagTable *tag_table; + GtkTextBuffer *buffer; gchar *font_family; gdouble font_size; @@ -60,6 +67,8 @@ struct _glLabelTextPrivate { gboolean size_changed; gdouble w; gdouble h; + + gboolean checkpoint_flag; }; @@ -77,6 +86,9 @@ static void gl_label_text_finalize (GObject *object); static void copy (glLabelObject *dst_object, glLabelObject *src_object); +static void buffer_begin_user_action_cb (GtkTextBuffer *textbuffer, + glLabelText *ltext); + static void buffer_changed_cb (GtkTextBuffer *textbuffer, glLabelText *ltext); @@ -85,25 +97,32 @@ static void get_size (glLabelObject *object, gdouble *h); static void set_font_family (glLabelObject *object, - const gchar *font_family); + const gchar *font_family, + gboolean checkpoint); static void set_font_size (glLabelObject *object, - gdouble font_size); + gdouble font_size, + gboolean checkpoint); static void set_font_weight (glLabelObject *object, - PangoWeight font_weight); + PangoWeight font_weight, + gboolean checkpoint); static void set_font_italic_flag (glLabelObject *object, - gboolean font_italic_flag); + gboolean font_italic_flag, + gboolean checkpoint); static void set_text_alignment (glLabelObject *object, - PangoAlignment text_alignment); + PangoAlignment text_alignment, + gboolean checkpoint); static void set_text_line_spacing (glLabelObject *object, - gdouble text_line_spacing); + gdouble text_line_spacing, + gboolean checkpoint); static void set_text_color (glLabelObject *object, - glColorNode *text_color_node); + glColorNode *text_color_node, + gboolean checkpoint); static gchar *get_font_family (glLabelObject *object); @@ -119,6 +138,11 @@ static gdouble get_text_line_spacing (glLabelObject *object); static glColorNode* get_text_color (glLabelObject *object); +static void set_text_path (glLabelText *this, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record); + static void draw_object (glLabelObject *object, cairo_t *cr, gboolean screen_flag, @@ -148,11 +172,14 @@ static gboolean object_at (glLabelObject *object, gdouble x_pixels, gdouble y_pixels); +static void draw_handles (glLabelObject *object, + cairo_t *cr); + /*****************************************************************************/ /* Object infrastructure. */ /*****************************************************************************/ -G_DEFINE_TYPE (glLabelText, gl_label_text, GL_TYPE_LABEL_OBJECT); +G_DEFINE_TYPE (glLabelText, gl_label_text, GL_TYPE_LABEL_OBJECT) /*****************************************************************************/ @@ -187,6 +214,7 @@ gl_label_text_class_init (glLabelTextClass *class) label_object_class->draw_object = draw_object; label_object_class->draw_shadow = draw_shadow; label_object_class->object_at = object_at; + label_object_class->draw_handles = draw_handles; object_class->finalize = gl_label_text_finalize; } @@ -205,6 +233,10 @@ gl_label_text_init (glLabelText *ltext) ltext->priv->size_changed = TRUE; + ltext->priv->checkpoint_flag = TRUE; + + g_signal_connect (G_OBJECT(ltext->priv->buffer), "begin-user-action", + G_CALLBACK(buffer_begin_user_action_cb), ltext); g_signal_connect (G_OBJECT(ltext->priv->buffer), "changed", G_CALLBACK(buffer_changed_cb), ltext); } @@ -234,7 +266,8 @@ gl_label_text_finalize (GObject *object) /** New Object Generator. */ /*****************************************************************************/ GObject * -gl_label_text_new (glLabel *label) +gl_label_text_new (glLabel *label, + gboolean checkpoint) { glLabelText *ltext; glColorNode *color_node; @@ -243,7 +276,10 @@ gl_label_text_new (glLabel *label) if (label != NULL) { - gl_label_object_set_parent (GL_LABEL_OBJECT(ltext), label); + if ( checkpoint ) + { + gl_label_checkpoint (label, _("Create text object")); + } color_node = gl_color_node_new_default (); @@ -256,6 +292,9 @@ gl_label_text_new (glLabel *label) ltext->priv->align = gl_label_get_default_text_alignment (label); ltext->priv->color_node = color_node; ltext->priv->line_spacing = gl_label_get_default_text_line_spacing (label); + + gl_label_add_object (label, GL_LABEL_OBJECT (ltext)); + gl_label_object_set_parent (GL_LABEL_OBJECT (ltext), label); } return G_OBJECT (ltext); @@ -281,13 +320,13 @@ copy (glLabelObject *dst_object, lines = gl_label_text_get_lines (ltext); text_color_node = get_text_color (src_object); - gl_label_text_set_lines (new_ltext, lines); + gl_label_text_set_lines (new_ltext, lines, FALSE); new_ltext->priv->font_family = g_strdup (ltext->priv->font_family); new_ltext->priv->font_size = ltext->priv->font_size; new_ltext->priv->font_weight = ltext->priv->font_weight; new_ltext->priv->font_italic_flag = ltext->priv->font_italic_flag; - set_text_color (dst_object, text_color_node); + set_text_color (dst_object, text_color_node, FALSE); new_ltext->priv->align = ltext->priv->align; new_ltext->priv->line_spacing = ltext->priv->line_spacing; new_ltext->priv->auto_shrink = ltext->priv->auto_shrink; @@ -308,7 +347,8 @@ copy (glLabelObject *dst_object, /*****************************************************************************/ void gl_label_text_set_lines (glLabelText *ltext, - GList *lines) + GList *lines, + gboolean checkpoint) { gchar *text; @@ -316,28 +356,37 @@ gl_label_text_set_lines (glLabelText *ltext, g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); + ltext->priv->checkpoint_flag = checkpoint; + text = gl_text_node_lines_expand (lines, NULL); gtk_text_buffer_set_text (ltext->priv->buffer, text, -1); g_free (text); ltext->priv->size_changed = TRUE; + ltext->priv->checkpoint_flag = TRUE; + gl_debug (DEBUG_LABEL, "END"); } void gl_label_text_set_text (glLabelText *ltext, - const gchar *text) + const gchar *text, + gboolean checkpoint) { gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); + ltext->priv->checkpoint_flag = checkpoint; + gtk_text_buffer_set_text (ltext->priv->buffer, text, -1); ltext->priv->size_changed = TRUE; + ltext->priv->checkpoint_flag = TRUE; + gl_debug (DEBUG_LABEL, "END"); } @@ -389,6 +438,23 @@ gl_label_text_get_text (glLabelText *ltext) } +/*****************************************************************************/ +/* Text buffer "changed" callback. */ +/*****************************************************************************/ +static void +buffer_begin_user_action_cb (GtkTextBuffer *textbuffer, + glLabelText *ltext) +{ + glLabel *label; + + if ( ltext->priv->checkpoint_flag ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Typing")); + } +} + + /*****************************************************************************/ /* Text buffer "changed" callback. */ /*****************************************************************************/ @@ -491,10 +557,12 @@ get_size (glLabelObject *object, /*****************************************************************************/ static void set_font_family (glLabelObject *object, - const gchar *font_family) + const gchar *font_family, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; gchar *good_font_family; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); @@ -511,6 +579,13 @@ set_font_family (glLabelObject *object, } g_free (ltext->priv->font_family); } + + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Font family")); + } + ltext->priv->font_family = g_strdup (good_font_family); g_free (good_font_family); @@ -531,21 +606,28 @@ set_font_family (glLabelObject *object, /*****************************************************************************/ static void set_font_size (glLabelObject *object, - gdouble font_size) + gdouble font_size, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (ltext->priv->font_size != font_size) { + if (ltext->priv->font_size != font_size) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Font size")); + } ltext->priv->size_changed = TRUE; ltext->priv->font_size = font_size; gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -557,21 +639,28 @@ set_font_size (glLabelObject *object, /*****************************************************************************/ static void set_font_weight (glLabelObject *object, - PangoWeight font_weight) + PangoWeight font_weight, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (ltext->priv->font_weight != font_weight) { + if (ltext->priv->font_weight != font_weight) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Font weight")); + } ltext->priv->size_changed = TRUE; ltext->priv->font_weight = font_weight; gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -583,21 +672,28 @@ set_font_weight (glLabelObject *object, /*****************************************************************************/ static void set_font_italic_flag (glLabelObject *object, - gboolean font_italic_flag) + gboolean font_italic_flag, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (ltext->priv->font_italic_flag != font_italic_flag) { + if (ltext->priv->font_italic_flag != font_italic_flag) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Italic")); + } ltext->priv->size_changed = TRUE; ltext->priv->font_italic_flag = font_italic_flag; gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -609,21 +705,28 @@ set_font_italic_flag (glLabelObject *object, /*****************************************************************************/ static void set_text_alignment (glLabelObject *object, - PangoAlignment text_alignment) + PangoAlignment text_alignment, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (ltext->priv->align != text_alignment) { + if (ltext->priv->align != text_alignment) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Align text")); + } ltext->priv->size_changed = TRUE; ltext->priv->align = text_alignment; gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -635,21 +738,28 @@ set_text_alignment (glLabelObject *object, /*****************************************************************************/ static void set_text_line_spacing (glLabelObject *object, - gdouble line_spacing) + gdouble line_spacing, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (ltext->priv->line_spacing != line_spacing) { + if (ltext->priv->line_spacing != line_spacing) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Line spacing")); + } ltext->priv->size_changed = TRUE; ltext->priv->line_spacing = line_spacing; gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -661,21 +771,28 @@ set_text_line_spacing (glLabelObject *object, /*****************************************************************************/ static void set_text_color (glLabelObject *object, - glColorNode *text_color_node) + glColorNode *text_color_node, + gboolean checkpoint) { glLabelText *ltext = (glLabelText *)object; + glLabel *label; gl_debug (DEBUG_LABEL, "START"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (!gl_color_node_equal (ltext->priv->color_node, text_color_node)) { + if (!gl_color_node_equal (ltext->priv->color_node, text_color_node)) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Text color")); + } gl_color_node_free (&(ltext->priv->color_node)); ltext->priv->color_node = gl_color_node_dup (text_color_node); gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -799,17 +916,25 @@ get_text_color (glLabelObject *object) /*****************************************************************************/ void gl_label_text_set_auto_shrink (glLabelText *ltext, - gboolean auto_shrink) + gboolean auto_shrink, + gboolean checkpoint) { + glLabel *label; + gl_debug (DEBUG_LABEL, "BEGIN"); g_return_if_fail (ltext && GL_IS_LABEL_TEXT (ltext)); - if (ltext->priv->auto_shrink != auto_shrink) { + if (ltext->priv->auto_shrink != auto_shrink) + { + if ( checkpoint ) + { + label = gl_label_object_get_parent (GL_LABEL_OBJECT (ltext)); + gl_label_checkpoint (label, _("Auto shrink")); + } ltext->priv->auto_shrink = auto_shrink; gl_label_object_emit_changed (GL_LABEL_OBJECT(ltext)); - } gl_debug (DEBUG_LABEL, "END"); @@ -831,146 +956,114 @@ gl_label_text_get_auto_shrink (glLabelText *ltext) /*****************************************************************************/ -/* Draw object method. */ +/* Automatically shrink text size to fit within horizontal width. */ /*****************************************************************************/ -static void -draw_object (glLabelObject *object, - cairo_t *cr, - gboolean screen_flag, - glMergeRecord *record) +static gdouble +auto_shrink_font_size (cairo_t *cr, + gchar *family, + gdouble size, + PangoWeight weight, + PangoStyle style, + gchar *text, + gdouble width) { - glColorNode *color_node; - guint color; + PangoLayout *layout; + PangoFontDescription *desc; + gint iw, ih; + gdouble layout_width; + gdouble new_size; - gl_debug (DEBUG_LABEL, "START"); + layout = pango_cairo_create_layout (cr); - color_node = gl_label_object_get_text_color (object); - color = gl_color_node_expand (color_node, record); - if (color_node->field_flag && screen_flag) - { - color = GL_COLOR_MERGE_DEFAULT; - } - gl_color_node_free (&color_node); - - draw_text_real (object, cr, screen_flag, record, color); + desc = pango_font_description_new (); + pango_font_description_set_family (desc, family); + pango_font_description_set_weight (desc, weight); + pango_font_description_set_style (desc, style); + pango_font_description_set_size (desc, size * PANGO_SCALE); - gl_debug (DEBUG_LABEL, "END"); -} + pango_layout_set_font_description (layout, desc); + pango_font_description_free (desc); + pango_layout_set_text (layout, text, -1); + pango_layout_set_width (layout, -1); + pango_layout_get_size (layout, &iw, &ih); + layout_width = (gdouble)iw / (gdouble)PANGO_SCALE; -/*****************************************************************************/ -/* Draw shadow method. */ -/*****************************************************************************/ -static void -draw_shadow (glLabelObject *object, - cairo_t *cr, - gboolean screen_flag, - glMergeRecord *record) -{ - glColorNode *color_node; - guint color; - glColorNode *shadow_color_node; - gdouble shadow_opacity; - guint shadow_color; + g_object_unref (layout); - gl_debug (DEBUG_LABEL, "START"); + g_print ("Object w = %g, layout w = %g\n", width, layout_width); - color_node = gl_label_object_get_text_color (object); - color = gl_color_node_expand (color_node, record); - if (color_node->field_flag && screen_flag) + if ( layout_width > width ) { - color = GL_COLOR_MERGE_DEFAULT; - } - gl_color_node_free (&color_node); - - shadow_color_node = gl_label_object_get_shadow_color (object); - if (shadow_color_node->field_flag) - { - shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT; - } - shadow_opacity = gl_label_object_get_shadow_opacity (object); - shadow_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, color); - gl_color_node_free (&shadow_color_node); + /* Scale down. */ + new_size = size * (width-2*GL_LABEL_TEXT_MARGIN)/layout_width; - draw_text_real (object, cr, screen_flag, record, shadow_color); + /* Round down to nearest 1/2 point */ + new_size = (int)(new_size*2.0) / 2.0; - gl_debug (DEBUG_LABEL, "END"); + /* don't get ridiculously small. */ + if (new_size < 1.0) + { + new_size = 1.0; + } + } + else + { + new_size = size; + } + + return new_size; } /*****************************************************************************/ -/* Draw text. */ +/* Update pango layout. */ /*****************************************************************************/ static void -draw_text_real (glLabelObject *object, - cairo_t *cr, - gboolean screen_flag, - glMergeRecord *record, - guint color) +set_text_path (glLabelText *this, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record) { - gdouble object_w, object_h; - gdouble raw_w, raw_h; - gchar *text; - GList *lines; - gchar *font_family; - gdouble font_size; - PangoWeight font_weight; - gboolean font_italic_flag; - gboolean auto_shrink; - gdouble text_line_spacing; - PangoAlignment alignment; - PangoStyle style; - PangoLayout *layout; + gdouble object_w, object_h; + gdouble raw_w, raw_h; + gchar *text; + GList *lines; + gdouble font_size; + gboolean auto_shrink; + PangoLayout *layout; + PangoStyle style; PangoFontDescription *desc; - gdouble scale_x, scale_y; cairo_font_options_t *font_options; PangoContext *context; - gl_debug (DEBUG_LABEL, "START"); + gl_debug (DEBUG_LABEL, "START"); - gl_label_object_get_size (object, &object_w, &object_h); - gl_label_object_get_raw_size (object, &raw_w, &raw_h); - lines = gl_label_text_get_lines (GL_LABEL_TEXT (object)); - font_family = gl_label_object_get_font_family (object); - font_size = gl_label_object_get_font_size (object) * FONT_SCALE; - font_weight = gl_label_object_get_font_weight (object); - font_italic_flag = gl_label_object_get_font_italic_flag (object); - - alignment = gl_label_object_get_text_alignment (object); - text_line_spacing = - gl_label_object_get_text_line_spacing (object); - auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object)); + cairo_save (cr); - text = gl_text_node_lines_expand (lines, record); + gl_label_object_get_size (GL_LABEL_OBJECT (this), &object_w, &object_h); + gl_label_object_get_raw_size (GL_LABEL_OBJECT (this), &raw_w, &raw_h); - style = font_italic_flag ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL; + lines = gl_label_text_get_lines (this); + text = gl_text_node_lines_expand (lines, record); + style = this->priv->font_italic_flag ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL; + font_size = this->priv->font_size; + auto_shrink = gl_label_text_get_auto_shrink (this); if (!screen_flag && record && auto_shrink && (raw_w != 0.0)) { font_size = auto_shrink_font_size (cr, - font_family, - font_size, - font_weight, + this->priv->font_family, + this->priv->font_size * FONT_SCALE, + this->priv->font_weight, style, text, object_w); } - /* - * Workaround for pango Bug#341481. - * Render font at device scale and scale font size accordingly. - */ - scale_x = 1.0; - scale_y = 1.0; - cairo_device_to_user_distance (cr, &scale_x, &scale_y); - scale_x = fabs (scale_x); - scale_y = fabs (scale_y); - cairo_save (cr); - cairo_scale (cr, scale_x, scale_y); - layout = pango_cairo_create_layout (cr); font_options = cairo_font_options_create (); @@ -980,101 +1073,125 @@ draw_text_real (glLabelObject *object, cairo_font_options_destroy (font_options); desc = pango_font_description_new (); - pango_font_description_set_family (desc, font_family); - pango_font_description_set_weight (desc, font_weight); + pango_font_description_set_family (desc, this->priv->font_family); + pango_font_description_set_weight (desc, this->priv->font_weight); + pango_font_description_set_size (desc, font_size * FONT_SCALE * PANGO_SCALE); pango_font_description_set_style (desc, style); - pango_font_description_set_size (desc, font_size * PANGO_SCALE / scale_x); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_text (layout, text, -1); - pango_layout_set_spacing (layout, font_size * (text_line_spacing-1) * PANGO_SCALE / scale_x); + pango_layout_set_spacing (layout, font_size * (this->priv->line_spacing-1) * PANGO_SCALE); if (raw_w == 0.0) { pango_layout_set_width (layout, -1); } else { - pango_layout_set_width (layout, object_w * PANGO_SCALE / scale_x); + pango_layout_set_width (layout, object_w * PANGO_SCALE); } - pango_layout_set_wrap (layout, PANGO_WRAP_CHAR); - pango_layout_set_alignment (layout, alignment); - + pango_layout_set_wrap (layout, PANGO_WRAP_WORD); + pango_layout_set_alignment (layout, this->priv->align); - cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (color)); - cairo_move_to (cr, GL_LABEL_TEXT_MARGIN/scale_x, 0); - pango_cairo_show_layout (cr, layout); - cairo_restore (cr); + cairo_move_to (cr, GL_LABEL_TEXT_MARGIN, 0); + pango_cairo_layout_path (cr, layout); g_object_unref (layout); + gl_text_node_lines_free (&lines); + cairo_restore (cr); - gl_text_node_lines_free (&lines); - g_free (font_family); - - gl_debug (DEBUG_LABEL, "END"); + gl_debug (DEBUG_LABEL, "END"); } /*****************************************************************************/ -/* Automatically shrink text size to fit within horizontal width. */ +/* Draw object method. */ /*****************************************************************************/ -static gdouble -auto_shrink_font_size (cairo_t *cr, - gchar *family, - gdouble size, - PangoWeight weight, - PangoStyle style, - gchar *text, - gdouble width) +static void +draw_object (glLabelObject *object, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record) { - PangoLayout *layout; - PangoFontDescription *desc; - gint iw, ih; - gdouble layout_width; - gdouble new_size; + glColorNode *color_node; + guint color; - layout = pango_cairo_create_layout (cr); + gl_debug (DEBUG_LABEL, "START"); - desc = pango_font_description_new (); - pango_font_description_set_family (desc, family); - pango_font_description_set_weight (desc, weight); - pango_font_description_set_style (desc, style); - pango_font_description_set_size (desc, size * PANGO_SCALE); - - pango_layout_set_font_description (layout, desc); - pango_font_description_free (desc); + color_node = gl_label_object_get_text_color (object); + color = gl_color_node_expand (color_node, record); + if (color_node->field_flag && screen_flag) + { + color = GL_COLOR_MERGE_DEFAULT; + } + gl_color_node_free (&color_node); - pango_layout_set_text (layout, text, -1); - pango_layout_set_width (layout, -1); - pango_layout_get_size (layout, &iw, &ih); - layout_width = (gdouble)iw / (gdouble)PANGO_SCALE; + draw_text_real (object, cr, screen_flag, record, color); - g_object_unref (layout); + gl_debug (DEBUG_LABEL, "END"); +} - g_print ("Object w = %g, layout w = %g\n", width, layout_width); - if ( layout_width > width ) - { - /* Scale down. */ - new_size = size * (width-2*GL_LABEL_TEXT_MARGIN)/layout_width; +/*****************************************************************************/ +/* Draw shadow method. */ +/*****************************************************************************/ +static void +draw_shadow (glLabelObject *object, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record) +{ + glColorNode *color_node; + guint color; + glColorNode *shadow_color_node; + gdouble shadow_opacity; + guint shadow_color; - /* Round down to nearest 1/2 point */ - new_size = (int)(new_size*2.0) / 2.0; + gl_debug (DEBUG_LABEL, "START"); - /* don't get ridiculously small. */ - if (new_size < 1.0) - { - new_size = 1.0; - } + color_node = gl_label_object_get_text_color (object); + color = gl_color_node_expand (color_node, record); + if (color_node->field_flag && screen_flag) + { + color = GL_COLOR_MERGE_DEFAULT; } - else + gl_color_node_free (&color_node); + + shadow_color_node = gl_label_object_get_shadow_color (object); + if (shadow_color_node->field_flag) { - new_size = size; + shadow_color_node->color = GL_COLOR_SHADOW_MERGE_DEFAULT; } + shadow_opacity = gl_label_object_get_shadow_opacity (object); + shadow_color = gl_color_shadow (shadow_color_node->color, shadow_opacity, color); + gl_color_node_free (&shadow_color_node); - return new_size; + draw_text_real (object, cr, screen_flag, record, shadow_color); + + gl_debug (DEBUG_LABEL, "END"); +} + + +/*****************************************************************************/ +/* Draw text. */ +/*****************************************************************************/ +static void +draw_text_real (glLabelObject *object, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record, + guint color) +{ + gl_debug (DEBUG_LABEL, "START"); + + set_text_path (GL_LABEL_TEXT (object), cr, screen_flag, record); + + cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (color)); + cairo_fill (cr); + + gl_debug (DEBUG_LABEL, "END"); } @@ -1088,20 +1205,89 @@ object_at (glLabelObject *object, gdouble y) { gdouble w, h; + gdouble scale_x, scale_y; gl_label_object_get_size (object, &w, &h); - cairo_rectangle (cr, 0.0, 0.0, w, h); - - if (cairo_in_fill (cr, x, y)) + if ( (x >= 0) && (x <= w) && (y >= 0) && (y <= h) ) { - return TRUE; + cairo_new_path (cr); + set_text_path (GL_LABEL_TEXT (object), cr, TRUE, NULL); + if (cairo_in_fill (cr, x, y)) + { + return TRUE; + } + + + scale_x = 1.0; + scale_y = 1.0; + cairo_device_to_user_distance (cr, &scale_x, &scale_y); + + cairo_set_line_width (cr, 2*SELECTION_SLOP_PIXELS*scale_x); + + if (cairo_in_stroke (cr, x, y)) + { + return TRUE; + } + + + if (gl_label_object_is_selected (object)) + { + cairo_new_path (cr); + cairo_rectangle (cr, 0, 0, w, h); + + scale_x = 1.0; + scale_y = 1.0; + cairo_device_to_user_distance (cr, &scale_x, &scale_y); + + cairo_set_line_width (cr, 2*SELECTION_SLOP_PIXELS*scale_x); + + if (cairo_in_stroke (cr, x, y)) + { + return TRUE; + } + } + } return FALSE; } +/*****************************************************************************/ +/* Draw text style handles. */ +/*****************************************************************************/ +static void +draw_handles (glLabelObject *object, + cairo_t *cr) +{ + gdouble w, h; + gdouble scale_x, scale_y; + gdouble dashes[2] = { 2, 2 }; + + gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h); + + cairo_save (cr); + + cairo_rectangle (cr, 0, 0, w, h); + + scale_x = 1.0; + scale_y = 1.0; + cairo_device_to_user_distance (cr, &scale_x, &scale_y); + cairo_scale (cr, scale_x, scale_y); + + cairo_set_dash (cr, dashes, 2, 0); + cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS); + cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS); + cairo_stroke (cr); + + cairo_restore (cr); + + gl_label_object_draw_handles_box (object, cr); +} + + + /* * Local Variables: -- emacs