Blame gdk/gdkpango.c

Packit 98cdb6
/* GDK - The GIMP Drawing Kit
Packit 98cdb6
 * Copyright (C) 2000 Red Hat, Inc. 
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include <math.h>
Packit 98cdb6
#include <pango/pangocairo.h>
Packit 98cdb6
#include "gdkcairo.h"
Packit 98cdb6
#include "gdkcolor.h"
Packit 98cdb6
#include "gdkgc.h"
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
#include "gdkpango.h"
Packit 98cdb6
#include "gdkrgb.h"
Packit 98cdb6
#include "gdkprivate.h"
Packit 98cdb6
#include "gdkscreen.h"
Packit 98cdb6
#include "gdkintl.h"
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
#define GDK_INFO_KEY "gdk-info"
Packit 98cdb6
Packit 98cdb6
/* We have various arrays indexed by render part; if PangoRenderPart
Packit 98cdb6
 * is extended, we want to make sure not to overwrite the end of
Packit 98cdb6
 * those arrays.
Packit 98cdb6
 */
Packit 98cdb6
#define MAX_RENDER_PART  PANGO_RENDER_PART_STRIKETHROUGH
Packit 98cdb6
Packit 98cdb6
struct _GdkPangoRendererPrivate
Packit 98cdb6
{
Packit 98cdb6
  GdkScreen *screen;
Packit 98cdb6
Packit 98cdb6
  /* GdkPangoRenderer specific state */
Packit 98cdb6
  PangoColor override_color[MAX_RENDER_PART + 1];
Packit 98cdb6
  gboolean override_color_set[MAX_RENDER_PART + 1];
Packit 98cdb6
  
Packit 98cdb6
  GdkBitmap *stipple[MAX_RENDER_PART + 1];
Packit 98cdb6
  PangoColor emboss_color;
Packit 98cdb6
  gboolean embossed;
Packit 98cdb6
Packit 98cdb6
  cairo_t *cr;
Packit 98cdb6
  PangoRenderPart last_part;
Packit 98cdb6
Packit 98cdb6
  /* Current target */
Packit 98cdb6
  GdkDrawable *drawable;
Packit 98cdb6
  GdkGC *base_gc;
Packit 98cdb6
Packit 98cdb6
  gboolean gc_changed;
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
static PangoAttrType gdk_pango_attr_stipple_type;
Packit 98cdb6
static PangoAttrType gdk_pango_attr_embossed_type;
Packit 98cdb6
static PangoAttrType gdk_pango_attr_emboss_color_type;
Packit 98cdb6
Packit 98cdb6
enum {
Packit 98cdb6
  PROP_0,
Packit 98cdb6
  PROP_SCREEN
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
G_DEFINE_TYPE (GdkPangoRenderer, gdk_pango_renderer, PANGO_TYPE_RENDERER)
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_finalize (GObject *object)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (object);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
  int i;
Packit 98cdb6
Packit 98cdb6
  if (priv->base_gc)
Packit 98cdb6
    g_object_unref (priv->base_gc);
Packit 98cdb6
  if (priv->drawable)
Packit 98cdb6
    g_object_unref (priv->drawable);
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i <= MAX_RENDER_PART; i++)
Packit 98cdb6
    if (priv->stipple[i])
Packit 98cdb6
      g_object_unref (priv->stipple[i]);
Packit 98cdb6
Packit 98cdb6
  G_OBJECT_CLASS (gdk_pango_renderer_parent_class)->finalize (object);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GObject*
Packit 98cdb6
gdk_pango_renderer_constructor (GType                  type,
Packit 98cdb6
				guint                  n_construct_properties,
Packit 98cdb6
				GObjectConstructParam *construct_params)
Packit 98cdb6
{
Packit 98cdb6
  GObject *object;
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer;
Packit 98cdb6
Packit 98cdb6
  object = G_OBJECT_CLASS (gdk_pango_renderer_parent_class)->constructor (type,
Packit 98cdb6
                                                                          n_construct_properties,
Packit 98cdb6
                                                                          construct_params);
Packit 98cdb6
Packit 98cdb6
  gdk_renderer = GDK_PANGO_RENDERER (object);
Packit 98cdb6
  
Packit 98cdb6
  if (!gdk_renderer->priv->screen)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("Screen must be specified at construct time for GdkPangoRenderer");
Packit 98cdb6
      gdk_renderer->priv->screen = gdk_screen_get_default ();
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return object;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Adjusts matrix and color for the renderer to draw the secondary
Packit 98cdb6
 * "shadow" copy for embossed text */
Packit 98cdb6
static void
Packit 98cdb6
emboss_context (GdkPangoRenderer *renderer, cairo_t *cr)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRendererPrivate *priv = renderer->priv;
Packit 98cdb6
  cairo_matrix_t tmp_matrix;
Packit 98cdb6
  double red, green, blue;
Packit 98cdb6
Packit 98cdb6
  /* The gymnastics here to adjust the matrix are because we want
Packit 98cdb6
   * to offset by +1,+1 in device-space, not in user-space,
Packit 98cdb6
   * so we can't just draw the layout at x + 1, y + 1
Packit 98cdb6
   */
Packit 98cdb6
  cairo_get_matrix (cr, &tmp_matrix);
Packit 98cdb6
  tmp_matrix.x0 += 1.0;
Packit 98cdb6
  tmp_matrix.y0 += 1.0;
Packit 98cdb6
  cairo_set_matrix (cr, &tmp_matrix);
Packit 98cdb6
Packit 98cdb6
  red = (double) priv->emboss_color.red / 65535.;
Packit 98cdb6
  green = (double) priv->emboss_color.green / 65535.;
Packit 98cdb6
  blue = (double) priv->emboss_color.blue / 65535.;
Packit 98cdb6
Packit 98cdb6
  cairo_set_source_rgb (cr, red, green, blue);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static inline gboolean
Packit 98cdb6
color_equal (const PangoColor *c1, const PangoColor *c2)
Packit 98cdb6
{
Packit 98cdb6
  if (!c1 && !c2)
Packit 98cdb6
    return TRUE;
Packit 98cdb6
Packit 98cdb6
  if (c1 && c2 &&
Packit 98cdb6
      c1->red == c2->red &&
Packit 98cdb6
      c1->green == c2->green &&
Packit 98cdb6
      c1->blue == c2->blue)
Packit 98cdb6
    return TRUE;
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static cairo_t *
Packit 98cdb6
get_cairo_context (GdkPangoRenderer *gdk_renderer,
Packit 98cdb6
		   PangoRenderPart   part)
Packit 98cdb6
{
Packit 98cdb6
  PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
Packit 98cdb6
  if (!priv->cr)
Packit 98cdb6
    {
Packit 98cdb6
      const PangoMatrix *matrix;
Packit 98cdb6
      
Packit 98cdb6
      priv->cr = gdk_cairo_create (priv->drawable);
Packit 98cdb6
Packit 98cdb6
      matrix = pango_renderer_get_matrix (renderer);
Packit 98cdb6
      if (matrix)
Packit 98cdb6
	{
Packit 98cdb6
	  cairo_matrix_t cairo_matrix;
Packit 98cdb6
	  
Packit 98cdb6
	  cairo_matrix_init (&cairo_matrix,
Packit 98cdb6
			     matrix->xx, matrix->yx,
Packit 98cdb6
			     matrix->xy, matrix->yy,
Packit 98cdb6
			     matrix->x0, matrix->y0);
Packit 98cdb6
	  cairo_set_matrix (priv->cr, &cairo_matrix);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (part != priv->last_part)
Packit 98cdb6
    {
Packit 98cdb6
      PangoColor *pango_color;
Packit 98cdb6
      GdkColor *color;
Packit 98cdb6
      GdkColor tmp_color;
Packit 98cdb6
      gboolean changed;
Packit 98cdb6
Packit 98cdb6
      pango_color = pango_renderer_get_color (renderer, part);
Packit 98cdb6
      
Packit 98cdb6
      if (priv->last_part != -1)
Packit 98cdb6
	changed = priv->gc_changed ||
Packit 98cdb6
	  priv->stipple[priv->last_part] != priv->stipple[part] ||
Packit 98cdb6
	  !color_equal (pango_color,
Packit 98cdb6
			pango_renderer_get_color (renderer, priv->last_part));
Packit 98cdb6
      else
Packit 98cdb6
	changed = TRUE;
Packit 98cdb6
      
Packit 98cdb6
      if (changed)
Packit 98cdb6
	{
Packit 98cdb6
	  if (pango_color)
Packit 98cdb6
	    {
Packit 98cdb6
	      tmp_color.red = pango_color->red;
Packit 98cdb6
	      tmp_color.green = pango_color->green;
Packit 98cdb6
	      tmp_color.blue = pango_color->blue;
Packit 98cdb6
	      
Packit 98cdb6
	      color = &tmp_color;
Packit 98cdb6
	    }
Packit 98cdb6
	  else
Packit 98cdb6
	    color = NULL;
Packit 98cdb6
Packit 98cdb6
	  _gdk_gc_update_context (priv->base_gc,
Packit 98cdb6
				  priv->cr,
Packit 98cdb6
				  color,
Packit 98cdb6
				  priv->stipple[part],
Packit 98cdb6
				  priv->gc_changed,
Packit 98cdb6
				  priv->drawable);
Packit 98cdb6
	}
Packit 98cdb6
Packit 98cdb6
      priv->last_part = part;
Packit 98cdb6
      priv->gc_changed = FALSE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return priv->cr;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_draw_glyphs (PangoRenderer    *renderer,
Packit 98cdb6
				PangoFont        *font,
Packit 98cdb6
				PangoGlyphString *glyphs,
Packit 98cdb6
				int               x,
Packit 98cdb6
				int               y)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
  cairo_t *cr;
Packit 98cdb6
Packit 98cdb6
  cr = get_cairo_context (gdk_renderer, 
Packit 98cdb6
			  PANGO_RENDER_PART_FOREGROUND);
Packit 98cdb6
Packit 98cdb6
  if (priv->embossed)
Packit 98cdb6
    {
Packit 98cdb6
      cairo_save (cr);
Packit 98cdb6
      emboss_context (gdk_renderer, cr);
Packit 98cdb6
      cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
Packit 98cdb6
      pango_cairo_show_glyph_string (cr, font, glyphs);
Packit 98cdb6
      cairo_restore (cr);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
Packit 98cdb6
  pango_cairo_show_glyph_string (cr, font, glyphs);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_draw_rectangle (PangoRenderer    *renderer,
Packit 98cdb6
				   PangoRenderPart   part,
Packit 98cdb6
				   int               x,
Packit 98cdb6
				   int               y,
Packit 98cdb6
				   int               width,
Packit 98cdb6
				   int               height)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
  cairo_t *cr;
Packit 98cdb6
  
Packit 98cdb6
  cr = get_cairo_context (gdk_renderer, part);
Packit 98cdb6
Packit 98cdb6
  if (priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
Packit 98cdb6
    {
Packit 98cdb6
      cairo_save (cr);
Packit 98cdb6
      emboss_context (gdk_renderer, cr);
Packit 98cdb6
      cairo_rectangle (cr,
Packit 98cdb6
		       (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
Packit 98cdb6
		       (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
Packit 98cdb6
Packit 98cdb6
      cairo_fill (cr);
Packit 98cdb6
      cairo_restore (cr);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  cairo_rectangle (cr,
Packit 98cdb6
		   (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
Packit 98cdb6
		   (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
Packit 98cdb6
  cairo_fill (cr);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_draw_error_underline (PangoRenderer    *renderer,
Packit 98cdb6
					 int               x,
Packit 98cdb6
					 int               y,
Packit 98cdb6
					 int               width,
Packit 98cdb6
					 int               height)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
  cairo_t *cr;
Packit 98cdb6
  
Packit 98cdb6
  cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE);
Packit 98cdb6
  
Packit 98cdb6
  if (priv->embossed)
Packit 98cdb6
    {
Packit 98cdb6
      cairo_save (cr);
Packit 98cdb6
      emboss_context (gdk_renderer, cr);
Packit 98cdb6
      pango_cairo_show_error_underline (cr,
Packit 98cdb6
            (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
Packit 98cdb6
            (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
Packit 98cdb6
      cairo_restore (cr);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  pango_cairo_show_error_underline (cr,
Packit 98cdb6
	(double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
Packit 98cdb6
	(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_draw_shape (PangoRenderer  *renderer,
Packit 98cdb6
			       PangoAttrShape *attr,
Packit 98cdb6
			       int             x,
Packit 98cdb6
			       int             y)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
  PangoLayout *layout;
Packit 98cdb6
  PangoCairoShapeRendererFunc shape_renderer;
Packit 98cdb6
  gpointer                    shape_renderer_data;
Packit 98cdb6
  cairo_t *cr;
Packit 98cdb6
  double dx = (double)x / PANGO_SCALE, dy = (double)y / PANGO_SCALE;
Packit 98cdb6
Packit 98cdb6
  layout = pango_renderer_get_layout (renderer);
Packit 98cdb6
Packit 98cdb6
  if (!layout)
Packit 98cdb6
  	return;
Packit 98cdb6
Packit 98cdb6
  shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout),
Packit 98cdb6
							   &shape_renderer_data);
Packit 98cdb6
Packit 98cdb6
  if (!shape_renderer)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_FOREGROUND);
Packit 98cdb6
  
Packit 98cdb6
  cairo_save (cr);
Packit 98cdb6
Packit 98cdb6
  if (priv->embossed)
Packit 98cdb6
    {
Packit 98cdb6
      cairo_save (cr);
Packit 98cdb6
      emboss_context (gdk_renderer, cr);
Packit 98cdb6
Packit 98cdb6
      cairo_move_to (cr, dx, dy);
Packit 98cdb6
      shape_renderer (cr, attr, FALSE, shape_renderer_data);
Packit 98cdb6
Packit 98cdb6
      cairo_restore (cr);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  cairo_move_to (cr, dx, dy);
Packit 98cdb6
  shape_renderer (cr, attr, FALSE, shape_renderer_data);
Packit 98cdb6
Packit 98cdb6
  cairo_restore (cr);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_part_changed (PangoRenderer   *renderer,
Packit 98cdb6
				 PangoRenderPart  part)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
Packit 98cdb6
  if (gdk_renderer->priv->last_part == part)
Packit 98cdb6
    gdk_renderer->priv->last_part = (PangoRenderPart)-1;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_begin (PangoRenderer *renderer)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
  
Packit 98cdb6
  if (!priv->drawable || !priv->base_gc)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("gdk_pango_renderer_set_drawable() and gdk_pango_renderer_set_drawable()"
Packit 98cdb6
		 "must be used to set the target drawable and GC before using the renderer\n");
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_end (PangoRenderer *renderer)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  GdkPangoRendererPrivate *priv = gdk_renderer->priv;
Packit 98cdb6
Packit 98cdb6
  if (priv->cr)
Packit 98cdb6
    {
Packit 98cdb6
      cairo_destroy (priv->cr);
Packit 98cdb6
      priv->cr = NULL;
Packit 98cdb6
    }
Packit 98cdb6
  priv->last_part = (PangoRenderPart)-1;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_prepare_run (PangoRenderer  *renderer,
Packit 98cdb6
				PangoLayoutRun *run)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  gboolean embossed = FALSE;
Packit 98cdb6
  GdkBitmap *stipple = NULL;
Packit 98cdb6
  gboolean changed = FALSE;
Packit 98cdb6
  PangoColor emboss_color;
Packit 98cdb6
  GSList *l;
Packit 98cdb6
  int i;
Packit 98cdb6
Packit 98cdb6
  emboss_color.red = 0xffff;
Packit 98cdb6
  emboss_color.green = 0xffff;
Packit 98cdb6
  emboss_color.blue = 0xffff;
Packit 98cdb6
Packit 98cdb6
  for (l = run->item->analysis.extra_attrs; l; l = l->next)
Packit 98cdb6
    {
Packit 98cdb6
      PangoAttribute *attr = l->data;
Packit 98cdb6
Packit 98cdb6
      /* stipple_type and embossed_type aren't necessarily
Packit 98cdb6
       * initialized, but they are 0, which is an
Packit 98cdb6
       * invalid type so won't occur. 
Packit 98cdb6
       */
Packit 98cdb6
      if (attr->klass->type == gdk_pango_attr_stipple_type)
Packit 98cdb6
	{
Packit 98cdb6
	  stipple = ((GdkPangoAttrStipple*)attr)->stipple;
Packit 98cdb6
	}
Packit 98cdb6
      else if (attr->klass->type == gdk_pango_attr_embossed_type)
Packit 98cdb6
	{
Packit 98cdb6
	  embossed = ((GdkPangoAttrEmbossed*)attr)->embossed;
Packit 98cdb6
	}
Packit 98cdb6
      else if (attr->klass->type == gdk_pango_attr_emboss_color_type)
Packit 98cdb6
	{
Packit 98cdb6
	  emboss_color = ((GdkPangoAttrEmbossColor*)attr)->color;
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_FOREGROUND, stipple);
Packit 98cdb6
  gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_BACKGROUND, stipple);
Packit 98cdb6
  gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_UNDERLINE, stipple);
Packit 98cdb6
  gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_STRIKETHROUGH, stipple);
Packit 98cdb6
Packit 98cdb6
  if (embossed != gdk_renderer->priv->embossed)
Packit 98cdb6
    {
Packit 98cdb6
      gdk_renderer->priv->embossed = embossed;
Packit 98cdb6
      changed = TRUE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (!color_equal (&gdk_renderer->priv->emboss_color, &emboss_color))
Packit 98cdb6
    {
Packit 98cdb6
      gdk_renderer->priv->emboss_color = emboss_color;
Packit 98cdb6
      changed = TRUE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (changed)
Packit 98cdb6
    pango_renderer_part_changed (renderer, PANGO_RENDER_PART_FOREGROUND);
Packit 98cdb6
Packit 98cdb6
  PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->prepare_run (renderer, run);
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i <= MAX_RENDER_PART; i++)
Packit 98cdb6
    {
Packit 98cdb6
      if (gdk_renderer->priv->override_color_set[i])
Packit 98cdb6
	pango_renderer_set_color (renderer, i, &gdk_renderer->priv->override_color[i]);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_set_property (GObject         *object,
Packit 98cdb6
				 guint            prop_id,
Packit 98cdb6
				 const GValue    *value,
Packit 98cdb6
				 GParamSpec      *pspec)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (object);
Packit 98cdb6
Packit 98cdb6
  switch (prop_id)
Packit 98cdb6
    {
Packit 98cdb6
    case PROP_SCREEN:
Packit 98cdb6
      gdk_renderer->priv->screen = g_value_get_object (value);
Packit 98cdb6
      break;
Packit 98cdb6
    default:
Packit 98cdb6
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_get_property (GObject    *object,
Packit 98cdb6
				 guint       prop_id,
Packit 98cdb6
				 GValue     *value,
Packit 98cdb6
				 GParamSpec *pspec)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (object);
Packit 98cdb6
Packit 98cdb6
  switch (prop_id)
Packit 98cdb6
    {
Packit 98cdb6
    case PROP_SCREEN:
Packit 98cdb6
      g_value_set_object (value, gdk_renderer->priv->screen);
Packit 98cdb6
      break;
Packit 98cdb6
    default:
Packit 98cdb6
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit 98cdb6
      break;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_init (GdkPangoRenderer *renderer)
Packit 98cdb6
{
Packit 98cdb6
  renderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer,
Packit 98cdb6
						GDK_TYPE_PANGO_RENDERER,
Packit 98cdb6
						GdkPangoRendererPrivate);
Packit 98cdb6
Packit 98cdb6
  renderer->priv->last_part = (PangoRenderPart)-1;
Packit 98cdb6
  renderer->priv->gc_changed = TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_renderer_class_init (GdkPangoRendererClass *klass)
Packit 98cdb6
{
Packit 98cdb6
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit 98cdb6
  
Packit 98cdb6
  PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
Packit 98cdb6
  
Packit 98cdb6
  renderer_class->draw_glyphs = gdk_pango_renderer_draw_glyphs;
Packit 98cdb6
  renderer_class->draw_rectangle = gdk_pango_renderer_draw_rectangle;
Packit 98cdb6
  renderer_class->draw_error_underline = gdk_pango_renderer_draw_error_underline;
Packit 98cdb6
  renderer_class->draw_shape = gdk_pango_renderer_draw_shape;
Packit 98cdb6
  renderer_class->part_changed = gdk_pango_renderer_part_changed;
Packit 98cdb6
  renderer_class->begin = gdk_pango_renderer_begin;
Packit 98cdb6
  renderer_class->end = gdk_pango_renderer_end;
Packit 98cdb6
  renderer_class->prepare_run = gdk_pango_renderer_prepare_run;
Packit 98cdb6
Packit 98cdb6
  object_class->finalize = gdk_pango_renderer_finalize;
Packit 98cdb6
  object_class->constructor = gdk_pango_renderer_constructor;
Packit 98cdb6
  object_class->set_property = gdk_pango_renderer_set_property;
Packit 98cdb6
  object_class->get_property = gdk_pango_renderer_get_property;
Packit 98cdb6
  
Packit 98cdb6
  g_object_class_install_property (object_class,
Packit 98cdb6
                                   PROP_SCREEN,
Packit 98cdb6
                                   g_param_spec_object ("screen",
Packit 98cdb6
                                                        P_("Screen"),
Packit 98cdb6
                                                        P_("the GdkScreen for the renderer"),
Packit 98cdb6
                                                        GDK_TYPE_SCREEN,
Packit 98cdb6
                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
Packit 98cdb6
							G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | 
Packit 98cdb6
							G_PARAM_STATIC_BLURB));
Packit 98cdb6
Packit 98cdb6
  g_type_class_add_private (object_class, sizeof (GdkPangoRendererPrivate));  
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_renderer_new:
Packit 98cdb6
 * @screen: a #GdkScreen
Packit 98cdb6
 * 
Packit 98cdb6
 * Creates a new #PangoRenderer for @screen. Normally you can use the
Packit 98cdb6
 * results of gdk_pango_renderer_get_default() rather than creating a new
Packit 98cdb6
 * renderer.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a newly created #PangoRenderer. Free with g_object_unref().
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.6
Packit 98cdb6
 **/
Packit 98cdb6
PangoRenderer *
Packit 98cdb6
gdk_pango_renderer_new (GdkScreen *screen)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (screen != NULL, NULL);
Packit 98cdb6
  
Packit 98cdb6
  return g_object_new (GDK_TYPE_PANGO_RENDERER,
Packit 98cdb6
		       "screen", screen,
Packit 98cdb6
		       NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
on_renderer_display_closed (GdkDisplay       *display,
Packit 98cdb6
                            gboolean          is_error,
Packit 98cdb6
			    GdkPangoRenderer *renderer)
Packit 98cdb6
{
Packit 98cdb6
  g_signal_handlers_disconnect_by_func (display,
Packit 98cdb6
					on_renderer_display_closed,
Packit 98cdb6
					renderer);
Packit 98cdb6
  g_object_set_data (G_OBJECT (renderer->priv->screen),
Packit 98cdb6
                     g_intern_static_string ("gdk-pango-renderer"), NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_renderer_get_default:
Packit 98cdb6
 * @screen: a #GdkScreen
Packit 98cdb6
 * 
Packit 98cdb6
 * Gets the default #PangoRenderer for a screen. This default renderer
Packit 98cdb6
 * is shared by all users of the display, so properties such as the color
Packit 98cdb6
 * or transformation matrix set for the renderer may be overwritten
Packit 98cdb6
 * by functions such as gdk_draw_layout().
Packit 98cdb6
 *
Packit 98cdb6
 * Before using the renderer, you need to call gdk_pango_renderer_set_drawable()
Packit 98cdb6
 * and gdk_pango_renderer_set_gc() to set the drawable and graphics context
Packit 98cdb6
 * to use for drawing.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the default #PangoRenderer for @screen. The
Packit 98cdb6
 *  renderer is owned by GTK+ and will be kept around until the
Packit 98cdb6
 *  screen is closed.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.6
Packit 98cdb6
 **/
Packit 98cdb6
PangoRenderer *
Packit 98cdb6
gdk_pango_renderer_get_default (GdkScreen *screen)
Packit 98cdb6
{
Packit 98cdb6
  PangoRenderer *renderer;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
Packit 98cdb6
  
Packit 98cdb6
  renderer = g_object_get_data (G_OBJECT (screen), "gdk-pango-renderer");
Packit 98cdb6
  if (!renderer)
Packit 98cdb6
    {
Packit 98cdb6
      renderer = gdk_pango_renderer_new (screen);
Packit 98cdb6
      g_object_set_data_full (G_OBJECT (screen), 
Packit 98cdb6
                              g_intern_static_string ("gdk-pango-renderer"), renderer,
Packit 98cdb6
			      (GDestroyNotify)g_object_unref);
Packit 98cdb6
Packit 98cdb6
      g_signal_connect (gdk_screen_get_display (screen), "closed",
Packit 98cdb6
			G_CALLBACK (on_renderer_display_closed), renderer);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return renderer;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_renderer_set_drawable:
Packit 98cdb6
 * @gdk_renderer: a #GdkPangoRenderer
Packit 98cdb6
 * @drawable: (allow-none): the new target drawable, or %NULL
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the drawable the renderer draws to.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.6
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_pango_renderer_set_drawable (GdkPangoRenderer *gdk_renderer,
Packit 98cdb6
				 GdkDrawable      *drawable)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRendererPrivate *priv;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer));
Packit 98cdb6
  g_return_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
Packit 98cdb6
  priv = gdk_renderer->priv;
Packit 98cdb6
  
Packit 98cdb6
  if (priv->drawable != drawable)
Packit 98cdb6
    {
Packit 98cdb6
      if (priv->drawable)
Packit 98cdb6
	g_object_unref (priv->drawable);
Packit 98cdb6
      priv->drawable = drawable;
Packit 98cdb6
      if (priv->drawable)
Packit 98cdb6
	g_object_ref (priv->drawable);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_renderer_set_gc:
Packit 98cdb6
 * @gdk_renderer: a #GdkPangoRenderer
Packit 98cdb6
 * @gc: (allow-none): the new GC to use for drawing, or %NULL
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the GC the renderer draws with. Note that the GC must not be
Packit 98cdb6
 * modified until it is unset by calling the function again with
Packit 98cdb6
 * %NULL for the @gc parameter, since GDK may make internal copies
Packit 98cdb6
 * of the GC which won't be updated to follow changes to the
Packit 98cdb6
 * original GC.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.6
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_pango_renderer_set_gc (GdkPangoRenderer *gdk_renderer,
Packit 98cdb6
			   GdkGC            *gc)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRendererPrivate *priv;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer));
Packit 98cdb6
  g_return_if_fail (gc == NULL || GDK_IS_GC (gc));
Packit 98cdb6
Packit 98cdb6
  priv = gdk_renderer->priv;
Packit 98cdb6
  
Packit 98cdb6
  if (priv->base_gc != gc)
Packit 98cdb6
    {
Packit 98cdb6
      if (priv->base_gc)
Packit 98cdb6
	g_object_unref (priv->base_gc);
Packit 98cdb6
      priv->base_gc = gc;
Packit 98cdb6
      if (priv->base_gc)
Packit 98cdb6
	g_object_ref (priv->base_gc);
Packit 98cdb6
Packit 98cdb6
      priv->gc_changed = TRUE;
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_renderer_set_stipple:
Packit 98cdb6
 * @gdk_renderer: a #GdkPangoRenderer
Packit 98cdb6
 * @part: the part to render with the stipple
Packit 98cdb6
 * @stipple: the new stipple value.
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the stipple for one render part (foreground, background, underline,
Packit 98cdb6
 * etc.) Note that this is overwritten when iterating through the individual
Packit 98cdb6
 * styled runs of a #PangoLayout or #PangoLayoutLine. This function is thus
Packit 98cdb6
 * only useful when you call low level functions like pango_renderer_draw_glyphs()
Packit 98cdb6
 * directly, or in the 'prepare_run' virtual function of a subclass of
Packit 98cdb6
 * #GdkPangoRenderer.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.6
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_pango_renderer_set_stipple (GdkPangoRenderer *gdk_renderer,
Packit 98cdb6
				PangoRenderPart   part,
Packit 98cdb6
				GdkBitmap        *stipple)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer));
Packit 98cdb6
Packit 98cdb6
  if (part > MAX_RENDER_PART)	/* Silently ignore unknown parts */
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (stipple != gdk_renderer->priv->stipple[part])
Packit 98cdb6
    {
Packit 98cdb6
      if (gdk_renderer->priv->stipple[part])
Packit 98cdb6
	g_object_unref (gdk_renderer->priv->stipple[part]);
Packit 98cdb6
Packit 98cdb6
      gdk_renderer->priv->stipple[part] = stipple;
Packit 98cdb6
      
Packit 98cdb6
      if (gdk_renderer->priv->stipple[part])
Packit 98cdb6
	g_object_ref (gdk_renderer->priv->stipple[part]);
Packit 98cdb6
Packit 98cdb6
      pango_renderer_part_changed (PANGO_RENDERER (gdk_renderer), part);
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_renderer_set_override_color:
Packit 98cdb6
 * @gdk_renderer: a #GdkPangoRenderer
Packit 98cdb6
 * @part: the part to render to set the color of
Packit 98cdb6
 * @color: (allow-none): the color to use, or %NULL to unset a previously
Packit 98cdb6
 *         set override color.
Packit 98cdb6
 * 
Packit 98cdb6
 * Sets the color for a particular render part (foreground,
Packit 98cdb6
 * background, underline, etc.), overriding any attributes on the layouts
Packit 98cdb6
 * renderered with this renderer.
Packit 98cdb6
 * 
Packit 98cdb6
 * Since: 2.6
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_pango_renderer_set_override_color (GdkPangoRenderer *gdk_renderer,
Packit 98cdb6
				       PangoRenderPart   part,
Packit 98cdb6
				       const GdkColor   *color)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRendererPrivate *priv;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer));
Packit 98cdb6
Packit 98cdb6
  priv = gdk_renderer->priv;
Packit 98cdb6
  
Packit 98cdb6
  if (part > MAX_RENDER_PART)	/* Silently ignore unknown parts */
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (color)
Packit 98cdb6
    {
Packit 98cdb6
      priv->override_color[part].red = color->red;
Packit 98cdb6
      priv->override_color[part].green = color->green;
Packit 98cdb6
      priv->override_color[part].blue = color->blue;
Packit 98cdb6
      priv->override_color_set[part] = TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    priv->override_color_set[part] = FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_context_set_colormap:
Packit 98cdb6
 * @context: a #PangoContext
Packit 98cdb6
 * @colormap: a #GdkColormap
Packit 98cdb6
 *
Packit 98cdb6
 * This function used to set the colormap to be used for drawing with
Packit 98cdb6
 * @context. The colormap is now always derived from the graphics
Packit 98cdb6
 * context used for drawing, so calling this function is no longer
Packit 98cdb6
 * necessary.
Packit 98cdb6
 **/
Packit 98cdb6
void
Packit 98cdb6
gdk_pango_context_set_colormap (PangoContext *context,
Packit 98cdb6
				GdkColormap  *colormap)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (PANGO_IS_CONTEXT (context));
Packit 98cdb6
  g_return_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Gets a renderer to draw with, setting the properties of the
Packit 98cdb6
 * renderer and activating it. Note that since we activate the
Packit 98cdb6
 * renderer here, the implicit setting of the matrix that
Packit 98cdb6
 * pango_renderer_draw_layout_[line] normally do when they
Packit 98cdb6
 * activate the renderer is suppressed. */
Packit 98cdb6
static PangoRenderer *
Packit 98cdb6
get_renderer (GdkDrawable     *drawable,
Packit 98cdb6
	      GdkGC           *gc,
Packit 98cdb6
	      const GdkColor  *foreground,
Packit 98cdb6
	      const GdkColor  *background)
Packit 98cdb6
{
Packit 98cdb6
  GdkScreen *screen = gdk_drawable_get_screen (drawable);
Packit 98cdb6
  PangoRenderer *renderer = gdk_pango_renderer_get_default (screen);
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
Packit 98cdb6
  gdk_pango_renderer_set_drawable (gdk_renderer, drawable);
Packit 98cdb6
  gdk_pango_renderer_set_gc (gdk_renderer, gc);  
Packit 98cdb6
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_FOREGROUND,
Packit 98cdb6
					 foreground);
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_UNDERLINE,
Packit 98cdb6
					 foreground);
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_STRIKETHROUGH,
Packit 98cdb6
					 foreground);
Packit 98cdb6
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_BACKGROUND,
Packit 98cdb6
					 background);
Packit 98cdb6
Packit 98cdb6
  pango_renderer_activate (renderer);
Packit 98cdb6
Packit 98cdb6
  return renderer;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Cleans up the renderer obtained with get_renderer() */
Packit 98cdb6
static void
Packit 98cdb6
release_renderer (PangoRenderer *renderer)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
Packit 98cdb6
  
Packit 98cdb6
  pango_renderer_deactivate (renderer);
Packit 98cdb6
  
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_FOREGROUND,
Packit 98cdb6
					 NULL);
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_UNDERLINE,
Packit 98cdb6
					 NULL);
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_STRIKETHROUGH,
Packit 98cdb6
					 NULL);
Packit 98cdb6
  gdk_pango_renderer_set_override_color (gdk_renderer,
Packit 98cdb6
					 PANGO_RENDER_PART_BACKGROUND,
Packit 98cdb6
					 NULL);
Packit 98cdb6
  
Packit 98cdb6
  gdk_pango_renderer_set_drawable (gdk_renderer, NULL);
Packit 98cdb6
  gdk_pango_renderer_set_gc (gdk_renderer, NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_draw_layout_line_with_colors:
Packit 98cdb6
 * @drawable:  the drawable on which to draw the line
Packit 98cdb6
 * @gc:        base graphics to use
Packit 98cdb6
 * @x:         the x position of start of string (in pixels)
Packit 98cdb6
 * @y:         the y position of baseline (in pixels)
Packit 98cdb6
 * @line:      a #PangoLayoutLine
Packit 98cdb6
 * @foreground: (allow-none): foreground override color, or %NULL for none
Packit 98cdb6
 * @background: (allow-none): background override color, or %NULL for none
Packit 98cdb6
 *
Packit 98cdb6
 * Render a #PangoLayoutLine onto a #GdkDrawable, overriding the
Packit 98cdb6
 * layout's normal colors with @foreground and/or @background.
Packit 98cdb6
 * @foreground and @background need not be allocated.
Packit 98cdb6
 *
Packit 98cdb6
 * If the layout's #PangoContext has a transformation matrix set, then
Packit 98cdb6
 * @x and @y specify the position of the left edge of the baseline
Packit 98cdb6
 * (left is in before-tranform user coordinates) in after-transform
Packit 98cdb6
 * device coordinates.
Packit 98cdb6
 */
Packit 98cdb6
void 
Packit 98cdb6
gdk_draw_layout_line_with_colors (GdkDrawable      *drawable,
Packit 98cdb6
                                  GdkGC            *gc,
Packit 98cdb6
                                  gint              x, 
Packit 98cdb6
                                  gint              y,
Packit 98cdb6
                                  PangoLayoutLine  *line,
Packit 98cdb6
                                  const GdkColor   *foreground,
Packit 98cdb6
                                  const GdkColor   *background)
Packit 98cdb6
{
Packit 98cdb6
  PangoRenderer *renderer;
Packit 98cdb6
  const PangoMatrix *matrix;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
  g_return_if_fail (GDK_IS_GC (gc));
Packit 98cdb6
  g_return_if_fail (line != NULL);
Packit 98cdb6
Packit 98cdb6
  renderer = get_renderer (drawable, gc, foreground, background);
Packit 98cdb6
Packit 98cdb6
  /* When we have a matrix, we do positioning by adjusting the matrix, and
Packit 98cdb6
   * clamp just pass x=0, y=0 to the lower levels. We don't want to introduce
Packit 98cdb6
   * a matrix when the caller didn't provide one, however, since that adds
Packit 98cdb6
   * lots of floating point arithmetic for each glyph.
Packit 98cdb6
   */
Packit 98cdb6
  matrix = pango_context_get_matrix (pango_layout_get_context (line->layout));
Packit 98cdb6
  if (matrix)
Packit 98cdb6
    {
Packit 98cdb6
      PangoMatrix tmp_matrix;
Packit 98cdb6
      
Packit 98cdb6
      tmp_matrix = *matrix;
Packit 98cdb6
      tmp_matrix.x0 += x;
Packit 98cdb6
      tmp_matrix.y0 += y;
Packit 98cdb6
      pango_renderer_set_matrix (renderer, &tmp_matrix);
Packit 98cdb6
Packit 98cdb6
      x = 0;
Packit 98cdb6
      y = 0;
Packit 98cdb6
    }
Packit 98cdb6
  /* Fall back to introduce a matrix if the coords would scale out of range.
Packit 98cdb6
   * The x and y here will be added to in-layout coordinates.  So we cannot
Packit 98cdb6
   * support the entire range here safely.  So, we just accept the middle half
Packit 98cdb6
   * and use fallback for the rest. */
Packit 98cdb6
  else if (GDK_PANGO_UNITS_OVERFLOWS (x, y))
Packit 98cdb6
    {
Packit 98cdb6
      PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
Packit 98cdb6
      tmp_matrix.x0 += x;
Packit 98cdb6
      tmp_matrix.y0 += y;
Packit 98cdb6
      pango_renderer_set_matrix (renderer, &tmp_matrix);
Packit 98cdb6
Packit 98cdb6
      x = 0;
Packit 98cdb6
      y = 0;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    pango_renderer_set_matrix (renderer, NULL);
Packit 98cdb6
Packit 98cdb6
  pango_renderer_draw_layout_line (renderer, line, x * PANGO_SCALE, y * PANGO_SCALE);
Packit 98cdb6
Packit 98cdb6
  release_renderer (renderer);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_draw_layout_with_colors:
Packit 98cdb6
 * @drawable:  the drawable on which to draw string
Packit 98cdb6
 * @gc:        base graphics context to use
Packit 98cdb6
 * @x:         the X position of the left of the layout (in pixels)
Packit 98cdb6
 * @y:         the Y position of the top of the layout (in pixels)
Packit 98cdb6
 * @layout:    a #PangoLayout
Packit 98cdb6
 * @foreground: (allow-none): foreground override color, or %NULL for none
Packit 98cdb6
 * @background: (allow-none): background override color, or %NULL for none
Packit 98cdb6
 *
Packit 98cdb6
 * Render a #PangoLayout onto a #GdkDrawable, overriding the
Packit 98cdb6
 * layout's normal colors with @foreground and/or @background.
Packit 98cdb6
 * @foreground and @background need not be allocated.
Packit 98cdb6
 *
Packit 98cdb6
 * If the layout's #PangoContext has a transformation matrix set, then
Packit 98cdb6
 * @x and @y specify the position of the top left corner of the
Packit 98cdb6
 * bounding box (in device space) of the transformed layout.
Packit 98cdb6
 *
Packit 98cdb6
 * If you're using GTK+, the ususal way to obtain a #PangoLayout
Packit 98cdb6
 * is gtk_widget_create_pango_layout().
Packit 98cdb6
 */
Packit 98cdb6
void 
Packit 98cdb6
gdk_draw_layout_with_colors (GdkDrawable     *drawable,
Packit 98cdb6
                             GdkGC           *gc,
Packit 98cdb6
                             int              x, 
Packit 98cdb6
                             int              y,
Packit 98cdb6
                             PangoLayout     *layout,
Packit 98cdb6
                             const GdkColor  *foreground,
Packit 98cdb6
                             const GdkColor  *background)
Packit 98cdb6
{
Packit 98cdb6
  PangoRenderer *renderer;
Packit 98cdb6
  const PangoMatrix *matrix;
Packit 98cdb6
  
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
  g_return_if_fail (GDK_IS_GC (gc));
Packit 98cdb6
  g_return_if_fail (PANGO_IS_LAYOUT (layout));
Packit 98cdb6
Packit 98cdb6
  renderer = get_renderer (drawable, gc, foreground, background);
Packit 98cdb6
Packit 98cdb6
  /* When we have a matrix, we do positioning by adjusting the matrix, and
Packit 98cdb6
   * clamp just pass x=0, y=0 to the lower levels. We don't want to introduce
Packit 98cdb6
   * a matrix when the caller didn't provide one, however, since that adds
Packit 98cdb6
   * lots of floating point arithmetic for each glyph.
Packit 98cdb6
   */
Packit 98cdb6
  matrix = pango_context_get_matrix (pango_layout_get_context (layout));
Packit 98cdb6
  if (matrix)
Packit 98cdb6
    {
Packit 98cdb6
      PangoMatrix tmp_matrix;
Packit 98cdb6
      PangoRectangle rect;
Packit 98cdb6
Packit 98cdb6
      pango_layout_get_extents (layout, NULL, &rect);
Packit 98cdb6
      pango_matrix_transform_rectangle (matrix, &rect);
Packit 98cdb6
      pango_extents_to_pixels (&rect, NULL);
Packit 98cdb6
      
Packit 98cdb6
      tmp_matrix = *matrix;
Packit 98cdb6
      tmp_matrix.x0 += x - rect.x;
Packit 98cdb6
      tmp_matrix.y0 += y - rect.y;
Packit 98cdb6
      pango_renderer_set_matrix (renderer, &tmp_matrix);
Packit 98cdb6
      
Packit 98cdb6
      x = 0;
Packit 98cdb6
      y = 0;
Packit 98cdb6
    }
Packit 98cdb6
  else if (GDK_PANGO_UNITS_OVERFLOWS (x, y))
Packit 98cdb6
    {
Packit 98cdb6
      PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
Packit 98cdb6
      tmp_matrix.x0 = x;
Packit 98cdb6
      tmp_matrix.y0 = y;
Packit 98cdb6
      pango_renderer_set_matrix (renderer, &tmp_matrix);
Packit 98cdb6
Packit 98cdb6
      x = 0;
Packit 98cdb6
      y = 0;
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    pango_renderer_set_matrix (renderer, NULL);
Packit 98cdb6
Packit 98cdb6
  pango_renderer_draw_layout (renderer, layout, x * PANGO_SCALE, y * PANGO_SCALE);
Packit 98cdb6
  
Packit 98cdb6
  release_renderer (renderer);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_draw_layout_line:
Packit 98cdb6
 * @drawable:  the drawable on which to draw the line
Packit 98cdb6
 * @gc:        base graphics to use
Packit 98cdb6
 * @x:         the x position of start of string (in pixels)
Packit 98cdb6
 * @y:         the y position of baseline (in pixels)
Packit 98cdb6
 * @line:      a #PangoLayoutLine
Packit 98cdb6
 *
Packit 98cdb6
 * Render a #PangoLayoutLine onto an GDK drawable
Packit 98cdb6
 *
Packit 98cdb6
 * If the layout's #PangoContext has a transformation matrix set, then
Packit 98cdb6
 * @x and @y specify the position of the left edge of the baseline
Packit 98cdb6
 * (left is in before-tranform user coordinates) in after-transform
Packit 98cdb6
 * device coordinates.
Packit 98cdb6
 */
Packit 98cdb6
void 
Packit 98cdb6
gdk_draw_layout_line (GdkDrawable      *drawable,
Packit 98cdb6
		      GdkGC            *gc,
Packit 98cdb6
		      gint              x, 
Packit 98cdb6
		      gint              y,
Packit 98cdb6
		      PangoLayoutLine  *line)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
  g_return_if_fail (GDK_IS_GC (gc));
Packit 98cdb6
  g_return_if_fail (line != NULL);
Packit 98cdb6
  
Packit 98cdb6
  gdk_draw_layout_line_with_colors (drawable, gc, x, y, line, NULL, NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_draw_layout:
Packit 98cdb6
 * @drawable:  the drawable on which to draw string
Packit 98cdb6
 * @gc:        base graphics context to use
Packit 98cdb6
 * @x:         the X position of the left of the layout (in pixels)
Packit 98cdb6
 * @y:         the Y position of the top of the layout (in pixels)
Packit 98cdb6
 * @layout:    a #PangoLayout
Packit 98cdb6
 *
Packit 98cdb6
 * Render a #PangoLayout onto a GDK drawable
Packit 98cdb6
 *
Packit 98cdb6
 * If the layout's #PangoContext has a transformation matrix set, then
Packit 98cdb6
 * @x and @y specify the position of the top left corner of the
Packit 98cdb6
 * bounding box (in device space) of the transformed layout.
Packit 98cdb6
 *
Packit 98cdb6
 * If you're using GTK+, the usual way to obtain a #PangoLayout
Packit 98cdb6
 * is gtk_widget_create_pango_layout().
Packit 98cdb6
 */
Packit 98cdb6
void 
Packit 98cdb6
gdk_draw_layout (GdkDrawable     *drawable,
Packit 98cdb6
		 GdkGC           *gc,
Packit 98cdb6
		 int              x, 
Packit 98cdb6
		 int              y,
Packit 98cdb6
		 PangoLayout     *layout)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
Packit 98cdb6
  g_return_if_fail (GDK_IS_GC (gc));
Packit 98cdb6
  g_return_if_fail (PANGO_IS_LAYOUT (layout));
Packit 98cdb6
Packit 98cdb6
  gdk_draw_layout_with_colors (drawable, gc, x, y, layout, NULL, NULL);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* GdkPangoAttrStipple */
Packit 98cdb6
Packit 98cdb6
static PangoAttribute *
Packit 98cdb6
gdk_pango_attr_stipple_copy (const PangoAttribute *attr)
Packit 98cdb6
{
Packit 98cdb6
  const GdkPangoAttrStipple *src = (const GdkPangoAttrStipple*) attr;
Packit 98cdb6
Packit 98cdb6
  return gdk_pango_attr_stipple_new (src->stipple);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_attr_stipple_destroy (PangoAttribute *attr)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoAttrStipple *st = (GdkPangoAttrStipple*) attr;
Packit 98cdb6
Packit 98cdb6
  if (st->stipple)
Packit 98cdb6
    g_object_unref (st->stipple);
Packit 98cdb6
  
Packit 98cdb6
  g_free (attr);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gdk_pango_attr_stipple_compare (const PangoAttribute *attr1,
Packit 98cdb6
                                    const PangoAttribute *attr2)
Packit 98cdb6
{
Packit 98cdb6
  const GdkPangoAttrStipple *a = (const GdkPangoAttrStipple*) attr1;
Packit 98cdb6
  const GdkPangoAttrStipple *b = (const GdkPangoAttrStipple*) attr2;
Packit 98cdb6
Packit 98cdb6
  return a->stipple == b->stipple;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_attr_stipple_new:
Packit 98cdb6
 * @stipple: a bitmap to be set as stipple
Packit 98cdb6
 *
Packit 98cdb6
 * Creates a new attribute containing a stipple bitmap to be used when
Packit 98cdb6
 * rendering the text.
Packit 98cdb6
 *
Packit 98cdb6
 * Return value: new #PangoAttribute
Packit 98cdb6
 **/
Packit 98cdb6
Packit 98cdb6
PangoAttribute *
Packit 98cdb6
gdk_pango_attr_stipple_new (GdkBitmap *stipple)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoAttrStipple *result;
Packit 98cdb6
  
Packit 98cdb6
  static PangoAttrClass klass = {
Packit 98cdb6
    0,
Packit 98cdb6
    gdk_pango_attr_stipple_copy,
Packit 98cdb6
    gdk_pango_attr_stipple_destroy,
Packit 98cdb6
    gdk_pango_attr_stipple_compare
Packit 98cdb6
  };
Packit 98cdb6
Packit 98cdb6
  if (!klass.type)
Packit 98cdb6
    klass.type = gdk_pango_attr_stipple_type =
Packit 98cdb6
      pango_attr_type_register ("GdkPangoAttrStipple");
Packit 98cdb6
Packit 98cdb6
  result = g_new (GdkPangoAttrStipple, 1);
Packit 98cdb6
  result->attr.klass = &klass;
Packit 98cdb6
Packit 98cdb6
  if (stipple)
Packit 98cdb6
    g_object_ref (stipple);
Packit 98cdb6
  
Packit 98cdb6
  result->stipple = stipple;
Packit 98cdb6
Packit 98cdb6
  return (PangoAttribute *)result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* GdkPangoAttrEmbossed */
Packit 98cdb6
Packit 98cdb6
static PangoAttribute *
Packit 98cdb6
gdk_pango_attr_embossed_copy (const PangoAttribute *attr)
Packit 98cdb6
{
Packit 98cdb6
  const GdkPangoAttrEmbossed *e = (const GdkPangoAttrEmbossed*) attr;
Packit 98cdb6
Packit 98cdb6
  return gdk_pango_attr_embossed_new (e->embossed);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_attr_embossed_destroy (PangoAttribute *attr)
Packit 98cdb6
{
Packit 98cdb6
  g_free (attr);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gdk_pango_attr_embossed_compare (const PangoAttribute *attr1,
Packit 98cdb6
                                 const PangoAttribute *attr2)
Packit 98cdb6
{
Packit 98cdb6
  const GdkPangoAttrEmbossed *e1 = (const GdkPangoAttrEmbossed*) attr1;
Packit 98cdb6
  const GdkPangoAttrEmbossed *e2 = (const GdkPangoAttrEmbossed*) attr2;
Packit 98cdb6
Packit 98cdb6
  return e1->embossed == e2->embossed;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_attr_embossed_new:
Packit 98cdb6
 * @embossed: if the region should be embossed
Packit 98cdb6
 *
Packit 98cdb6
 * Creates a new attribute flagging a region as embossed or not.
Packit 98cdb6
 *
Packit 98cdb6
 * Return value: new #PangoAttribute
Packit 98cdb6
 **/
Packit 98cdb6
Packit 98cdb6
PangoAttribute *
Packit 98cdb6
gdk_pango_attr_embossed_new (gboolean embossed)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoAttrEmbossed *result;
Packit 98cdb6
  
Packit 98cdb6
  static PangoAttrClass klass = {
Packit 98cdb6
    0,
Packit 98cdb6
    gdk_pango_attr_embossed_copy,
Packit 98cdb6
    gdk_pango_attr_embossed_destroy,
Packit 98cdb6
    gdk_pango_attr_embossed_compare
Packit 98cdb6
  };
Packit 98cdb6
Packit 98cdb6
  if (!klass.type)
Packit 98cdb6
    klass.type = gdk_pango_attr_embossed_type =
Packit 98cdb6
      pango_attr_type_register ("GdkPangoAttrEmbossed");
Packit 98cdb6
Packit 98cdb6
  result = g_new (GdkPangoAttrEmbossed, 1);
Packit 98cdb6
  result->attr.klass = &klass;
Packit 98cdb6
  result->embossed = embossed;
Packit 98cdb6
  
Packit 98cdb6
  return (PangoAttribute *)result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* GdkPangoAttrEmbossColor */
Packit 98cdb6
Packit 98cdb6
static PangoAttribute *
Packit 98cdb6
gdk_pango_attr_emboss_color_copy (const PangoAttribute *attr)
Packit 98cdb6
{
Packit 98cdb6
  const GdkPangoAttrEmbossColor *old = (const GdkPangoAttrEmbossColor*) attr;
Packit 98cdb6
  GdkPangoAttrEmbossColor *copy;
Packit 98cdb6
Packit 98cdb6
  copy = g_new (GdkPangoAttrEmbossColor, 1);
Packit 98cdb6
  copy->attr.klass = old->attr.klass;
Packit 98cdb6
  copy->color = old->color;
Packit 98cdb6
Packit 98cdb6
  return (PangoAttribute *) copy;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
gdk_pango_attr_emboss_color_destroy (PangoAttribute *attr)
Packit 98cdb6
{
Packit 98cdb6
  g_free (attr);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
gdk_pango_attr_emboss_color_compare (const PangoAttribute *attr1,
Packit 98cdb6
                                     const PangoAttribute *attr2)
Packit 98cdb6
{
Packit 98cdb6
  const GdkPangoAttrEmbossColor *c1 = (const GdkPangoAttrEmbossColor*) attr1;
Packit 98cdb6
  const GdkPangoAttrEmbossColor *c2 = (const GdkPangoAttrEmbossColor*) attr2;
Packit 98cdb6
Packit 98cdb6
  return color_equal (&c1->color, &c2->color);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_attr_emboss_color_new:
Packit 98cdb6
 * @color: a GdkColor representing the color to emboss with
Packit 98cdb6
 *
Packit 98cdb6
 * Creates a new attribute specifying the color to emboss text with.
Packit 98cdb6
 *
Packit 98cdb6
 * Return value: new #PangoAttribute
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.12
Packit 98cdb6
 **/
Packit 98cdb6
PangoAttribute *
Packit 98cdb6
gdk_pango_attr_emboss_color_new (const GdkColor *color)
Packit 98cdb6
{
Packit 98cdb6
  GdkPangoAttrEmbossColor *result;
Packit 98cdb6
  
Packit 98cdb6
  static PangoAttrClass klass = {
Packit 98cdb6
    0,
Packit 98cdb6
    gdk_pango_attr_emboss_color_copy,
Packit 98cdb6
    gdk_pango_attr_emboss_color_destroy,
Packit 98cdb6
    gdk_pango_attr_emboss_color_compare
Packit 98cdb6
  };
Packit 98cdb6
Packit 98cdb6
  if (!klass.type)
Packit 98cdb6
    klass.type = gdk_pango_attr_emboss_color_type =
Packit 98cdb6
      pango_attr_type_register ("GdkPangoAttrEmbossColor");
Packit 98cdb6
Packit 98cdb6
  result = g_new (GdkPangoAttrEmbossColor, 1);
Packit 98cdb6
  result->attr.klass = &klass;
Packit 98cdb6
  result->color.red = color->red;
Packit 98cdb6
  result->color.green = color->green;
Packit 98cdb6
  result->color.blue = color->blue;
Packit 98cdb6
Packit 98cdb6
  return (PangoAttribute *) result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/* Get a clip region to draw only part of a layout. index_ranges
Packit 98cdb6
 * contains alternating range starts/stops. The region is the
Packit 98cdb6
 * region which contains the given ranges, i.e. if you draw with the
Packit 98cdb6
 * region as clip, only the given ranges are drawn.
Packit 98cdb6
 */
Packit 98cdb6
static GdkRegion*
Packit 98cdb6
layout_iter_get_line_clip_region (PangoLayoutIter *iter,
Packit 98cdb6
				  gint             x_origin,
Packit 98cdb6
				  gint             y_origin,
Packit 98cdb6
				  const gint      *index_ranges,
Packit 98cdb6
				  gint             n_ranges)
Packit 98cdb6
{
Packit 98cdb6
  PangoLayoutLine *line;
Packit 98cdb6
  GdkRegion *clip_region;
Packit 98cdb6
  PangoRectangle logical_rect;
Packit 98cdb6
  gint baseline;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  line = pango_layout_iter_get_line_readonly (iter);
Packit 98cdb6
Packit 98cdb6
  clip_region = gdk_region_new ();
Packit 98cdb6
Packit 98cdb6
  pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
Packit 98cdb6
  baseline = pango_layout_iter_get_baseline (iter);
Packit 98cdb6
Packit 98cdb6
  i = 0;
Packit 98cdb6
  while (i < n_ranges)
Packit 98cdb6
    {  
Packit 98cdb6
      gint *pixel_ranges = NULL;
Packit 98cdb6
      gint n_pixel_ranges = 0;
Packit 98cdb6
      gint j;
Packit 98cdb6
Packit 98cdb6
      /* Note that get_x_ranges returns layout coordinates
Packit 98cdb6
       */
Packit 98cdb6
      if (index_ranges[i*2+1] >= line->start_index &&
Packit 98cdb6
	  index_ranges[i*2] < line->start_index + line->length)
Packit 98cdb6
	pango_layout_line_get_x_ranges (line,
Packit 98cdb6
					index_ranges[i*2],
Packit 98cdb6
					index_ranges[i*2+1],
Packit 98cdb6
					&pixel_ranges, &n_pixel_ranges);
Packit 98cdb6
  
Packit 98cdb6
      for (j = 0; j < n_pixel_ranges; j++)
Packit 98cdb6
        {
Packit 98cdb6
          GdkRectangle rect;
Packit 98cdb6
	  int x_off, y_off;
Packit 98cdb6
          
Packit 98cdb6
          x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x);
Packit 98cdb6
	  y_off = PANGO_PIXELS (baseline - logical_rect.y);
Packit 98cdb6
Packit 98cdb6
          rect.x = x_origin + x_off;
Packit 98cdb6
          rect.y = y_origin - y_off;
Packit 98cdb6
          rect.width = PANGO_PIXELS (pixel_ranges[2*j + 1] - logical_rect.x) - x_off;
Packit 98cdb6
          rect.height = PANGO_PIXELS (baseline - logical_rect.y + logical_rect.height) - y_off;
Packit 98cdb6
Packit 98cdb6
          gdk_region_union_with_rect (clip_region, &rect);
Packit 98cdb6
        }
Packit 98cdb6
Packit 98cdb6
      g_free (pixel_ranges);
Packit 98cdb6
      ++i;
Packit 98cdb6
    }
Packit 98cdb6
  return clip_region;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_layout_line_get_clip_region:
Packit 98cdb6
 * @line: a #PangoLayoutLine 
Packit 98cdb6
 * @x_origin: X pixel where you intend to draw the layout line with this clip
Packit 98cdb6
 * @y_origin: baseline pixel where you intend to draw the layout line with this clip
Packit 98cdb6
 * @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes
Packit 98cdb6
 * @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges
Packit 98cdb6
 * 
Packit 98cdb6
 * Obtains a clip region which contains the areas where the given
Packit 98cdb6
 * ranges of text would be drawn. @x_origin and @y_origin are the same
Packit 98cdb6
 * position you would pass to gdk_draw_layout_line(). @index_ranges
Packit 98cdb6
 * should contain ranges of bytes in the layout's text. The clip
Packit 98cdb6
 * region will include space to the left or right of the line (to the
Packit 98cdb6
 * layout bounding box) if you have indexes above or below the indexes
Packit 98cdb6
 * contained inside the line. This is to draw the selection all the way
Packit 98cdb6
 * to the side of the layout. However, the clip region is in line coordinates,
Packit 98cdb6
 * not layout coordinates.
Packit 98cdb6
 *
Packit 98cdb6
 * Note that the regions returned correspond to logical extents of the text
Packit 98cdb6
 * ranges, not ink extents. So the drawn line may in fact touch areas out of
Packit 98cdb6
 * the clip region.  The clip region is mainly useful for highlightling parts
Packit 98cdb6
 * of text, such as when text is selected.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a clip region containing the given ranges
Packit 98cdb6
 **/
Packit 98cdb6
GdkRegion*
Packit 98cdb6
gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
Packit 98cdb6
                                       gint             x_origin,
Packit 98cdb6
                                       gint             y_origin,
Packit 98cdb6
                                       const gint      *index_ranges,
Packit 98cdb6
                                       gint             n_ranges)
Packit 98cdb6
{
Packit 98cdb6
  GdkRegion *clip_region;
Packit 98cdb6
  PangoLayoutIter *iter;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (line != NULL, NULL);
Packit 98cdb6
  g_return_val_if_fail (index_ranges != NULL, NULL);
Packit 98cdb6
  
Packit 98cdb6
  iter = pango_layout_get_iter (line->layout);
Packit 98cdb6
  while (pango_layout_iter_get_line_readonly (iter) != line)
Packit 98cdb6
    pango_layout_iter_next_line (iter);
Packit 98cdb6
  
Packit 98cdb6
  clip_region = layout_iter_get_line_clip_region(iter, x_origin, y_origin, index_ranges, n_ranges);
Packit 98cdb6
Packit 98cdb6
  pango_layout_iter_free (iter);
Packit 98cdb6
Packit 98cdb6
  return clip_region;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_layout_get_clip_region:
Packit 98cdb6
 * @layout: a #PangoLayout 
Packit 98cdb6
 * @x_origin: X pixel where you intend to draw the layout with this clip
Packit 98cdb6
 * @y_origin: Y pixel where you intend to draw the layout with this clip
Packit 98cdb6
 * @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes
Packit 98cdb6
 * @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges
Packit 98cdb6
 * 
Packit 98cdb6
 * Obtains a clip region which contains the areas where the given ranges
Packit 98cdb6
 * of text would be drawn. @x_origin and @y_origin are the same position
Packit 98cdb6
 * you would pass to gdk_draw_layout_line(). @index_ranges should contain
Packit 98cdb6
 * ranges of bytes in the layout's text.
Packit 98cdb6
 * 
Packit 98cdb6
 * Note that the regions returned correspond to logical extents of the text
Packit 98cdb6
 * ranges, not ink extents. So the drawn layout may in fact touch areas out of
Packit 98cdb6
 * the clip region.  The clip region is mainly useful for highlightling parts
Packit 98cdb6
 * of text, such as when text is selected.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a clip region containing the given ranges
Packit 98cdb6
 **/
Packit 98cdb6
GdkRegion*
Packit 98cdb6
gdk_pango_layout_get_clip_region (PangoLayout *layout,
Packit 98cdb6
                                  gint         x_origin,
Packit 98cdb6
                                  gint         y_origin,
Packit 98cdb6
                                  const gint  *index_ranges,
Packit 98cdb6
                                  gint         n_ranges)
Packit 98cdb6
{
Packit 98cdb6
  PangoLayoutIter *iter;  
Packit 98cdb6
  GdkRegion *clip_region;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
Packit 98cdb6
  g_return_val_if_fail (index_ranges != NULL, NULL);
Packit 98cdb6
  
Packit 98cdb6
  clip_region = gdk_region_new ();
Packit 98cdb6
  
Packit 98cdb6
  iter = pango_layout_get_iter (layout);
Packit 98cdb6
  
Packit 98cdb6
  do
Packit 98cdb6
    {
Packit 98cdb6
      PangoRectangle logical_rect;
Packit 98cdb6
      GdkRegion *line_region;
Packit 98cdb6
      gint baseline;
Packit 98cdb6
      
Packit 98cdb6
      pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
Packit 98cdb6
      baseline = pango_layout_iter_get_baseline (iter);      
Packit 98cdb6
Packit 98cdb6
      line_region = layout_iter_get_line_clip_region(iter, 
Packit 98cdb6
						     x_origin + PANGO_PIXELS (logical_rect.x),
Packit 98cdb6
						     y_origin + PANGO_PIXELS (baseline),
Packit 98cdb6
						     index_ranges,
Packit 98cdb6
						     n_ranges);
Packit 98cdb6
Packit 98cdb6
      gdk_region_union (clip_region, line_region);
Packit 98cdb6
      gdk_region_destroy (line_region);
Packit 98cdb6
    }
Packit 98cdb6
  while (pango_layout_iter_next_line (iter));
Packit 98cdb6
Packit 98cdb6
  pango_layout_iter_free (iter);
Packit 98cdb6
Packit 98cdb6
  return clip_region;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_context_get:
Packit 98cdb6
 * 
Packit 98cdb6
 * Creates a #PangoContext for the default GDK screen.
Packit 98cdb6
 *
Packit 98cdb6
 * The context must be freed when you're finished with it.
Packit 98cdb6
 * 
Packit 98cdb6
 * When using GTK+, normally you should use gtk_widget_get_pango_context()
Packit 98cdb6
 * instead of this function, to get the appropriate context for
Packit 98cdb6
 * the widget you intend to render text onto.
Packit 98cdb6
 * 
Packit 98cdb6
 * The newly created context will have the default font options (see
Packit 98cdb6
 * #cairo_font_options_t) for the default screen; if these options
Packit 98cdb6
 * change it will not be updated. Using gtk_widget_get_pango_context()
Packit 98cdb6
 * is more convenient if you want to keep a context around and track
Packit 98cdb6
 * changes to the screen's font rendering settings.
Packit 98cdb6
 *
Packit 98cdb6
 * Return value: a new #PangoContext for the default display
Packit 98cdb6
 **/
Packit 98cdb6
PangoContext *
Packit 98cdb6
gdk_pango_context_get (void)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_pango_context_get_for_screen (gdk_screen_get_default ());
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_pango_context_get_for_screen:
Packit 98cdb6
 * @screen: the #GdkScreen for which the context is to be created.
Packit 98cdb6
 * 
Packit 98cdb6
 * Creates a #PangoContext for @screen.
Packit 98cdb6
 *
Packit 98cdb6
 * The context must be freed when you're finished with it.
Packit 98cdb6
 * 
Packit 98cdb6
 * When using GTK+, normally you should use gtk_widget_get_pango_context()
Packit 98cdb6
 * instead of this function, to get the appropriate context for
Packit 98cdb6
 * the widget you intend to render text onto.
Packit 98cdb6
 * 
Packit 98cdb6
 * The newly created context will have the default font options
Packit 98cdb6
 * (see #cairo_font_options_t) for the screen; if these options
Packit 98cdb6
 * change it will not be updated. Using gtk_widget_get_pango_context()
Packit 98cdb6
 * is more convenient if you want to keep a context around and track
Packit 98cdb6
 * changes to the screen's font rendering settings.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a new #PangoContext for @screen
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
PangoContext *
Packit 98cdb6
gdk_pango_context_get_for_screen (GdkScreen *screen)
Packit 98cdb6
{
Packit 98cdb6
  PangoFontMap *fontmap;
Packit 98cdb6
  PangoContext *context;
Packit 98cdb6
  const cairo_font_options_t *options;
Packit 98cdb6
  double dpi;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
Packit 98cdb6
Packit 98cdb6
  fontmap = pango_cairo_font_map_get_default ();
Packit 98cdb6
  context = pango_font_map_create_context (fontmap);
Packit 98cdb6
Packit 98cdb6
  options = gdk_screen_get_font_options (screen);
Packit 98cdb6
  pango_cairo_context_set_font_options (context, options);
Packit 98cdb6
Packit 98cdb6
  dpi = gdk_screen_get_resolution (screen);
Packit 98cdb6
  pango_cairo_context_set_resolution (context, dpi);
Packit 98cdb6
Packit 98cdb6
  return context;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_PANGO_C__
Packit 98cdb6
#include "gdkaliasdef.c"