]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextutil.c
GtkLabelAccessible: Sanity check _get_text() input values
[~andy/gtk] / gtk / gtktextutil.c
index 700900f66046030f961134a02f368a30d519c208..a2811f2d3cb8ed0e5ade1a51fa41e103d33eb381 100644 (file)
@@ -1,4 +1,4 @@
-/* GTK - The GTK+ Toolkit
+/* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This library is free software; you can redistribute it and/or
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
@@ -35,7 +33,6 @@
 #include "gtktextbuffer.h"
 #include "gtkmenuitem.h"
 #include "gtkintl.h"
-#include "gtkalias.h"
 
 #define DRAG_ICON_MAX_WIDTH 250
 #define DRAG_ICON_MAX_HEIGHT 250
@@ -105,7 +102,7 @@ activate_cb (GtkWidget *menu_item,
   (* info->func) (buf, info->data);
 }
 
-/**
+/*
  * _gtk_text_util_append_special_char_menuitems
  * @menushell: a #GtkMenuShell
  * @callback:  call this when an item is chosen
@@ -119,7 +116,7 @@ activate_cb (GtkWidget *menu_item,
  * become public sometime, but it probably needs more thought first.
  * e.g. maybe there should be a way to just get the list of items,
  * instead of requiring the menu items to be created.
- **/
+ */
 void
 _gtk_text_util_append_special_char_menuitems (GtkMenuShell              *menushell,
                                               GtkTextUtilCharChosenFunc  func,
@@ -194,24 +191,30 @@ limit_layout_lines (PangoLayout *layout)
     }
 }
 
-/**
+/*
  * _gtk_text_util_create_drag_icon
  * @widget: #GtkWidget to extract the pango context
  * @text: a #gchar to render the icon
  * @len: length of @text, or -1 for NUL-terminated text
  *
  * Creates a drag and drop icon from @text.
- **/
-GdkPixmap *
+ *
+ * Returns: a #cairo_surface_t to use as DND icon
+ */
+cairo_surface_t *
 _gtk_text_util_create_drag_icon (GtkWidget *widget, 
                                  gchar     *text,
                                  gsize      len)
 {
-  GdkDrawable  *drawable = NULL;
+  GtkStyleContext *style_context;
+  GtkStateFlags state;
+  cairo_surface_t *surface;
   PangoContext *context;
   PangoLayout  *layout;
+  cairo_t      *cr;
   gint          pixmap_height, pixmap_width;
   gint          layout_width, layout_height;
+  GdkRGBA       color;
 
   g_return_val_if_fail (widget != NULL, NULL);
   g_return_val_if_fail (text != NULL, NULL);
@@ -234,70 +237,98 @@ _gtk_text_util_create_drag_icon (GtkWidget *widget,
   pixmap_width  = layout_width  / PANGO_SCALE + DRAG_ICON_LAYOUT_BORDER * 2;
   pixmap_height = layout_height / PANGO_SCALE + DRAG_ICON_LAYOUT_BORDER * 2;
 
-  drawable = gdk_pixmap_new (widget->window,
-                             pixmap_width  + 2,
-                             pixmap_height + 2,
-                             -1);
-
-  gdk_draw_rectangle (drawable,
-                      widget->style->base_gc [GTK_WIDGET_STATE (widget)],
-                      TRUE,
-                      0, 0,
-                      pixmap_width + 1,
-                      pixmap_height + 1);
-
-  gdk_draw_layout (drawable,
-                   widget->style->text_gc [GTK_WIDGET_STATE (widget)],
-                   1 + DRAG_ICON_LAYOUT_BORDER,
-                   1 + DRAG_ICON_LAYOUT_BORDER,
-                   layout);
-
-  gdk_draw_rectangle (drawable,
-                      widget->style->black_gc,
-                      FALSE,
-                      0, 0,
-                      pixmap_width + 1,
-                      pixmap_height + 1);
+  style_context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
+
+  surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+                                               CAIRO_CONTENT_COLOR,
+                                               pixmap_width  + 2,
+                                               pixmap_height + 2);
+  cr = cairo_create (surface);
+
+  gtk_style_context_save (style_context);
+  gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_VIEW);
 
