gtktextlayout.h 9.32 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#ifndef GTK_TEXT_LAYOUT_H
#define GTK_TEXT_LAYOUT_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* This is a "semi-private" header; it is intended for
 * use by the text widget, and the text canvas item,
 * but that's all. We may have to install it so the
 * canvas item can use it, but users are not supposed
 * to use it. 
 */

15 16 17 18 19 20 21 22 23
#include <gtk/gtktextbuffer.h>
#include <gtk/gtktextiter.h>

/* forward declarations that have to be here to avoid including
 * gtktextbtree.h
 */
typedef struct _GtkTextLine     GtkTextLine;
typedef struct _GtkTextLineData GtkTextLineData;

24 25 26 27 28 29 30
#define GTK_TYPE_TEXT_LAYOUT             (gtk_text_layout_get_type())
#define GTK_TEXT_LAYOUT(obj)             (GTK_CHECK_CAST ((obj), GTK_TYPE_TEXT_LAYOUT, GtkTextLayout))
#define GTK_TEXT_LAYOUT_CLASS(klass)     (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_LAYOUT, GtkTextLayoutClass))
#define GTK_IS_TEXT_LAYOUT(obj)          (GTK_CHECK_TYPE ((obj), GTK_TYPE_TEXT_LAYOUT))
#define GTK_IS_TEXT_LAYOUT_CLASS(klass)  (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_LAYOUT))
#define GTK_TEXT_LAYOUT_GET_CLASS(obj)   (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_TEXT_LAYOUT, GtkTextLayoutClass))

31
typedef struct _GtkTextLayout      GtkTextLayout;
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
typedef struct _GtkTextLayoutClass GtkTextLayoutClass;
typedef struct _GtkTextLineDisplay GtkTextLineDisplay;
typedef struct _GtkTextCursorDisplay GtkTextCursorDisplay;
typedef struct _GtkTextAttrAppearance GtkTextAttrAppearance;

struct _GtkTextLayout
{
  GtkObject parent_instance;

  /* width of the display area on-screen,
   * i.e. pixels we should wrap to fit inside. */
  gint screen_width;

  /* width/height of the total logical area being layed out */
  gint width;
  gint height;

49 50 51 52 53 54 55 56
  /* Pixel offsets from the left and from the top to be used when we
   * draw; these allow us to create left/top margins. We don't need
   * anything special for bottom/right margins, because those don't
   * affect drawing.
   */
  /* gint left_edge; */
  /* gint top_edge; */
  
57 58 59
  GtkTextBuffer *buffer;

  /* Default style used if no tags override it */
60
  GtkTextAttributes *default_style;
61 62 63 64 65 66 67 68

  /* Pango contexts used for creating layouts */
  PangoContext *ltr_context;
  PangoContext *rtl_context;

  /* A cache of one style; this is used to ensure
   * we don't constantly regenerate the style
   * over long runs with the same style. */
69
  GtkTextAttributes *one_style_cache;
70 71 72 73 74 75 76 77

  /* A cache of one line display. Getting the same line
   * many times in a row is the most common case.
   */
  GtkTextLineDisplay *one_display_cache;
  
  /* Whether we are allowed to wrap right now */
  gint wrap_loop_count;
78 79 80

  /* Whether to show the insertion cursor */
  guint cursor_visible : 1;
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
};

struct _GtkTextLayoutClass
{
  GtkObjectClass parent_class;

  /* Some portion of the layout was invalidated
   */
  void (* invalidated) (GtkTextLayout *layout);

  /* A range of the layout changed appearance and possibly height
   */
  void (* changed)  (GtkTextLayout *layout,
		     gint           y,
		     gint           old_height,
		     gint           new_height);

  
  GtkTextLineData *(* wrap) (GtkTextLayout *layout,
                             GtkTextLine *line,
                             /* may be NULL */
                             GtkTextLineData *line_data);
  
  void (* get_log_attrs) (GtkTextLayout  *layout,
			  GtkTextLine    *line,
			  PangoLogAttr  **attrs,
			  gint           *n_attrs);
  void  (* invalidate)      (GtkTextLayout *layout,
                             const GtkTextIter *start,
                             const GtkTextIter *end);
  void  (* free_line_data) (GtkTextLayout   *layout,
			    GtkTextLine     *line,
			    GtkTextLineData *line_data);
};

struct _GtkTextAttrAppearance
{
  PangoAttribute attr;
  GtkTextAppearance appearance;
};

struct _GtkTextCursorDisplay
{
  gint x;
  gint y;
  gint height;
  guint is_strong : 1;
  guint is_weak : 1;
};

struct _GtkTextLineDisplay
{
  PangoLayout *layout;
  GSList *cursors;
135
  GSList *pixmaps;
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153

  GtkTextDirection direction;

  gint width;			/* Width of layout */
  gint total_width;		/* width - margins, if no width set on layout, if width set on layout, -1 */
  gint height;
  gint x_offset;		/* Amount layout is shifted from left edge */
  gint left_margin;
  gint right_margin;
  gint top_margin;
  gint bottom_margin;

  gboolean size_only;
  GtkTextLine *line;
};

extern PangoAttrType gtk_text_attr_appearance_type;

