[gimp/gimp-2-8] 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/gimp-2-8] Bug 662787 - Segfaults when trying to set a large text size
- Date: Thu, 24 Oct 2013 07:42:46 +0000 (UTC)
commit c79e7f5e8755e66696b98628eb9b555e24c7a4eb
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.
(cherry picked from commit 2aabbbd9c733a9078d08b15bedef6e9adae1031f)
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 d47a703..fb84aaf 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 8984c76..58ccab5 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -567,6 +567,7 @@ gimp_text_layer_render (GimpTextLayer *layer)
gdouble yres;
gint width;
gint height;
+ GError *error = NULL;
if (! layer->text)
return FALSE;
@@ -585,7 +586,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));
@@ -645,7 +651,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);
@@ -671,6 +678,7 @@ gimp_text_layer_render_layout (GimpTextLayer *layer,
gint width;
gint height;
gpointer pr;
+ cairo_status_t status;
g_return_if_fail (gimp_drawable_has_alpha (drawable));
@@ -678,6 +686,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 06161e5..5266bc8 100644
--- a/app/text/gimptextlayout.c
+++ b/app/text/gimptextlayout.c
@@ -31,9 +31,12 @@
#include "text-types.h"
+#include "core/gimperror.h"
+
#include "gimptext.h"
#include "gimptextlayout.h"
+#include "gimp-intl.h"
struct _GimpTextLayout
{
@@ -50,7 +53,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,
@@ -100,7 +104,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;
@@ -135,7 +140,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)
{
@@ -509,7 +514,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;
@@ -549,7 +555,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 9160396..a6ca9ec 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -1765,11 +1765,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]