+  gtk_style_context_get_background_color (style_context, state, &color);
+  gdk_cairo_set_source_rgba (cr, &color);
+  cairo_paint (cr);
+
+  gtk_style_context_get_color (style_context, state, &color);
+  gdk_cairo_set_source_rgba (cr, &color);
+  cairo_move_to (cr, 1 + DRAG_ICON_LAYOUT_BORDER, 1 + DRAG_ICON_LAYOUT_BORDER);
+  pango_cairo_show_layout (cr, layout);
+
+  cairo_set_source_rgb (cr, 0, 0, 0);
+  cairo_rectangle (cr, 0.5, 0.5, pixmap_width + 1, pixmap_height + 1);
+  cairo_set_line_width (cr, 1.0);
+  cairo_stroke (cr);
+
+  cairo_destroy (cr);
   g_object_unref (layout);
 
-  return drawable;
+  cairo_surface_set_device_offset (surface, 2, 2);
+
+  gtk_style_context_restore (style_context);
+
+  return surface;
 }
 
 static void
 gtk_text_view_set_attributes_from_style (GtkTextView        *text_view,
-                                         GtkTextAttributes  *values,
-                                         GtkStyle           *style)
+                                         GtkTextAttributes  *values)
 {
-  values->appearance.bg_color = style->base[GTK_STATE_NORMAL];
-  values->appearance.fg_color = style->text[GTK_STATE_NORMAL];
+  GtkStyleContext *context;
+  GdkRGBA bg_color, fg_color;
+  GtkStateFlags state;
+
+  context = gtk_widget_get_style_context (GTK_WIDGET (text_view));
+  state = gtk_widget_get_state_flags (GTK_WIDGET (text_view));
+
+  gtk_style_context_get_background_color (context, state, &bg_color);
+  gtk_style_context_get_color (context, state, &fg_color);
+
+  values->appearance.bg_color.red = CLAMP (bg_color.red * 65535. + 0.5, 0, 65535);
+  values->appearance.bg_color.green = CLAMP (bg_color.green * 65535. + 0.5, 0, 65535);
+  values->appearance.bg_color.blue = CLAMP (bg_color.blue * 65535. + 0.5, 0, 65535);
+
+  values->appearance.fg_color.red = CLAMP (fg_color.red * 65535. + 0.5, 0, 65535);
+  values->appearance.fg_color.green = CLAMP (fg_color.green * 65535. + 0.5, 0, 65535);
+  values->appearance.fg_color.blue = CLAMP (fg_color.blue * 65535. + 0.5, 0, 65535);
 
   if (values->font)
     pango_font_description_free (values->font);
 
-  values->font = pango_font_description_copy (style->font_desc);
+  gtk_style_context_get (context, state, "font", &values->font, NULL);
 }
 