Elliot Lee's avatar
Elliot Lee committed
154
GtkType        gtk_text_layout_get_type (void) G_GNUC_CONST;
155 156
GtkTextLayout *gtk_text_layout_new      (void);

157 158 159 160 161 162 163 164 165 166 167 168 169 170
void gtk_text_layout_set_buffer             (GtkTextLayout     *layout,
					     GtkTextBuffer     *buffer);
void gtk_text_layout_set_default_style      (GtkTextLayout     *layout,
					     GtkTextAttributes *values);
void gtk_text_layout_set_contexts           (GtkTextLayout     *layout,
					     PangoContext      *ltr_context,
					     PangoContext      *rtl_context);
void gtk_text_layout_default_style_changed  (GtkTextLayout     *layout);
void gtk_text_layout_set_screen_width       (GtkTextLayout     *layout,
					     gint               width);

void     gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
					     gboolean       cursor_visible);
gboolean gtk_text_layout_get_cursor_visible (GtkTextLayout *layout);
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

/* Getting the size or the lines potentially results in a call to
 * recompute, which is pretty massively expensive. Thus it should
 * basically only be done in an idle handler.
 * 
 * Long-term, we would really like to be able to do these without
 * a full recompute so they may get cheaper over time.
 */
void    gtk_text_layout_get_size (GtkTextLayout  *layout,
	  		          gint           *width,
			          gint           *height);


GSList *gtk_text_layout_get_lines (GtkTextLayout *layout,
				   /* [top_y, bottom_y) */
				   gint           top_y, 
				   gint           bottom_y,
				   gint          *first_line_y);

void gtk_text_layout_wrap_loop_start (GtkTextLayout  *layout);
void gtk_text_layout_wrap_loop_end   (GtkTextLayout  *layout);

GtkTextLineDisplay *gtk_text_layout_get_line_display  (GtkTextLayout      *layout,
						       GtkTextLine        *line,
						       gboolean            size_only);
void                gtk_text_layout_free_line_display (GtkTextLayout      *layout,
						       GtkTextLineDisplay *display);

void gtk_text_layout_get_line_at_y     (GtkTextLayout     *layout,
					GtkTextIter       *target_iter,
					gint               y,
					gint              *line_top);
void gtk_text_layout_get_iter_at_pixel (GtkTextLayout     *layout,
					GtkTextIter       *iter,
					gint               x,
					gint               y);
void gtk_text_layout_invalidate        (GtkTextLayout     *layout,
					const GtkTextIter *start,
					const GtkTextIter *end);
void gtk_text_layout_free_line_data    (GtkTextLayout     *layout,
					GtkTextLine       *line,
					GtkTextLineData   *line_data);

gboolean gtk_text_layout_is_valid        (GtkTextLayout *layout);
void     gtk_text_layout_validate_yrange (GtkTextLayout *layout,
					  GtkTextIter   *anchor_line,
					  gint           y0,
					  gint           y1);
void     gtk_text_layout_validate        (GtkTextLayout *layout,
					  gint           max_pixels);

      /* This function should return the passed-in line data,
         OR remove the existing line data from the line, and
         return a NEW line data after adding it to the line.
         That is, invariant after calling the callback is that
         there should be exactly one line data for this view
         stored on the btree line. */
GtkTextLineData *gtk_text_layout_wrap (GtkTextLayout   *layout,
				       GtkTextLine     *line,
                                         /* may be NULL */
				       GtkTextLineData *line_data);
void     gtk_text_layout_get_log_attrs (GtkTextLayout  *layout,
					GtkTextLine    *line,
					PangoLogAttr  **attrs,
					gint           *n_attrs);
void     gtk_text_layout_changed              (GtkTextLayout     *layout,
					       gint               y,
					       gint               old_height,
					       gint               new_height);
void     gtk_text_layout_get_iter_location    (GtkTextLayout     *layout,
					       const GtkTextIter *iter,
					       GdkRectangle      *rect);
243 244 245 246
void     gtk_text_layout_get_line_yrange      (GtkTextLayout     *layout,
					       const GtkTextIter *iter,
					       gint              *y,
					       gint              *height);
247 248 249 250 251 252 253 254 255
void     gtk_text_layout_get_cursor_locations (GtkTextLayout     *layout,
					       GtkTextIter       *iter,
					       GdkRectangle      *strong_pos,
					       GdkRectangle      *weak_pos);
gboolean gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout     *layout,
					       GtkTextIter       *iter,
					       gint               top,
					       gint               bottom);

256 257 258
void gtk_text_layout_move_iter_to_line_end      (GtkTextLayout *layout,
						 GtkTextIter   *iter,
						 gint           direction);
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
void gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
						 GtkTextIter   *iter);
void gtk_text_layout_move_iter_to_next_line     (GtkTextLayout *layout,
						 GtkTextIter   *iter);
void gtk_text_layout_move_iter_to_x             (GtkTextLayout *layout,
						 GtkTextIter   *iter,
						 gint           x);
void gtk_text_layout_move_iter_visually         (GtkTextLayout *layout,
						 GtkTextIter   *iter,
						 gint           count);

void gtk_text_layout_spew (GtkTextLayout *layout);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif