[gimp] Bug 662787 - Segfaults when trying to set a large text size
- From: Jehan Pagès <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 662787 - Segfaults when trying to set a large text size
- Date: Thu, 24 Oct 2013 07:24:40 +0000 (UTC)
commit 2aabbbd9c733a9078d08b15bedef6e9adae1031f
Author: Jehan <jehan girinstud io>
Date: Sat Aug 31 03:16:44 2013 +1200
Bug 662787 - Segfaults when trying to set a large text size
If a font size is too big for cairo or pango to deal with, nicely back
up from rendering and alert the user via an error dialog.
app/text/gimptext-vectors.c | 9 ++++++++-
app/text/gimptextlayer.c | 24 ++++++++++++++++++++++--
app/text/gimptextlayout.c | 41 ++++++++++++++++++++++++++++++++++++-----
app/text/gimptextlayout.h | 3 ++-
app/tools/gimptexttool.c | 8 +++++++-
5 files changed, 75 insertions(+), 10 deletions(-)
---
diff --git a/app/text/gimptext-vectors.c b/app/text/gimptext-vectors.c
index e7ef488..600c967 100644
--- a/app/text/gimptext-vectors.c
+++ b/app/text/gimptext-vectors.c
@@ -26,6 +26,7 @@
#include "text-types.h"
+#include "core/gimp.h"
#include "core/gimpimage.h"
#include "vectors/gimpbezierstroke.h"
@@ -69,6 +70,7 @@ gimp_text_vectors_new (GimpImage *image,
cairo_t *cr;
gdouble xres;
gdouble yres;
+ GError *error = NULL;
if (text->text)
gimp_object_set_name_safe (GIMP_OBJECT (vectors), text->text);
@@ -80,7 +82,12 @@ gimp_text_vectors_new (GimpImage *image,
gimp_image_get_resolution (image, &xres, &yres);
- layout = gimp_text_layout_new (text, xres, yres);
+ layout = gimp_text_layout_new (text, xres, yres, &error);
+ if (error)
+ {
+ gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
+ g_error_free (error);
+ }
gimp_text_layout_render (layout, cr, text->base_dir, TRUE);
g_object_unref (layout);
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index bc85a04..0097d33 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -614,6 +614,7 @@ gimp_text_layer_render (GimpTextLayer *layer)
gdouble yres;
gint width;
gint height;
+ GError *error = NULL;
if (! layer->text)
return FALSE;
@@ -632,7 +633,12 @@ gimp_text_layer_render (GimpTextLayer *layer)
gimp_image_get_resolution (image, &xres, &yres);
- layout = gimp_text_layout_new (layer->text, xres, yres);
+ layout = gimp_text_layout_new (layer->text, xres, yres, &error);
+ if (error)
+ {
+ gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
+ g_error_free (error);
+ }
g_object_freeze_notify (G_OBJECT (drawable));
@@ -693,7 +699,8 @@ gimp_text_layer_render (GimpTextLayer *layer)
}
}
- gimp_text_layer_render_layout (layer, layout);
+ if (width > 0 && height > 0)
+ gimp_text_layer_render_layout (layer, layout);
g_object_unref (layout);
@@ -713,6 +720,7 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
cairo_surface_t *surface;
gint width;
gint height;
+ cairo_status_t status;
g_return_if_fail (gimp_drawable_has_alpha (drawable));
@@ -720,6 +728,18 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
height = gimp_item_get_height (item);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ status = cairo_surface_status (surface);
+
+ if (status != CAIRO_STATUS_SUCCESS)
+ {
+ GimpImage *image = gimp_item_get_image (item);
+
+ gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR,
+ _("Your text cannot be rendered. It is likely too big. "
+ "Please make it shorter or use a smaller font."));
+ cairo_surface_destroy (surface);
+ return;
+ }
cr = cairo_create (surface);
gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
diff --git a/app/text/gimptextlayout.c b/app/text/gimptextlayout.c
index c4dc0c8..02c43ad 100644
--- a/app/text/gimptextlayout.c
+++ b/app/text/gimptextlayout.c
@@ -32,9 +32,12 @@
#include "text-types.h"
+#include "core/gimperror.h"
+
#include "gimptext.h"
#include "gimptextlayout.h"
+#include "gimp-intl.h"
struct _GimpTextLayout
{
@@ -51,7 +54,8 @@ struct _GimpTextLayout
static void gimp_text_layout_finalize (GObject *object);
static void gimp_text_layout_position (GimpTextLayout *layout);
-static void gimp_text_layout_set_markup (GimpTextLayout *layout);
+static void gimp_text_layout_set_markup (GimpTextLayout *layout,
+ GError **error);
static PangoContext * gimp_text_get_pango_context (GimpText *text,
gdouble xres,
@@ -101,7 +105,8 @@ gimp_text_layout_finalize (GObject *object)
GimpTextLayout *
gimp_text_layout_new (GimpText *text,
gdouble xres,
- gdouble yres)
+ gdouble yres,
+ GError **error)
{
GimpTextLayout *layout;
PangoContext *context;
@@ -136,7 +141,7 @@ gimp_text_layout_new (GimpText *text,
pango_layout_set_font_description (layout->layout, font_desc);
pango_font_description_free (font_desc);
- gimp_text_layout_set_markup (layout);
+ gimp_text_layout_set_markup (layout, error);
switch (text->justify)
{
@@ -510,7 +515,8 @@ gimp_text_layout_apply_tags (GimpTextLayout *layout,
}
static void
-gimp_text_layout_set_markup (GimpTextLayout *layout)
+gimp_text_layout_set_markup (GimpTextLayout *layout,
+ GError **error)
{
GimpText *text = layout->text;
gchar *open_tag = NULL;
@@ -550,7 +556,32 @@ gimp_text_layout_set_markup (GimpTextLayout *layout)
g_free (tagged);
g_free (close_tag);
- pango_layout_set_markup (layout->layout, markup, -1);
+ if (pango_parse_markup (markup, -1, 0, NULL, NULL, NULL, error) == FALSE)
+ {
+ if (error && *error &&
+ (*error)->domain == G_MARKUP_ERROR &&
+ (*error)->code == G_MARKUP_ERROR_INVALID_CONTENT)
+ {
+ /* Errors from pango lib are not accurate enough.
+ * Other possible error codes are: G_MARKUP_ERROR_UNKNOWN_ELEMENT
+ * and G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, which likely indicate a bug
+ * in GIMP code or a pango library version issue.
+ * G_MARKUP_ERROR_INVALID_CONTENT on the other hand likely indicates
+ * size/color/style/weight/variant/etc. value issue. Font size is the
+ * only free text in GIMP GUI so we assume that must be it.
+ * Also we output a custom message because pango's error->message is
+ * too technical (telling of <span> tags, not using user's font size
+ * unit, and such). */
+ g_error_free (*error);
+ *error = NULL;
+ g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
+ _("The new text layout cannot be generated. "
+ "Most likely the font size is too big."));
+ }
+ }
+ else
+ pango_layout_set_markup (layout->layout, markup, -1);
+
g_free (markup);
}
diff --git a/app/text/gimptextlayout.h b/app/text/gimptextlayout.h
index fdb8a3d..510b039 100644
--- a/app/text/gimptextlayout.h
+++ b/app/text/gimptextlayout.h
@@ -39,7 +39,8 @@ GType gimp_text_layout_get_type (void) G_GNUC_CONST;
GimpTextLayout * gimp_text_layout_new (GimpText *text,
gdouble xres,
- gdouble yres);
+ gdouble yres,
+ GError **error);
gboolean gimp_text_layout_get_size (GimpTextLayout *layout,
gint *width,
gint *heigth);
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 508b08c..ed6fa26 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -1764,11 +1764,17 @@ gimp_text_tool_ensure_layout (GimpTextTool *text_tool)
GimpImage *image = gimp_item_get_image (GIMP_ITEM (text_tool->layer));
gdouble xres;
gdouble yres;
+ GError *error = NULL;
gimp_image_get_resolution (image, &xres, &yres);
text_tool->layout = gimp_text_layout_new (text_tool->layer->text,
- xres, yres);
+ xres, yres, &error);
+ if (error)
+ {
+ gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
+ g_error_free (error);
+ }
}
return text_tool->layout != NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]