-GdkPixmap *
+cairo_surface_t *
 _gtk_text_util_create_rich_drag_icon (GtkWidget     *widget,
                                       GtkTextBuffer *buffer,
                                       GtkTextIter   *start,
                                       GtkTextIter   *end)
 {
-  GdkDrawable       *drawable = NULL;
+  GtkAllocation      allocation;
+  cairo_surface_t   *surface;
   gint               pixmap_height, pixmap_width;
   gint               layout_width, layout_height;
+  GtkStyleContext   *context;
+  GtkStateFlags      state;
+  GdkRGBA            color;
   GtkTextBuffer     *new_buffer;
   GtkTextLayout     *layout;
   GtkTextAttributes *style;
   PangoContext      *ltr_context, *rtl_context;
   GtkTextIter        iter;
+  cairo_t           *cr;
 
    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
    g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
    g_return_val_if_fail (start != NULL, NULL);
    g_return_val_if_fail (end != NULL, NULL);
 
+   context = gtk_widget_get_style_context (widget);
+   state = gtk_widget_get_state_flags (widget);
+
    new_buffer = gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
    gtk_text_buffer_get_start_iter (new_buffer, &iter);
 
@@ -319,13 +350,12 @@ _gtk_text_util_create_rich_drag_icon (GtkWidget     *widget,
 
    style = gtk_text_attributes_new ();
 
-   layout_width = widget->allocation.width;
+   gtk_widget_get_allocation (widget, &allocation);
+   layout_width = allocation.width;
 
    if (GTK_IS_TEXT_VIEW (widget))
      {
-       gtk_widget_ensure_style (widget);
-       gtk_text_view_set_attributes_from_style (GTK_TEXT_VIEW (widget),
-                                                style, widget->style);
+       gtk_text_view_set_attributes_from_style (GTK_TEXT_VIEW (widget), style);
 
        layout_width = layout_width
          - gtk_text_view_get_border_window_size (GTK_TEXT_VIEW (widget), GTK_TEXT_WINDOW_LEFT)
@@ -351,34 +381,41 @@ _gtk_text_util_create_rich_drag_icon (GtkWidget     *widget,
    pixmap_width  = layout_width + DRAG_ICON_LAYOUT_BORDER * 2;
    pixmap_height = layout_height + DRAG_ICON_LAYOUT_BORDER * 2;
 
-   drawable = gdk_pixmap_new (widget->window,
-                              pixmap_width  + 2, pixmap_height + 2, -1);
-
-   gdk_draw_rectangle (drawable,
-                       widget->style->base_gc [GTK_WIDGET_STATE (widget)],
-                       TRUE,
-                       0, 0,
-                       pixmap_width + 1,
-                       pixmap_height + 1);
-
-   gtk_text_layout_draw (layout, widget, drawable,
-                         widget->style->text_gc [GTK_WIDGET_STATE (widget)],
-                         - (1 + DRAG_ICON_LAYOUT_BORDER),
-                         - (1 + DRAG_ICON_LAYOUT_BORDER),
-                         0, 0,
-                         pixmap_width, pixmap_height, NULL);
-
-   gdk_draw_rectangle (drawable,
-                       widget->style->black_gc,
-                       FALSE,
-                       0, 0,
-                       pixmap_width + 1,
-                       pixmap_height + 1);
+   surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+                                                CAIRO_CONTENT_COLOR,
+                                                pixmap_width  + 2,
+                                                pixmap_height + 2);
+
+   cr = cairo_create (surface);
+
+   gtk_style_context_save (context);
+   gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+
+   gtk_style_context_get_background_color (context, state, &color);
+   gdk_cairo_set_source_rgba (cr, &color);
+   cairo_paint (cr);
+
+   cairo_save (cr);
 
+   cairo_translate (cr, 1 + DRAG_ICON_LAYOUT_BORDER, 1 + DRAG_ICON_LAYOUT_BORDER);
+   gtk_text_layout_draw (layout, widget, cr, NULL);
+
+   cairo_restore (cr);
+
+   cairo_set_source_rgb (cr, 0, 0, 0);
+   cairo_rectangle (cr, 0.5, 0.5, pixmap_width + 1, pixmap_height + 1);
+   cairo_set_line_width (cr, 1.0);
+   cairo_stroke (cr);
+
+   cairo_destroy (cr);
    g_object_unref (layout);
    g_object_unref (new_buffer);
 
-   return drawable;
+   cairo_surface_set_device_offset (surface, 2, 2);
+
+   gtk_style_context_restore (context);
+
+   return surface;
 }
 
 
@@ -401,17 +438,17 @@ layout_get_char_width (PangoLayout *layout)
   return width;
 }
 
-/**
+/*
  * _gtk_text_util_get_block_cursor_location
  * @layout: a #PangoLayout
  * @index: index at which cursor is located
  * @pos: cursor location
- * @at_line_end: whether cursor i sdrawn at line end, not over some
+ * @at_line_end: whether cursor idrawn at line end, not over some
  * character
  *
  * Returns: whether cursor should actually be drawn as a rectangle.
- * It may not be the case if character at index is invisible.
- **/
+ *     It may not be the case if character at index is invisible.
+ */
 gboolean
 _gtk_text_util_get_block_cursor_location (PangoLayout    *layout,
                                          gint            index,