⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pango-layout.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Pango * pango-layout.c: High-level layout driver * * Copyright (C) 2000, 2001, 2006 Red Hat Software * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library 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 <config.h>#include "pango-glyph.h"		/* For pango_shape() */#include "pango-break.h"#include "pango-item.h"#include "pango-engine.h"#include "pango-impl-utils.h"#include "pango-glyph-item-private.h"#include <string.h>#include "pango-layout-private.h"typedef struct _Extents Extents;typedef struct _ItemProperties ItemProperties;typedef struct _ParaBreakState ParaBreakState;struct _Extents{  /* Vertical position of the line's baseline in layout coords */  int baseline;  /* Line extents in layout coords */  PangoRectangle ink_rect;  PangoRectangle logical_rect;};struct _ItemProperties{  PangoUnderline  uline;  gboolean        strikethrough;  gint            rise;  gint            letter_spacing;  gboolean        shape_set;  PangoRectangle *shape_ink_rect;  PangoRectangle *shape_logical_rect;};struct _PangoLayoutIter{  PangoLayout *layout;  GSList *line_list_link;  PangoLayoutLine *line;  /* If run is NULL, it means we're on a "virtual run"   * at the end of the line with 0 width   */  GSList *run_list_link;  PangoLayoutRun *run; /* FIXME nuke this, just keep the link */  int index;  /* list of Extents for each line in layout coordinates */  GSList *line_extents;  GSList *line_extents_link;  /* X position of the current run */  int run_x;  /* Width of the current run */  int run_width;  /* this run is left-to-right */  gboolean ltr;  /* X position of the left side of the current cluster */  int cluster_x;  /* The width of the current cluster */  int cluster_width;  /* glyph offset to the current cluster start */  int cluster_start;  /* first glyph in the next cluster */  int next_cluster_glyph;  /* number of Unicode chars in current cluster */  int cluster_num_chars;  /* visual position of current character within the cluster */  int character_position;  /* the real width of layout */  int layout_width;};typedef struct _PangoLayoutLinePrivate PangoLayoutLinePrivate;struct _PangoLayoutLinePrivate{  PangoLayoutLine line;  guint ref_count;  /* Extents cache status:   *   * LEAKED means that the user has access to this line structure or a   * run included in this line, and so can change the glyphs/glyph-widths.   * If this is true, extents caching will be disabled.   */  enum {    NOT_CACHED,    CACHED,    LEAKED  } cache_status;  PangoRectangle ink_rect;  PangoRectangle logical_rect;};struct _PangoLayoutClass{  GObjectClass parent_class;};#define LINE_IS_VALID(line) ((line)->layout != NULL)#ifdef G_DISABLE_CHECKS#define ITER_IS_INVALID(iter) FALSE#else#define ITER_IS_INVALID(iter) G_UNLIKELY (check_invalid ((iter), G_STRLOC))static gbooleancheck_invalid (PangoLayoutIter *iter,	       const char      *loc){  if (iter->line->layout == NULL)    {      g_warning ("%s: PangoLayout changed since PangoLayoutIter was created, iterator invalid", loc);      return TRUE;    }  else    {      return FALSE;    }}#endifstatic void pango_layout_clear_lines (PangoLayout *layout);static void pango_layout_check_lines (PangoLayout *layout);static PangoAttrList *pango_layout_get_effective_attributes (PangoLayout *layout);static PangoLayoutLine * pango_layout_line_new         (PangoLayout     *layout);static void              pango_layout_line_postprocess (PangoLayoutLine *line,							ParaBreakState  *state,							gboolean         wrapped);static int *pango_layout_line_get_log2vis_map (PangoLayoutLine  *line,					       gboolean          strong);static int *pango_layout_line_get_vis2log_map (PangoLayoutLine  *line,					       gboolean          strong);static void pango_layout_line_leaked (PangoLayoutLine *line);/* doesn't leak line */static PangoLayoutLine* _pango_layout_iter_get_line (PangoLayoutIter *iter);static void pango_layout_get_item_properties (PangoItem      *item,					      ItemProperties *properties);static void pango_layout_get_empty_extents_at_index (PangoLayout    *layout,						     int             index,						     PangoRectangle *logical_rect);static void pango_layout_finalize    (GObject          *object);G_DEFINE_TYPE (PangoLayout, pango_layout, G_TYPE_OBJECT)static voidpango_layout_init (PangoLayout *layout){  layout->attrs = NULL;  layout->font_desc = NULL;  layout->text = NULL;  layout->length = 0;  layout->width = -1;  layout->height = -1;  layout->indent = 0;  layout->alignment = PANGO_ALIGN_LEFT;  layout->justify = FALSE;  layout->auto_dir = TRUE;  layout->log_attrs = NULL;  layout->lines = NULL;  layout->tab_width = -1;  layout->unknown_glyphs_count = -1;  layout->wrap = PANGO_WRAP_WORD;  layout->is_wrapped = FALSE;  layout->ellipsize = PANGO_ELLIPSIZE_NONE;  layout->is_ellipsized = FALSE;}static voidpango_layout_class_init (PangoLayoutClass *klass){  GObjectClass *object_class = G_OBJECT_CLASS (klass);  object_class->finalize = pango_layout_finalize;}static voidpango_layout_finalize (GObject *object){  PangoLayout *layout;  layout = PANGO_LAYOUT (object);  pango_layout_clear_lines (layout);  if (layout->context)    g_object_unref (layout->context);  if (layout->attrs)    pango_attr_list_unref (layout->attrs);  g_free (layout->text);  if (layout->font_desc)    pango_font_description_free (layout->font_desc);  if (layout->tabs)    pango_tab_array_free (layout->tabs);  G_OBJECT_CLASS (pango_layout_parent_class)->finalize (object);}/** * pango_layout_new: * @context: a #PangoContext * * Create a new #PangoLayout object with attributes initialized to * default values for a particular #PangoContext. * * Return value: the newly allocated #PangoLayout, with a reference *               count of one, which should be freed with *               g_object_unref(). **/PangoLayout *pango_layout_new (PangoContext *context){  PangoLayout *layout;  g_return_val_if_fail (context != NULL, NULL);  layout = g_object_new (PANGO_TYPE_LAYOUT, NULL);  layout->context = context;  g_object_ref (context);  return layout;}/** * pango_layout_copy: * @src: a #PangoLayout * * Does a deep copy-by-value of the @src layout. The attribute list, * tab array, and text from the original layout are all copied by * value. * * Return value: the newly allocated #PangoLayout, with a reference *               count of one, which should be freed with *               g_object_unref(). **/PangoLayout*pango_layout_copy (PangoLayout *src){  PangoLayout *layout;  g_return_val_if_fail (PANGO_IS_LAYOUT (src), NULL);  layout = pango_layout_new (src->context);  if (src->attrs)    layout->attrs = pango_attr_list_copy (src->attrs);  if (src->font_desc)    layout->font_desc = pango_font_description_copy (src->font_desc);  layout->text = g_strdup (src->text);  layout->length = src->length;  layout->width = src->width;  layout->height = src->height;  layout->indent = src->indent;  layout->spacing = src->spacing;  layout->justify = src->justify;  layout->auto_dir = src->auto_dir;  layout->alignment = src->alignment;  layout->n_chars = src->n_chars;  layout->tab_width = src->tab_width;  if (src->tabs)    layout->tabs = pango_tab_array_copy (src->tabs);  layout->wrap = src->wrap;  layout->ellipsize = src->ellipsize;  layout->unknown_glyphs_count = -1;  /* unknown_glyphs_count, is_wrapped, is_ellipsized, log_attrs, lines   * fields are updated by check_lines */  return layout;}/** * pango_layout_get_context: * @layout: a #PangoLayout * * Retrieves the #PangoContext used for this layout. * * Return value: the #PangoContext for the layout. This does not * have an additional refcount added, so if you want to keep * a copy of this around, you must reference it yourself. **/PangoContext *pango_layout_get_context (PangoLayout *layout){  g_return_val_if_fail (layout != NULL, NULL);  return layout->context;}/** * pango_layout_set_width: * @layout: a #PangoLayout. * @width: the desired width in Pango units, or -1 to indicate that no *         wrapping or ellipsization should be performed. * * Sets the width to which the lines of the #PangoLayout should wrap or * ellipsized.  The default value is -1: no width set. **/voidpango_layout_set_width (PangoLayout *layout,			int          width){  g_return_if_fail (layout != NULL);  if (width != layout->width)    {      layout->width = width;      pango_layout_clear_lines (layout);    }}/** * pango_layout_get_width: * @layout: a #PangoLayout * * Gets the width to which the lines of the #PangoLayout should wrap. * * Return value: the width in Pango units, or -1 if no width set. **/intpango_layout_get_width (PangoLayout    *layout){  g_return_val_if_fail (layout != NULL, 0);  return layout->width;}/** * pango_layout_set_height: * @layout: a #PangoLayout. * @height: the desired height of the layout in Pango units if positive, *          or desired number of lines if negative. * * Sets the height to which the #PangoLayout should be ellipsized at.  There * are two different behaviors, based on whether @height is positive or * negative. * * If @height is positive, it will be the maximum height of the layout.  Only * lines would be shown that would fit, and if there is any text omitted, * an ellipsis added.  At least one line is included in each paragraph regardless * of how small the height value is.  A value of zero will render exactly one * line for the entire layout. * * If @height is negative, it will be the (negative of) maximum number of lines per * paragraph.  That is, the total number of lines shown may well be more than * this value if the layout contains multiple paragraphs of text. * The default value of -1 means that first line of each paragraph is ellipsized. * This behvaior may be changed in the future to act per layout instead of per * paragraph.  File a bug against pango at <ulink * url="http://bugzilla.gnome.org/">http://bugzilla.gnome.org/</ulink> if your * code relies on this behavior. * * Height setting only has effect if a positive width is set on * @layout and ellipsization mode of @layout is not %PANGO_ELLIPSIZE_NONE. * The behavior is undefined if a height other than -1 is set and * ellipsization mode is set to %PANGO_ELLIPSIZE_NONE, and may change in the * future. * * Since: 1.20 **/voidpango_layout_set_height (PangoLayout *layout,			 int          height){  g_return_if_fail (layout != NULL);  if (height != layout->height)    {      layout->height = height;      if (layout->ellipsize != PANGO_ELLIPSIZE_NONE)	pango_layout_clear_lines (layout);    }}/** * pango_layout_get_height: * @layout: a #PangoLayout * * Gets the height of layout used for ellipsization.  See * pango_layout_set_height() for details. * * Return value: the height, in Pango units if positive, or * number of lines if negative. * * Since: 1.20 **/intpango_layout_get_height (PangoLayout    *layout){  g_return_val_if_fail (layout != NULL, 0);  return layout->height;}/** * pango_layout_set_wrap: * @layout: a #PangoLayout * @wrap: the wrap mode * * Sets the wrap mode; the wrap mode only has effect if a width * is set on the layout with pango_layout_set_width(). * To turn off wrapping, set the width to -1. **/voidpango_layout_set_wrap (PangoLayout  *layout,		       PangoWrapMode wrap){  g_return_if_fail (PANGO_IS_LAYOUT (layout));  if (layout->wrap != wrap)    {      layout->wrap = wrap;      if (layout->is_wrapped)	pango_layout_clear_lines (layout);    }}/** * pango_layout_get_wrap: * @layout: a #PangoLayout * * Gets the wrap mode for the layout. * * Use pango_layout_is_wrapped() to query whether any paragraphs * were actually wrapped. * * Return value: active wrap mode. **/PangoWrapModepango_layout_get_wrap (PangoLayout *layout){  g_return_val_if_fail (PANGO_IS_LAYOUT (layout), 0);  return layout->wrap;}/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -