diff options
author | Havoc Pennington <hp@redhat.com> | 2001-01-22 23:09:48 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-01-22 23:09:48 +0000 |
commit | e0fee22e7885f465370c184c7e02d542ec16b177 (patch) | |
tree | aeb869be43858272ae128529c043bf33abfee41b /gtk | |
parent | a081fe7d541c670d9017f60f3b9dd1b93affe9f5 (diff) | |
download | gtk+-e0fee22e7885f465370c184c7e02d542ec16b177.tar.gz |
Add built marshaller files to support GdkPixbufLoader signals
2001-01-22 Havoc Pennington <hp@redhat.com>
* Makefile.am: Add built marshaller files to support
GdkPixbufLoader signals
* gdk-pixbuf-io.c (gdk_pixbuf_load_module): have
GDK_PIXBUF_MODULEDIR unconditionally replace the compiled-in
module location, rather than acting as a fallback, because we are
using GDK_PIXBUF_MODULEDIR to use gdk-pixbuf before installing it.
* gdk-pixbuf.h: include gdk-pixbuf-loader.h
* gdk-pixbuf-loader.h, gdk-pixbuf-loader.c: Move back over here
from gtk, and add error to close(), because stop_load may do
parsing of the image.
* pixops/have_mmx.S (_pixops_have_mmx): add newline at end of file
* io-*.c: make individual operations static, and add fill_vtable
functions which are exported. Fix the collection of type warnings
that surfaced, including a number of functions that didn't
properly take a GError and some that weren't
const-correct. Involved adding error handling for a few loaders.
* gdk-pixbuf-io.h: Add error reporting to stop_load function
* gdk-pixbuf-io.c (gdk_pixbuf_load_module): change to just look up
a function that fills in the GdkPixbufModule vtable, instead of
looking up all the image functions individually; this means we
can get type safety within modules for the loader functions.
Also it means you don't have to keep the statically compiled and
GModule versions in sync.
* test-gdk-pixbuf.c (main): remove gdk_pixbuf_init()
* make-inline-pixbuf.c (main): remove call to gdk_pixbuf_init()
* gdk-pixbuf.h: nuke gdk_pixbuf_init()
* gdk-pixbuf-animation.c (gdk_pixbuf_frame_get_type): g_type_init
() here
* gdk-pixbuf.c (gdk_pixbuf_get_type): g_type_init () here
* gdk-pixbuf-animation.c (gdk_pixbuf_animation_get_type):
g_type_init() here
2001-01-22 Havoc Pennington <hp@redhat.com>
* demos/testanimation.c: fix to reflect gdk-pixbuf changes
* demos/testpixbuf.c: fix to reflect gdk-pixbuf changes
* gtk/gdk-pixbuf-loader.c, gtk/gdk-pixbuf-loader.h:
Remove, move back to gdk-pixbuf
* gtk/gtktextiter.c, gtk/gtktextiter.h: add sentence equivalents
to all the word functions
* gtk/gtktextview.c (gtk_text_view_start_cursor_blink): return
before doing anything on NULL layout or if we don't have the focus
* gtk/testtext.c (fill_example_buffer): "justification"
* gtk/gtktexttag.h, gtk/gtktexttag.c: change the tag attribute
to be called "justification" not "justify"
* demos/gtk-demo/textview.c (create_tags): "justification"
* gtk/gtktextlayout.c (set_para_values): Handle char-wise wrapping
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/gdk-pixbuf-loader.c | 625 | ||||
-rw-r--r-- | gtk/gdk-pixbuf-loader.h | 87 | ||||
-rw-r--r-- | gtk/gtktextiter.c | 159 | ||||
-rw-r--r-- | gtk/gtktextiter.h | 10 | ||||
-rw-r--r-- | gtk/gtktextlayout.c | 10 | ||||
-rw-r--r-- | gtk/gtktexttag.c | 36 | ||||
-rw-r--r-- | gtk/gtktexttag.h | 4 | ||||
-rw-r--r-- | gtk/gtktextview.c | 10 | ||||
-rw-r--r-- | gtk/testtext.c | 38 |
10 files changed, 225 insertions, 756 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index b8d296f997..bdd2659b57 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -131,7 +131,6 @@ gtk_public_h_sources = @STRIP_BEGIN@ \ gtkoptionmenu.h \ gtkpacker.h \ gtkpaned.h \ - gdk-pixbuf-loader.h \ gtkpixmap.h \ gtkplug.h \ gtkpreview.h \ @@ -357,7 +356,6 @@ gtk_c_sources = @STRIP_BEGIN@ \ gtkwindow-decorate.c \ fnmatch.c \ fnmatch.h \ - gdk-pixbuf-loader.c \ @STRIP_END@ # Extra headers that are used for enum type array/id generation gdk_headers = @STRIP_BEGIN@ \ diff --git a/gtk/gdk-pixbuf-loader.c b/gtk/gdk-pixbuf-loader.c deleted file mode 100644 index 60277caddd..0000000000 --- a/gtk/gdk-pixbuf-loader.c +++ /dev/null @@ -1,625 +0,0 @@ -/* GdkPixbuf library - Progressive loader object - * - * Copyright (C) 1999 The Free Software Foundation - * - * Authors: Mark Crichton <crichton@gimp.org> - * Miguel de Icaza <miguel@gnu.org> - * Federico Mena-Quintero <federico@gimp.org> - * Jonathan Blandford <jrb@redhat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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. - */ - -#include <string.h> - -#include "gdk-pixbuf-private.h" -#include "gdk-pixbuf-loader.h" -#include "gdk-pixbuf-io.h" - -#include "gtksignal.h" - -enum { - AREA_UPDATED, - AREA_PREPARED, - FRAME_DONE, - ANIMATION_DONE, - CLOSED, - LAST_SIGNAL -}; - - -static void gdk_pixbuf_loader_class_init (GdkPixbufLoaderClass *klass); -static void gdk_pixbuf_loader_init (GdkPixbufLoader *loader); -static void gdk_pixbuf_loader_finalize (GObject *loader); - -static gpointer parent_class = NULL; -static guint pixbuf_loader_signals[LAST_SIGNAL] = { 0 }; - - -/* Internal data */ - -#define LOADER_HEADER_SIZE 128 - -typedef struct -{ - GdkPixbuf *pixbuf; - GdkPixbufAnimation *animation; - gboolean closed; - guchar header_buf[LOADER_HEADER_SIZE]; - gint header_buf_offset; - GdkPixbufModule *image_module; - gpointer context; -} GdkPixbufLoaderPrivate; - - -/** - * gdk_pixbuf_loader_get_type: - * @void: - * - * Registers the #GdkPixubfLoader class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #GdkPixbufLoader class. - **/ -GType -gdk_pixbuf_loader_get_type (void) -{ - static GType loader_type = 0; - - if (!loader_type) - { - static const GTypeInfo loader_info = { - sizeof (GdkPixbufLoaderClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) gdk_pixbuf_loader_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GdkPixbufLoader), - 0, /* n_preallocs */ - (GInstanceInitFunc) gdk_pixbuf_loader_init - }; - - loader_type = g_type_register_static (G_TYPE_OBJECT, - "GdkPixbufLoader", - &loader_info, - 0); - } - - return loader_type; -} - -static void -gdk_pixbuf_loader_class_init (GdkPixbufLoaderClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - parent_class = g_type_class_peek_parent (class); - - object_class->finalize = gdk_pixbuf_loader_finalize; - - pixbuf_loader_signals[AREA_PREPARED] = - g_signal_newc ("area_prepared", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdkPixbufLoaderClass, area_prepared), - NULL, - gtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - pixbuf_loader_signals[AREA_UPDATED] = - g_signal_newc ("area_updated", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdkPixbufLoaderClass, area_updated), - NULL, - gtk_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - pixbuf_loader_signals[FRAME_DONE] = - g_signal_newc ("frame_done", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdkPixbufLoaderClass, frame_done), - NULL, - gtk_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - GDK_TYPE_PIXBUF_FRAME); - - pixbuf_loader_signals[ANIMATION_DONE] = - g_signal_newc ("animation_done", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdkPixbufLoaderClass, animation_done), - NULL, - gtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - pixbuf_loader_signals[CLOSED] = - g_signal_newc ("closed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GdkPixbufLoaderClass, closed), - NULL, - gtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -gdk_pixbuf_loader_init (GdkPixbufLoader *loader) -{ - GdkPixbufLoaderPrivate *priv; - - priv = g_new0 (GdkPixbufLoaderPrivate, 1); - loader->private = priv; -} - -static void -gdk_pixbuf_loader_finalize (GObject *object) -{ - GdkPixbufLoader *loader; - GdkPixbufLoaderPrivate *priv = NULL; - - loader = GDK_PIXBUF_LOADER (object); - priv = loader->private; - - if (!priv->closed) - g_warning ("GdkPixbufLoader finalized without calling gdk_pixbuf_loader_close() - this is not allowed. You must explicitly end the data stream to the loader before dropping the last reference."); - - if (priv->animation) - gdk_pixbuf_animation_unref (priv->animation); - - if (priv->pixbuf) - gdk_pixbuf_unref (priv->pixbuf); - - g_free (priv); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gdk_pixbuf_loader_prepare (GdkPixbuf *pixbuf, - gpointer loader) -{ - GdkPixbufLoaderPrivate *priv = NULL; - - priv = GDK_PIXBUF_LOADER (loader)->private; - gdk_pixbuf_ref (pixbuf); - - g_assert (priv->pixbuf == NULL); - - priv->pixbuf = pixbuf; - g_signal_emit (G_OBJECT (loader), pixbuf_loader_signals[AREA_PREPARED], 0); -} - -static void -gdk_pixbuf_loader_update (GdkPixbuf *pixbuf, - guint x, - guint y, - guint width, - guint height, - gpointer loader) -{ - GdkPixbufLoaderPrivate *priv = NULL; - - priv = GDK_PIXBUF_LOADER (loader)->private; - - g_signal_emit (G_OBJECT (loader), - pixbuf_loader_signals[AREA_UPDATED], - 0, - x, y, - /* sanity check in here. Defend against an errant loader */ - MIN (width, gdk_pixbuf_get_width (priv->pixbuf)), - MIN (height, gdk_pixbuf_get_height (priv->pixbuf))); -} - -static void -gdk_pixbuf_loader_frame_done (GdkPixbufFrame *frame, - gpointer loader) -{ - GdkPixbufLoaderPrivate *priv = NULL; - - priv = GDK_PIXBUF_LOADER (loader)->private; - - priv->pixbuf = NULL; - - if (priv->animation == NULL) - { - priv->animation = g_object_new (GDK_TYPE_PIXBUF_ANIMATION, NULL); - - priv->animation->n_frames = 0; - priv->animation->width = gdk_pixbuf_get_width (frame->pixbuf) + frame->x_offset; - priv->animation->height = gdk_pixbuf_get_height (frame->pixbuf) + frame->y_offset; - } - else - { - int w, h; - - /* update bbox size */ - w = gdk_pixbuf_get_width (frame->pixbuf) + frame->x_offset; - h = gdk_pixbuf_get_height (frame->pixbuf) + frame->y_offset; - - if (w > priv->animation->width) { - priv->animation->width = w; - } - if (h > priv->animation->height) { - priv->animation->height = h; - } - } - - priv->animation->frames = g_list_append (priv->animation->frames, frame); - priv->animation->n_frames++; - g_signal_emit (G_OBJECT (loader), - pixbuf_loader_signals[FRAME_DONE], - 0, - frame); -} - -static void -gdk_pixbuf_loader_animation_done (GdkPixbuf *pixbuf, - gpointer loader) -{ - GdkPixbufLoaderPrivate *priv = NULL; - GdkPixbufFrame *frame; - GList *current = NULL; - gint h, w; - - priv = GDK_PIXBUF_LOADER (loader)->private; - priv->pixbuf = NULL; - - current = gdk_pixbuf_animation_get_frames (priv->animation); - - while (current) - { - frame = (GdkPixbufFrame *) current->data; - - /* update bbox size */ - w = gdk_pixbuf_get_width (frame->pixbuf) + frame->x_offset; - h = gdk_pixbuf_get_height (frame->pixbuf) + frame->y_offset; - - if (w > priv->animation->width) - priv->animation->width = w; - if (h > priv->animation->height) - priv->animation->height = h; - current = current->next; - } - - g_signal_emit (G_OBJECT (loader), pixbuf_loader_signals[ANIMATION_DONE], 0); -} - -static gint -gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, - const char *image_type, - GError **error) -{ - GdkPixbufLoaderPrivate *priv = loader->private; - - if (image_type) - { - priv->image_module = gdk_pixbuf_get_named_module (image_type, - error); - } - else - { - g_return_val_if_fail (priv->header_buf_offset > 0, 0); - priv->image_module = gdk_pixbuf_get_module (priv->header_buf, - priv->header_buf_offset, - NULL, - error); - } - - if (priv->image_module == NULL) - return 0; - - if (priv->image_module->module == NULL) - if (!gdk_pixbuf_load_module (priv->image_module, error)) - return 0; - - if (priv->image_module->module == NULL) - return 0; - - if ((priv->image_module->begin_load == NULL) || - (priv->image_module->stop_load == NULL) || - (priv->image_module->load_increment == NULL)) - { - g_set_error (error, - GDK_PIXBUF_ERROR, - GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, - _("Incremental loading of image type '%s' is not supported"), - image_type); - - return 0; - } - - priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_prepare, - gdk_pixbuf_loader_update, - gdk_pixbuf_loader_frame_done, - gdk_pixbuf_loader_animation_done, - loader, - error); - - if (priv->context == NULL) - { - /* Defense against broken loaders; DO NOT take this as a GError - * example - */ - if (error && *error == NULL) - { - g_warning ("Bug! loader '%s' didn't set an error on failure", - priv->image_module->module_name); - g_set_error (error, - GDK_PIXBUF_ERROR, - GDK_PIXBUF_ERROR_FAILED, - _("Internal error: Image loader module '%s'" - " failed to begin loading an image, but didn't" - " give a reason for the failure"), - priv->image_module->module_name); - - } - - return 0; - } - - if (priv->header_buf_offset - && priv->image_module->load_increment (priv->context, priv->header_buf, priv->header_buf_offset, error)) - return priv->header_buf_offset; - - return 0; -} - -static int -gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, - const guchar *buf, - gsize count, - GError **error) -{ - gint n_bytes; - GdkPixbufLoaderPrivate *priv = loader->private; - - n_bytes = MIN(LOADER_HEADER_SIZE - priv->header_buf_offset, count); - memcpy (priv->header_buf + priv->header_buf_offset, buf, n_bytes); - - priv->header_buf_offset += n_bytes; - - if (priv->header_buf_offset >= LOADER_HEADER_SIZE) - { - if (gdk_pixbuf_loader_load_module (loader, NULL, error) == 0) - return 0; - } - - return n_bytes; -} - -/** - * gdk_pixbuf_loader_write: - * @loader: A pixbuf loader. - * @buf: Pointer to image data. - * @count: Length of the @buf buffer in bytes. - * @error: return location for errors - * - * This will cause a pixbuf loader to parse the next @count bytes of - * an image. It will return TRUE if the data was loaded successfully, - * and FALSE if an error occurred. In the latter case, the loader - * will be closed, and will not accept further writes. If FALSE is - * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR - * domain. - * - * Return value: #TRUE if the write was successful, or #FALSE if the loader - * cannot parse the buffer. - **/ -gboolean -gdk_pixbuf_loader_write (GdkPixbufLoader *loader, - const guchar *buf, - gsize count, - GError **error) -{ - GdkPixbufLoaderPrivate *priv; - - g_return_val_if_fail (loader != NULL, FALSE); - g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE); - - g_return_val_if_fail (buf != NULL, FALSE); - g_return_val_if_fail (count >= 0, FALSE); - - priv = loader->private; - - /* we expect it's not to be closed */ - g_return_val_if_fail (priv->closed == FALSE, FALSE); - - if (priv->image_module == NULL) - { - gint eaten; - - eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count, error); - if (eaten <= 0) - return FALSE; - - count -= eaten; - buf += eaten; - } - - if (count > 0 && priv->image_module->load_increment) - { - gboolean retval; - retval = priv->image_module->load_increment (priv->context, buf, count, - error); - if (!retval && error && *error == NULL) - { - /* Fix up busted image loader */ - g_warning ("Bug! loader '%s' didn't set an error on failure", - priv->image_module->module_name); - g_set_error (error, - GDK_PIXBUF_ERROR, - GDK_PIXBUF_ERROR_FAILED, - _("Internal error: Image loader module '%s'" - " failed to begin loading an image, but didn't" - " give a reason for the failure"), - priv->image_module->module_name); - } - - return retval; - } - - return TRUE; -} - -/** - * gdk_pixbuf_loader_new: - * - * Creates a new pixbuf loader object. - * - * Return value: A newly-created pixbuf loader. - **/ -GdkPixbufLoader * -gdk_pixbuf_loader_new (void) -{ - return g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); -} - -/** - * gdk_pixbuf_loader_new_with_type: - * - * Creates a new pixbuf loader object. - * - * Return value: A newly-created pixbuf loader. - **/ -GdkPixbufLoader * -gdk_pixbuf_loader_new_with_type (const char *image_type, - GError **error) -{ - GdkPixbufLoader *retval; - GError *tmp; - - retval = g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); - - tmp = NULL; - gdk_pixbuf_loader_load_module(retval, image_type, &tmp); - if (tmp != NULL) - { - g_propagate_error (error, tmp); - g_object_unref (G_OBJECT (retval)); - return NULL; - } - - return retval; -} - -/** - * gdk_pixbuf_loader_get_pixbuf: - * @loader: A pixbuf loader. - * - * Queries the GdkPixbuf that a pixbuf loader is currently creating. - * In general it only makes sense to call this function afer the - * "area_prepared" signal has been emitted by the loader; this means - * that enough data has been read to know the size of the image that - * will be allocated. If the loader has not received enough data via - * gdk_pixbuf_loader_write(), then this function returns NULL. The - * returned pixbuf will be the same in all future calls to the loader, - * so simply calling gdk_pixbuf_ref() should be sufficient to continue - * using it. Additionally, if the loader is an animation, it will - * return the first frame of the animation. - * - * Return value: The GdkPixbuf that the loader is creating, or NULL if not - * enough data has been read to determine how to create the image buffer. - **/ -GdkPixbuf * -gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader) -{ - GdkPixbufLoaderPrivate *priv; - - g_return_val_if_fail (loader != NULL, NULL); - g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL); - - priv = loader->private; - - if (priv->animation) - { - GList *list; - - list = gdk_pixbuf_animation_get_frames (priv->animation); - if (list != NULL) - { - GdkPixbufFrame *frame = list->data; - - return gdk_pixbuf_frame_get_pixbuf (frame); - } - } - - return priv->pixbuf; -} - -/** - * gdk_pixbuf_loader_get_animation: - * @loader: A pixbuf loader - * - * Queries the GdkPixbufAnimation that a pixbuf loader is currently creating. - * In general it only makes sense to call this function afer the "area_prepared" - * signal has been emitted by the loader. If the image is not an animation, - * then it will return NULL. - * - * Return value: The GdkPixbufAnimation that the loader is loading, or NULL if - not enough data has been read to determine the information. -**/ -GdkPixbufAnimation * -gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader) -{ - GdkPixbufLoaderPrivate *priv; - - g_return_val_if_fail (loader != NULL, NULL); - g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL); - - priv = loader->private; - - return priv->animation; -} - -/** - * gdk_pixbuf_loader_close: - * @loader: A pixbuf loader. - * - * Informs a pixbuf loader that no further writes with gdk_pixbuf_loader_write() - * will occur, so that it can free its internal loading structures. - **/ -void -gdk_pixbuf_loader_close (GdkPixbufLoader *loader) -{ - GdkPixbufLoaderPrivate *priv; - - g_return_if_fail (loader != NULL); - g_return_if_fail (GDK_IS_PIXBUF_LOADER (loader)); - - priv = loader->private; - - /* we expect it's not closed */ - g_return_if_fail (priv->closed == FALSE); - - /* We have less the 128 bytes in the image. Flush it, and keep going. */ - if (priv->image_module == NULL) - gdk_pixbuf_loader_load_module (loader, NULL, NULL); - - if (priv->image_module && priv->image_module->stop_load) - priv->image_module->stop_load (priv->context); - - priv->closed = TRUE; - - g_signal_emit (G_OBJECT (loader), pixbuf_loader_signals[CLOSED], 0); -} diff --git a/gtk/gdk-pixbuf-loader.h b/gtk/gdk-pixbuf-loader.h deleted file mode 100644 index 01532ad782..0000000000 --- a/gtk/gdk-pixbuf-loader.h +++ /dev/null @@ -1,87 +0,0 @@ -/* GdkPixbuf library - Progressive loader object - * - * Copyright (C) 1999 The Free Software Foundation - * - * Authors: Mark Crichton <crichton@gimp.org> - * Miguel de Icaza <miguel@gnu.org> - * Federico Mena-Quintero <federico@gimp.org> - * Jonathan Blandford <jrb@redhat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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. - */ - -#ifndef GDK_PIXBUF_LOADER_H -#define GDK_PIXBUF_LOADER_H - -#include <gdk-pixbuf/gdk-pixbuf.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define GDK_TYPE_PIXBUF_LOADER (gdk_pixbuf_loader_get_type ()) -#define GDK_PIXBUF_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PIXBUF_LOADER, GdkPixbufLoader)) -#define GDK_PIXBUF_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_LOADER, GdkPixbufLoaderClass)) -#define GDK_IS_PIXBUF_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PIXBUF_LOADER)) -#define GDK_IS_PIXBUF_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_LOADER)) -#define GDK_PIXBUF_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_LOADER, GdkPixbufLoaderClass)) - - -typedef struct _GdkPixbufLoader GdkPixbufLoader; -struct _GdkPixbufLoader -{ - GObject parent_instance; - - /*< private >*/ - gpointer private; -}; - -typedef struct _GdkPixbufLoaderClass GdkPixbufLoaderClass; -struct _GdkPixbufLoaderClass -{ - GObjectClass parent_class; - - void (*area_prepared) (GdkPixbufLoader *loader); - void (*area_updated) (GdkPixbufLoader *loader, - guint x, - guint y, - guint width, - guint height); - void (*frame_done) (GdkPixbufLoader *loader, - GdkPixbufFrame *frame); - void (*animation_done) (GdkPixbufLoader *loader); - void (*closed) (GdkPixbufLoader *loader); -}; - - -GType gdk_pixbuf_loader_get_type (void) G_GNUC_CONST; -GdkPixbufLoader * gdk_pixbuf_loader_new (void); -GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type, - GError **error); -gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, - const guchar *buf, - gsize count, - GError **error); -GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader); -GdkPixbufAnimation * gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader); -void gdk_pixbuf_loader_close (GdkPixbufLoader *loader); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index 5529e61bb5..549dcb2179 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -2447,6 +2447,8 @@ typedef gboolean (* TestLogAttrFunc) (const PangoLogAttr *attrs, gint min_offset, gint len); +/* Word funcs */ + static gboolean find_word_end_func (const PangoLogAttr *attrs, gint offset, @@ -2521,6 +2523,82 @@ inside_word_func (const PangoLogAttr *attrs, return attrs[offset].is_word_start; } +/* Sentence funcs */ + +static gboolean +find_sentence_end_func (const PangoLogAttr *attrs, + gint offset, + gint min_offset, + gint len, + gint *found_offset, + gboolean already_moved_initially) +{ + if (!already_moved_initially) + ++offset; + + /* Find end of next sentence */ + while (offset < min_offset + len && + !attrs[offset].is_sentence_end) + ++offset; + + *found_offset = offset; + + return offset < min_offset + len; +} + +static gboolean +is_sentence_end_func (const PangoLogAttr *attrs, + gint offset, + gint min_offset, + gint len) +{ + return attrs[offset].is_sentence_end; +} + +static gboolean +find_sentence_start_func (const PangoLogAttr *attrs, + gint offset, + gint min_offset, + gint len, + gint *found_offset, + gboolean already_moved_initially) +{ + if (!already_moved_initially) + --offset; + + /* Find start of prev sentence */ + while (offset >= min_offset && + !attrs[offset].is_sentence_start) + --offset; + + *found_offset = offset; + + return offset >= min_offset; +} + +static gboolean +is_sentence_start_func (const PangoLogAttr *attrs, + gint offset, + gint min_offset, + gint len) +{ + return attrs[offset].is_sentence_start; +} + +static gboolean +inside_sentence_func (const PangoLogAttr *attrs, + gint offset, + gint min_offset, + gint len) +{ + /* Find next sentence start or end */ + while (offset >= min_offset && + !(attrs[offset].is_sentence_start || attrs[offset].is_sentence_end)) + --offset; + + return attrs[offset].is_sentence_start; +} + static gboolean test_log_attrs (const GtkTextIter *iter, TestLogAttrFunc func) @@ -2683,7 +2761,6 @@ gtk_text_iter_backward_word_starts (GtkTextIter *iter, return TRUE; } - gboolean gtk_text_iter_starts_word (const GtkTextIter *iter) { @@ -2702,6 +2779,86 @@ gtk_text_iter_inside_word (const GtkTextIter *iter) return test_log_attrs (iter, inside_word_func); } +gboolean +gtk_text_iter_starts_sentence (const GtkTextIter *iter) +{ + return test_log_attrs (iter, is_sentence_start_func); +} + +gboolean +gtk_text_iter_ends_sentence (const GtkTextIter *iter) +{ + return test_log_attrs (iter, is_sentence_end_func); +} + +gboolean +gtk_text_iter_inside_sentence (const GtkTextIter *iter) +{ + return test_log_attrs (iter, inside_sentence_func); +} + +gboolean +gtk_text_iter_forward_sentence_end (GtkTextIter *iter) +{ + return find_by_log_attrs (iter, find_sentence_end_func, TRUE, FALSE); +} + +gboolean +gtk_text_iter_backward_sentence_start (GtkTextIter *iter) +{ + return find_by_log_attrs (iter, find_sentence_start_func, FALSE, FALSE); +} + +/* FIXME a loop around a truly slow function means + * a truly spectacularly slow function. + */ +gboolean +gtk_text_iter_forward_sentence_ends (GtkTextIter *iter, + gint count) +{ + g_return_val_if_fail (iter != NULL, FALSE); + + if (count == 0) + return FALSE; + + if (count < 0) + return gtk_text_iter_backward_sentence_starts (iter, -count); + + if (!gtk_text_iter_forward_sentence_end (iter)) + return FALSE; + --count; + + while (count > 0) + { + if (!gtk_text_iter_forward_sentence_end (iter)) + break; + --count; + } + return TRUE; +} + +gboolean +gtk_text_iter_backward_sentence_starts (GtkTextIter *iter, + gint count) +{ + g_return_val_if_fail (iter != NULL, FALSE); + + if (count < 0) + return gtk_text_iter_forward_sentence_ends (iter, -count); + + if (!gtk_text_iter_backward_sentence_start (iter)) + return FALSE; + --count; + + while (count > 0) + { + if (!gtk_text_iter_backward_sentence_start (iter)) + break; + --count; + } + return TRUE; +} + static gboolean find_forward_cursor_pos_func (const PangoLogAttr *attrs, gint offset, diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h index ddb86dd79d..2522588a7a 100644 --- a/gtk/gtktextiter.h +++ b/gtk/gtktextiter.h @@ -128,6 +128,9 @@ gboolean gtk_text_iter_editable (const GtkTextIter *iter, gboolean gtk_text_iter_starts_word (const GtkTextIter *iter); gboolean gtk_text_iter_ends_word (const GtkTextIter *iter); gboolean gtk_text_iter_inside_word (const GtkTextIter *iter); +gboolean gtk_text_iter_starts_sentence (const GtkTextIter *iter); +gboolean gtk_text_iter_ends_sentence (const GtkTextIter *iter); +gboolean gtk_text_iter_inside_sentence (const GtkTextIter *iter); gboolean gtk_text_iter_starts_line (const GtkTextIter *iter); gboolean gtk_text_iter_ends_line (const GtkTextIter *iter); gboolean gtk_text_iter_is_cursor_position (const GtkTextIter *iter); @@ -163,6 +166,13 @@ gboolean gtk_text_iter_forward_word_ends (GtkTextIter *iter, gint count); gboolean gtk_text_iter_backward_word_starts (GtkTextIter *iter, gint count); + +gboolean gtk_text_iter_forward_sentence_end (GtkTextIter *iter); +gboolean gtk_text_iter_backward_sentence_start (GtkTextIter *iter); +gboolean gtk_text_iter_forward_sentence_ends (GtkTextIter *iter, + gint count); +gboolean gtk_text_iter_backward_sentence_starts (GtkTextIter *iter, + gint count); /* cursor positions are almost equivalent to chars, but not quite; * in some languages, you can't put the cursor between certain * chars. Also, you can't put the cursor between \r\n at the end diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index bd10489b2d..01c8177a91 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -1069,7 +1069,7 @@ set_para_values (GtkTextLayout *layout, else display->layout = pango_layout_new (layout->rtl_context); - switch (style->justify) + switch (style->justification) { case GTK_JUSTIFY_LEFT: pango_align = (style->direction == GTK_TEXT_DIR_LTR) ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT; @@ -1122,11 +1122,17 @@ set_para_values (GtkTextLayout *layout, switch (style->wrap_mode) { case GTK_WRAPMODE_CHAR: - /* FIXME: Handle this; for now, fall-through */ + layout_width = layout->screen_width - display->left_margin - display->right_margin; + pango_layout_set_width (display->layout, layout_width * PANGO_SCALE); + pango_layout_set_wrap (display->layout, PANGO_WRAP_CHAR); + break; + case GTK_WRAPMODE_WORD: layout_width = layout->screen_width - display->left_margin - display->right_margin; pango_layout_set_width (display->layout, layout_width * PANGO_SCALE); + pango_layout_set_wrap (display->layout, PANGO_WRAP_WORD); break; + case GTK_WRAPMODE_NONE: break; } diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c index f2911c5ea2..1e3d51bfbb 100644 --- a/gtk/gtktexttag.c +++ b/gtk/gtktexttag.c @@ -90,7 +90,7 @@ enum { PROP_PIXELS_INSIDE_WRAP, PROP_EDITABLE, PROP_WRAP_MODE, - PROP_JUSTIFY, + PROP_JUSTIFICATION, PROP_DIRECTION, PROP_LEFT_MARGIN, PROP_INDENT, @@ -121,7 +121,7 @@ enum { PROP_PIXELS_INSIDE_WRAP_SET, PROP_EDITABLE_SET, PROP_WRAP_MODE_SET, - PROP_JUSTIFY_SET, + PROP_JUSTIFICATION_SET, PROP_LEFT_MARGIN_SET, PROP_INDENT_SET, PROP_STRIKETHROUGH_SET, @@ -364,8 +364,8 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (object_class, - PROP_JUSTIFY, - g_param_spec_enum ("justify", + PROP_JUSTIFICATION, + g_param_spec_enum ("justification", _("Justification"), _("Left, right, or center justification"), GTK_TYPE_JUSTIFICATION, @@ -555,7 +555,7 @@ gtk_text_tag_class_init (GtkTextTagClass *klass) _("Font size set"), _("Whether this tag affects the font size")); - ADD_SET_PROP ("justify_set", PROP_JUSTIFY_SET, + ADD_SET_PROP ("justification_set", PROP_JUSTIFICATION_SET, _("Justification set"), _("Whether this tag affects paragraph justification")); @@ -998,10 +998,10 @@ gtk_text_tag_set_property (GObject *object, size_changed = TRUE; break; - case PROP_JUSTIFY: - text_tag->justify_set = TRUE; - text_tag->values->justify = g_value_get_enum (value); - g_object_notify (G_OBJECT (text_tag), "justify_set"); + case PROP_JUSTIFICATION: + text_tag->justification_set = TRUE; + text_tag->values->justification = g_value_get_enum (value); + g_object_notify (G_OBJECT (text_tag), "justification_set"); size_changed = TRUE; break; @@ -1169,8 +1169,8 @@ gtk_text_tag_set_property (GObject *object, size_changed = TRUE; break; - case PROP_JUSTIFY_SET: - text_tag->justify_set = g_value_get_boolean (value); + case PROP_JUSTIFICATION_SET: + text_tag->justification_set = g_value_get_boolean (value); size_changed = TRUE; break; @@ -1363,8 +1363,8 @@ gtk_text_tag_get_property (GObject *object, g_value_set_enum (value, tag->values->wrap_mode); break; - case PROP_JUSTIFY: - g_value_set_enum (value, tag->values->justify); + case PROP_JUSTIFICATION: + g_value_set_enum (value, tag->values->justification); break; case PROP_DIRECTION: @@ -1474,8 +1474,8 @@ gtk_text_tag_get_property (GObject *object, g_value_set_boolean (value, tag->wrap_mode_set); break; - case PROP_JUSTIFY_SET: - g_value_set_boolean (value, tag->justify_set); + case PROP_JUSTIFICATION_SET: + g_value_set_boolean (value, tag->justification_set); break; case PROP_LEFT_MARGIN_SET: @@ -1952,8 +1952,8 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest, if (tag->size_set) dest->font.size = vals->font.size; - if (tag->justify_set) - dest->justify = vals->justify; + if (tag->justification_set) + dest->justification = vals->justification; if (vals->direction != GTK_TEXT_DIR_NONE) dest->direction = vals->direction; @@ -2026,7 +2026,7 @@ _gtk_text_tag_affects_size (GtkTextTag *tag) tag->weight_set || tag->size_set || tag->stretch_set || - tag->justify_set || + tag->justification_set || tag->left_margin_set || tag->indent_set || tag->rise_set || diff --git a/gtk/gtktexttag.h b/gtk/gtktexttag.h index 2b92cda968..f4abd8e174 100644 --- a/gtk/gtktexttag.h +++ b/gtk/gtktexttag.h @@ -68,7 +68,7 @@ struct _GtkTextTag guint stretch_set : 1; guint size_set : 1; guint fg_stipple_set : 1; - guint justify_set : 1; + guint justification_set : 1; guint left_margin_set : 1; guint indent_set : 1; guint rise_set : 1; @@ -148,7 +148,7 @@ struct _GtkTextAttributes GtkTextAppearance appearance; - GtkJustification justify; + GtkJustification justification; GtkTextDirection direction; /* Individual chunks of this can be set/unset as a group */ diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index b895960dc2..659656b7be 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -1728,7 +1728,7 @@ gtk_text_view_set_justification (GtkTextView *text_view, if (text_view->layout) { - text_view->layout->default_style->justify = justify; + text_view->layout->default_style->justification = justify; gtk_text_layout_default_style_changed (text_view->layout); } } @@ -3458,9 +3458,15 @@ gtk_text_view_start_cursor_blink(GtkTextView *text_view, #ifdef DEBUG_VALIDATION_AND_SCROLLING return; #endif + + if (text_view->layout == NULL) + return; if (!text_view->cursor_visible) return; + + if (!GTK_WIDGET_HAS_FOCUS (text_view)) + return; if (text_view->preblink_timeout != 0) { @@ -4140,7 +4146,7 @@ gtk_text_view_ensure_layout (GtkTextView *text_view) style->tabs = text_view->tabs ? pango_tab_array_copy (text_view->tabs) : NULL; style->wrap_mode = text_view->wrap_mode; - style->justify = text_view->justify; + style->justification = text_view->justify; style->direction = gtk_widget_get_direction (GTK_WIDGET (text_view)); gtk_text_layout_set_default_style (text_view->layout, style); diff --git a/gtk/testtext.c b/gtk/testtext.c index 3086f0bdbd..9a66df2cb9 100644 --- a/gtk/testtext.c +++ b/gtk/testtext.c @@ -470,17 +470,17 @@ fill_example_buffer (GtkTextBuffer *buffer) color.blue = color.red = 0; color.green = 0xffff; g_object_set (G_OBJECT (tag), - "background_gdk", &color, - "size_points", 10.0, - NULL); + "background_gdk", &color, + "size_points", 10.0, + NULL); tag = gtk_text_buffer_create_tag (buffer, "strikethrough"); setup_tag (tag); g_object_set (G_OBJECT (tag), - "strikethrough", TRUE, - NULL); + "strikethrough", TRUE, + NULL); tag = gtk_text_buffer_create_tag (buffer, "underline"); @@ -488,30 +488,30 @@ fill_example_buffer (GtkTextBuffer *buffer) setup_tag (tag); g_object_set (G_OBJECT (tag), - "underline", PANGO_UNDERLINE_SINGLE, - NULL); + "underline", PANGO_UNDERLINE_SINGLE, + NULL); setup_tag (tag); g_object_set (G_OBJECT (tag), - "underline", PANGO_UNDERLINE_SINGLE, - NULL); + "underline", PANGO_UNDERLINE_SINGLE, + NULL); tag = gtk_text_buffer_create_tag (buffer, "centered"); g_object_set (G_OBJECT (tag), - "justify", GTK_JUSTIFY_CENTER, - NULL); + "justification", GTK_JUSTIFY_CENTER, + NULL); tag = gtk_text_buffer_create_tag (buffer, "rtl_quote"); g_object_set (G_OBJECT (tag), - "wrap_mode", GTK_WRAPMODE_WORD, - "direction", GTK_TEXT_DIR_RTL, - "indent", 30, - "left_margin", 20, - "right_margin", 20, - NULL); + "wrap_mode", GTK_WRAPMODE_WORD, + "direction", GTK_TEXT_DIR_RTL, + "indent", 30, + "left_margin", 20, + "right_margin", 20, + NULL); #if 0 @@ -1182,6 +1182,9 @@ view_init_menus (View *view) case GTK_WRAPMODE_WORD: menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Wrap Words"); break; + case GTK_WRAPMODE_CHAR: + menu_item = gtk_item_factory_get_widget (view->item_factory, "/Settings/Wrap Chars"); + break; default: break; } @@ -1208,6 +1211,7 @@ static GtkItemFactoryEntry menu_items[] = { "/_Settings", NULL, 0, 0, "<Branch>" }, { "/Settings/Wrap _Off", NULL, do_wrap_changed, GTK_WRAPMODE_NONE, "<RadioItem>" }, { "/Settings/Wrap _Words", NULL, do_wrap_changed, GTK_WRAPMODE_WORD, "/Settings/Wrap Off" }, + { "/Settings/Wrap _Chars", NULL, do_wrap_changed, GTK_WRAPMODE_CHAR, "/Settings/Wrap Off" }, { "/Settings/sep1", NULL, 0, 0, "<Separator>" }, { "/Settings/Editable", NULL, do_editable_changed, TRUE, "<RadioItem>" }, { "/Settings/Not editable", NULL, do_editable_changed, FALSE, "/Settings/Editable" }, |