diff --git a/ChangeLog b/ChangeLog index 2c6b9a4df6..7c4c217f60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-01-05 Behdad Esfahbod + + * gdk/gdkprivate.h: + * gdk/gdkpango.c (gdk_draw_layout_line_with_colors), + (gdk_draw_layout_with_colors): + * gdk/gdkwindow.c (gdk_window_draw_glyphs_transformed): + Avoid overflow when converting coordinates to Pango units. (#332266, + Jody Goldberg) + 2007-01-04 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_popup): move set_cursor diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index d04aa9963e..54c0c961c8 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -844,8 +844,22 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable, PangoMatrix tmp_matrix; tmp_matrix = *matrix; - tmp_matrix.x0 = x; - tmp_matrix.y0 = y; + tmp_matrix.x0 += x; + tmp_matrix.y0 += y; + pango_renderer_set_matrix (renderer, &tmp_matrix); + + x = 0; + y = 0; + } + /* Fall back to introduce a matrix if the coords would scale out of range. + * The x and y here will be added to in-layout coordinates. So we cannot + * support the entire range here safely. So, we just accept the middle half + * and use fallback for the rest. */ + else if (GDK_PANGO_UNITS_OVERFLOWS (x, y)) + { + PangoMatrix tmp_matrix = PANGO_MATRIX_INIT; + tmp_matrix.x0 += x; + tmp_matrix.y0 += y; pango_renderer_set_matrix (renderer, &tmp_matrix); x = 0; @@ -965,6 +979,16 @@ gdk_draw_layout_with_colors (GdkDrawable *drawable, tmp_matrix.y0 += y - rect.y; pango_renderer_set_matrix (renderer, &tmp_matrix); + x = 0; + y = 0; + } + else if (GDK_PANGO_UNITS_OVERFLOWS (x, y)) + { + PangoMatrix tmp_matrix = PANGO_MATRIX_INIT; + tmp_matrix.x0 = x; + tmp_matrix.y0 = y; + pango_renderer_set_matrix (renderer, &tmp_matrix); + x = 0; y = 0; } diff --git a/gdk/gdkprivate.h b/gdk/gdkprivate.h index 4dcbfe6d60..95af2e151f 100644 --- a/gdk/gdkprivate.h +++ b/gdk/gdkprivate.h @@ -50,6 +50,16 @@ void gdk_synthesize_window_state (GdkWindow *window, GdkWindowState unset_flags, GdkWindowState set_flags); +/* Tests whether a pair of x,y may cause overflows when converted to Pango + * units (multiplied by PANGO_SCALE). We don't allow the entire range, leave + * some space for additions afterwards, to be safe... + */ +#define GDK_PANGO_UNITS_OVERFLOWS(x,y) (G_UNLIKELY ( \ + (y) >= PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2 || \ + (x) >= PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2 || \ + (y) <=-PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2 || \ + (x) <=-PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2)) + G_END_DECLS #endif /* __GDK_PRIVATE_H__ */ diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 66428f5478..3739b8ea98 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -1737,6 +1737,15 @@ gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, tmp_matrix.y0 -= y_offset; matrix = &tmp_matrix; } + else if (GDK_PANGO_UNITS_OVERFLOWS (x_offset, y_offset)) + { + PangoMatrix identity = PANGO_MATRIX_INIT; + + tmp_matrix = identity; + tmp_matrix.x0 -= x_offset; + tmp_matrix.y0 -= y_offset; + matrix = &tmp_matrix; + } else { x -= x_offset * PANGO_SCALE;