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

📄 pango-layout.c

📁 linux
💻 C
📖 第 1 页 / 共 5 页
字号:
      prev_dir = run_dir;      tmp_list = tmp_list->next;    }  /* And the last visual position   */  if ((cursor_dir == line->resolved_dir) || (prev_dir == line->resolved_dir))    result[pos] = line->resolved_dir == PANGO_DIRECTION_LTR ? end - start : 0;  return result;}static int *pango_layout_line_get_log2vis_map (PangoLayoutLine *line,				   gboolean         strong){  gchar *start, *end;  int *reverse_map;  int *result;  int i;  int n_chars;  pango_layout_line_get_range (line, &start, &end);  n_chars = g_utf8_strlen (start, end - start);  result = g_new0 (int, end - start + 1);  reverse_map = pango_layout_line_get_vis2log_map (line, strong);  for (i=0; i <= n_chars; i++)    result[reverse_map[i]] = i;  g_free (reverse_map);  return result;}static PangoDirectionpango_layout_line_get_char_direction (PangoLayoutLine *layout_line,				      int              index){  GSList *run_list;  run_list = layout_line->runs;  while (run_list)    {      PangoLayoutRun *run = run_list->data;      if (run->item->offset <= index && run->item->offset + run->item->length > index)	return run->item->analysis.level % 2 ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;      run_list = run_list->next;    }  g_assert_not_reached ();  return PANGO_DIRECTION_LTR;}/** * pango_layout_get_cursor_pos: * @layout: a #PangoLayout * @index_: the byte index of the cursor * @strong_pos: location to store the strong cursor position (may be %NULL) * @weak_pos: location to store the weak cursor position (may be %NULL) * * Given an index within a layout, determines the positions that of the * strong and weak cursors if the insertion point is at that * index. The position of each cursor is stored as a zero-width * rectangle. The strong cursor location is the location where * characters of the directionality equal to the base direction of the * layout are inserted.  The weak cursor location is the location * where characters of the directionality opposite to the base * direction of the layout are inserted. **/voidpango_layout_get_cursor_pos (PangoLayout    *layout,			     int             index,			     PangoRectangle *strong_pos,			     PangoRectangle *weak_pos){  PangoDirection dir1;  PangoRectangle line_rect;  PangoLayoutLine *layout_line = NULL; /* Quiet GCC */  int x1_trailing;  int x2;  g_return_if_fail (layout != NULL);  g_return_if_fail (index >= 0 && index <= layout->length);  layout_line = pango_layout_index_to_line_and_extents (layout, index,							&line_rect);  g_assert (index >= layout_line->start_index);  /* Examine the trailing edge of the character before the cursor */  if (index == layout_line->start_index)    {      dir1 = layout_line->resolved_dir;      if (layout_line->resolved_dir == PANGO_DIRECTION_LTR)	x1_trailing = 0;      else	x1_trailing = line_rect.width;    }  else    {      gint prev_index = g_utf8_prev_char (layout->text + index) - layout->text;      dir1 = pango_layout_line_get_char_direction (layout_line, prev_index);      pango_layout_line_index_to_x (layout_line, prev_index, TRUE, &x1_trailing);    }  /* Examine the leading edge of the character after the cursor */  if (index >= layout_line->start_index + layout_line->length)    {      if (layout_line->resolved_dir == PANGO_DIRECTION_LTR)	x2 = line_rect.width;      else	x2 = 0;    }  else    {      pango_layout_line_index_to_x (layout_line, index, FALSE, &x2);    }  if (strong_pos)    {      strong_pos->x = line_rect.x;      if (dir1 == layout_line->resolved_dir)	strong_pos->x += x1_trailing;      else	strong_pos->x += x2;      strong_pos->y = line_rect.y;      strong_pos->width = 0;      strong_pos->height = line_rect.height;    }  if (weak_pos)    {      weak_pos->x = line_rect.x;      if (dir1 == layout_line->resolved_dir)	weak_pos->x += x2;      else	weak_pos->x += x1_trailing;      weak_pos->y = line_rect.y;      weak_pos->width = 0;      weak_pos->height = line_rect.height;    }}static inline intdirection_simple (PangoDirection d){  switch (d)    {    case PANGO_DIRECTION_LTR :    case PANGO_DIRECTION_WEAK_LTR :    case PANGO_DIRECTION_TTB_RTL :      return 1;    case PANGO_DIRECTION_RTL :    case PANGO_DIRECTION_WEAK_RTL :    case PANGO_DIRECTION_TTB_LTR :      return -1;    case PANGO_DIRECTION_NEUTRAL :      return 0;    /* no default, compiler should complain if a new values is added */    }  /* not reached */  return 0;}static PangoAlignmentget_alignment (PangoLayout     *layout,	       PangoLayoutLine *line){  PangoAlignment alignment = layout->alignment;  if (alignment != PANGO_ALIGN_CENTER && line->layout->auto_dir &&      direction_simple (line->resolved_dir) ==      -direction_simple (pango_context_get_base_dir (layout->context)))    {      if (alignment == PANGO_ALIGN_LEFT)	alignment = PANGO_ALIGN_RIGHT;      else if (alignment == PANGO_ALIGN_RIGHT)	alignment = PANGO_ALIGN_LEFT;    }  return alignment;}static voidget_x_offset (PangoLayout     *layout,	      PangoLayoutLine *line,	      int              layout_width,	      int              line_width,	      int             *x_offset){  PangoAlignment alignment = get_alignment (layout, line);  /* Alignment */  if (alignment == PANGO_ALIGN_RIGHT)    *x_offset = layout_width - line_width;  else if (alignment == PANGO_ALIGN_CENTER)    *x_offset = (layout_width - line_width) / 2;  else    *x_offset = 0;  /* Indentation */  /* For center, we ignore indentation; I think I've seen word   * processors that still do the indentation here as if it were   * indented left/right, though we can't sensibly do that without   * knowing whether left/right is the "normal" thing for this text   */  if (alignment == PANGO_ALIGN_CENTER)    return;  if (line->is_paragraph_start)    {      if (layout->indent > 0)	{	  if (alignment == PANGO_ALIGN_LEFT)	    *x_offset += layout->indent;	  else	    *x_offset -= layout->indent;	}    }  else    {      if (layout->indent < 0)	{	  if (alignment == PANGO_ALIGN_LEFT)	    *x_offset -= layout->indent;	  else	    *x_offset += layout->indent;	}    }}static voidget_line_extents_layout_coords (PangoLayout     *layout,				PangoLayoutLine *line,				int              layout_width,				int              y_offset,				int             *baseline,				PangoRectangle  *line_ink_layout,				PangoRectangle  *line_logical_layout){  int x_offset;  /* Line extents in line coords (origin at line baseline) */  PangoRectangle line_ink;  PangoRectangle line_logical;  pango_layout_line_get_extents (line, line_ink_layout ? &line_ink : NULL,				 &line_logical);  get_x_offset (layout, line, layout_width, line_logical.width, &x_offset);  /* Convert the line's extents into layout coordinates */  if (line_ink_layout)    {      *line_ink_layout = line_ink;      line_ink_layout->x = line_ink.x + x_offset;      line_ink_layout->y = y_offset - line_logical.y + line_ink.y;    }  if (line_logical_layout)    {      *line_logical_layout = line_logical;      line_logical_layout->x = line_logical.x + x_offset;      line_logical_layout->y = y_offset;    }  if (baseline)    *baseline = y_offset - line_logical.y;}/* if non-NULL line_extents returns a list of line extents * in layout coordinates */static voidpango_layout_get_extents_internal (PangoLayout    *layout,				   PangoRectangle *ink_rect,				   PangoRectangle *logical_rect,				   GSList        **line_extents){  GSList *line_list;  int y_offset = 0;  int width;  gboolean need_width = FALSE;  g_return_if_fail (layout != NULL);  if (ink_rect && layout->ink_rect_cached)    {      *ink_rect = layout->ink_rect;      ink_rect = NULL;    }  if (logical_rect && layout->logical_rect_cached)    {      *logical_rect = layout->logical_rect;      logical_rect = NULL;    }  if (!ink_rect && !logical_rect && !line_extents)    return;  pango_layout_check_lines (layout);  /* When we are not wrapping, we need the overall width of the layout to   * figure out the x_offsets of each line. However, we only need the   * x_offsets if we are computing the ink_rect or individual line extents.   */  width = layout->width;  if (layout->auto_dir)    {      /* If one of the lines of the layout is not left aligned, then we need       * the width of the layout to calculate line x-offsets; this requires       * looping through the lines for layout->auto_dir.       */      line_list = layout->lines;      while (line_list && !need_width)	{	  PangoLayoutLine *line = line_list->data;	  if (get_alignment (layout, line) != PANGO_ALIGN_LEFT)	    need_width = TRUE;	  line_list = line_list->next;	}    }  else if (layout->alignment != PANGO_ALIGN_LEFT)    need_width = TRUE;  if (width == -1 && need_width && (ink_rect || line_extents))    {      PangoRectangle overall_logical;      pango_layout_get_extents_internal (layout, NULL, &overall_logical, NULL);      width = overall_logical.width;    }  if (logical_rect)    {      logical_rect->x = 0;      logical_rect->y = 0;      logical_rect->width = 0;      logical_rect->height = 0;    }  line_list = layout->lines;  while (line_list)    {      PangoLayoutLine *line = line_list->data;      /* Line extents in layout coords (origin at 0,0 of the layout) */      PangoRectangle line_ink_layout;      PangoRectangle line_logical_layout;      int new_pos;      /* This block gets the line extents in layout coords */      {	int baseline;	get_line_extents_layout_coords (layout, line,					width, y_offset,					&baseline,					ink_rect ? &line_ink_layout : NULL,					&line_logical_layout);	if (line_extents)	  {	    Extents *ext = g_slice_new (Extents);	    ext->baseline = baseline;	    ext->ink_rect = line_ink_layout;	    ext->logical_rect = line_logical_layout;	    *line_extents = g_slist_prepend (*line_extents, ext);	  }      }      if (ink_rect)	{	  /* Compute the union of the current ink_rect with	   * line_ink_layout	   */	  if (line_list == layout->lines)	    {	      *ink_rect = line_ink_layout;	    }	  else	    {	      new_pos = MIN (ink_rect->x, line_ink_layout.x);	      ink_rect->width =		MAX (ink_rect->x + ink_rect->width,		     line_ink_layout.x + line_ink_layout.width) - new_pos;	      ink_rect->x = new_pos;	      new_pos = MIN (ink_rect->y, line_ink_layout.y);	      ink_rect->height =		MAX (ink_rect->y + ink_rect->height,		     line_ink_layout.y + line_ink_layout.height) - new_pos;	      ink_rect->y = new_pos;	    }	}      if (logical_rect)	{	  if (layout->width == -1)	    {	      /* When no width is set on layout, we can just compute the max of the	       * line lengths to get the horizontal extents ... logical_rect.x = 0.	       */	      logical_rect->width = MAX (logical_rect->width, line_logical_layout.width);	    }	  else	    {	      /* When a width is set, we have to compute the union of the horizontal	       * extents of all the lines.	       */	      if (line_list == layout->lines)		{		  logical_rect->x = line_logical_layout.x;		  logical_rect->width = line_logical_layout.width;		}	      else		{		  new_pos = MIN (logical_rect->x, line_logical_layout.x);		  logical_rect->width =		    MAX (logical_rect->x + logical_rect->width,			 line_logical_layout.x + line_logical_layout.width) - new_pos;		  logical_rect->x = new_pos;		}	    }	  logical_rect->height += line_logical_layout.height;	  /* No space after the last line, of course. */	  if (line_list->next != NULL)	    logical_rect->height += layout->spacing;	}      y_offset += line_logical_layout.height + layout->spacing;      line_list = line_list->next;    }  if (ink_rect)    {      layout->ink_rect = *ink_rect;      layout->ink_rect_cached = TRUE;    }  if (logical_rect)    {      layout->logical_rect = *logical_rect;      layout->logical_rect_cached = TRUE;    }  if (line_extents)    *line_extents = g_slist_reverse (*line_extents);}/** * pango_layout_get_extents: * @layout:   a #PangoLayout * @ink_rect: rectangle used to store the extents of the layout as drawn *            or %NULL to indicate that the result is not needed. * @logical_rect: rectangle used to store the logical extents of the layout		 or %NULL to indicate that the result is not needed. * * Computes the logical and ink extents of @layout. Logical extents * are usually what you want for positioning things.  Note that both extents * may have non-zero x and y.  You may want to use those to offset where you * render the layout.  Not doing that is a very typical bug that shows up as * right-to-left layouts not being correctly positioned in a layout with * a set width. * * The extents are given in layout coordinates and in Pango units; layout * coordinates begin at the top left corner of the layout. */voidpango_layout_get_extents (PangoLayout    *layout,			  PangoRectangle *ink_rect,			  PangoRectangle *logical_rect){  g_return_if_fail (layout != NULL);  pango_layout_get_extents_internal (layout, ink_rect, logical_rect, NULL);}/** * pango_layout_get_pixel_extents: * @layout:   a #PangoLayout 

⌨️ 快捷键说明

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