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

📄 pango-layout.c

📁 linux
💻 C
📖 第 1 页 / 共 5 页
字号:
 */voidpango_layout_index_to_line_x (PangoLayout *layout,			      int          index,			      gboolean     trailing,			      int         *line,			      int         *x_pos){  int line_num;  PangoLayoutLine *layout_line = NULL;  g_return_if_fail (layout != NULL);  g_return_if_fail (index >= 0);  g_return_if_fail (index <= layout->length);  pango_layout_check_lines (layout);  layout_line = pango_layout_index_to_line (layout, index,					    &line_num, NULL, NULL);  if (layout_line)    {      /* use end of line if index was in the paragraph delimiters */      if (index > layout_line->start_index + layout_line->length)	index = layout_line->start_index + layout_line->length;      if (line)	*line = line_num;      pango_layout_line_index_to_x (layout_line, index, trailing, x_pos);    }  else    {      if (line)	*line = -1;      if (x_pos)	*x_pos = -1;    }}/** * pango_layout_move_cursor_visually: * @layout:       a #PangoLayout. * @strong:       whether the moving cursor is the strong cursor or the *                weak cursor. The strong cursor is the cursor corresponding *                to text insertion in the base direction for the layout. * @old_index:    the byte index of the grapheme for the old index * @old_trailing: if 0, the cursor was at the trailing edge of the *                grapheme indicated by @old_index, if > 0, the cursor *                was at the leading edge. * @direction:    direction to move cursor. A negative *                value indicates motion to the left. * @new_index:    location to store the new cursor byte index. A value of -1 *                indicates that the cursor has been moved off the beginning *                of the layout. A value of %G_MAXINT indicates that *                the cursor has been moved off the end of the layout. * @new_trailing: number of characters to move forward from the location returned *                for @new_index to get the position where the cursor should *                be displayed. This allows distinguishing the position at *                the beginning of one line from the position at the end *                of the preceding line. @new_index is always on the line *                where the cursor should be displayed. * * Computes a new cursor position from an old position and * a count of positions to move visually. If @direction is positive, * then the new strong cursor position will be one position * to the right of the old cursor position. If @direction is negative, * then the new strong cursor position will be one position * to the left of the old cursor position. * * In the presence of bidirectional text, the correspondence * between logical and visual order will depend on the direction * of the current run, and there may be jumps when the cursor * is moved off of the end of a run. * * Motion here is in cursor positions, not in characters, so a * single call to pango_layout_move_cursor_visually() may move the * cursor over multiple characters when multiple characters combine * to form a single grapheme. **/voidpango_layout_move_cursor_visually (PangoLayout *layout,				   gboolean     strong,				   int          old_index,				   int          old_trailing,				   int          direction,				   int         *new_index,				   int         *new_trailing){  PangoLayoutLine *line = NULL;  PangoLayoutLine *prev_line;  PangoLayoutLine *next_line;  int *log2vis_map;  int *vis2log_map;  int n_vis;  int vis_pos, vis_pos_old, log_pos;  int start_offset;  gboolean off_start = FALSE;  gboolean off_end = FALSE;  g_return_if_fail (layout != NULL);  g_return_if_fail (old_index >= 0 && old_index <= layout->length);  g_return_if_fail (old_index < layout->length || old_trailing == 0);  g_return_if_fail (new_index != NULL);  g_return_if_fail (new_trailing != NULL);  direction = (direction >= 0 ? 1 : -1);  pango_layout_check_lines (layout);  /* Find the line the old cursor is on */  line = pango_layout_index_to_line (layout, old_index,				     NULL, &prev_line, &next_line);  start_offset = g_utf8_pointer_to_offset (layout->text, layout->text + line->start_index);  while (old_trailing--)    old_index = g_utf8_next_char (layout->text + old_index) - layout->text;  log2vis_map = pango_layout_line_get_log2vis_map (line, strong);  n_vis = g_utf8_strlen (layout->text + line->start_index, line->length);  /* Clamp old_index to fit on the line */  if (old_index > (line->start_index + line->length))    old_index = line->start_index + line->length;  vis_pos = log2vis_map[old_index - line->start_index];  g_free (log2vis_map);  /* Handling movement between lines */  if (vis_pos == 0 && direction < 0)    {      if (line->resolved_dir == PANGO_DIRECTION_LTR)	off_start = TRUE;      else	off_end = TRUE;    }  else if (vis_pos == n_vis && direction > 0)    {      if (line->resolved_dir == PANGO_DIRECTION_LTR)	off_end = TRUE;      else	off_start = TRUE;    }  if (off_start || off_end)    {      /* If we move over a paragraph boundary, count that as       * an extra position in the motion       */      gboolean paragraph_boundary;      if (off_start)	{	  if (!prev_line)	    {	      *new_index = -1;	      *new_trailing = 0;	      return;	    }	  line = prev_line;	  paragraph_boundary = (line->start_index + line->length != old_index);	}      else	{	  if (!next_line)	    {	      *new_index = G_MAXINT;	      *new_trailing = 0;	      return;	    }	  line = next_line;	  paragraph_boundary = (line->start_index != old_index);	}      n_vis = g_utf8_strlen (layout->text + line->start_index, line->length);      start_offset = g_utf8_pointer_to_offset (layout->text, layout->text + line->start_index);      if (vis_pos == 0 && direction < 0)	{	  vis_pos = n_vis;	  if (paragraph_boundary)	    vis_pos++;	}      else /* (vis_pos == n_vis && direction > 0) */	{	  vis_pos = 0;	  if (paragraph_boundary)	    vis_pos--;	}    }  vis2log_map = pango_layout_line_get_vis2log_map (line, strong);  vis_pos_old = vis_pos + direction;  log_pos = g_utf8_pointer_to_offset (layout->text + line->start_index,				      layout->text + line->start_index + vis2log_map[vis_pos_old]);  do    {      vis_pos += direction;      log_pos += g_utf8_pointer_to_offset (layout->text + line->start_index + vis2log_map[vis_pos_old],					   layout->text + line->start_index + vis2log_map[vis_pos]);      vis_pos_old = vis_pos;    }  while (vis_pos > 0 && vis_pos < n_vis &&	 !layout->log_attrs[start_offset + log_pos].is_cursor_position);  *new_index = line->start_index + vis2log_map[vis_pos];  g_free (vis2log_map);  *new_trailing = 0;  if (*new_index == line->start_index + line->length && line->length > 0)    {      do	{	  log_pos--;	  *new_index = g_utf8_prev_char (layout->text + *new_index) - layout->text;	  (*new_trailing)++;	}      while (log_pos > 0 && !layout->log_attrs[start_offset + log_pos].is_cursor_position);    }}/** * pango_layout_xy_to_index: * @layout:    a #PangoLayout * @x:         the X offset (in #PangoGlyphUnit) *             from the left edge of the layout. * @y:         the Y offset (in #PangoGlyphUnit) *             from the top edge of the layout * @index_:    location to store calculated byte index * @trailing:  location to store a integer indicating where *             in the grapheme the user clicked. It will either *             be zero, or the number of characters in the *             grapheme. 0 represents the trailing edge of the grapheme. * * Converts from X and Y position within a layout to the byte * index to the character at that logical position. If the * Y position is not inside the layout, the closest position is chosen * (the position will be clamped inside the layout). If the * X position is not within the layout, then the start or the * end of the line is chosen as  described for pango_layout_x_to_index(). * If either the X or Y positions were not inside the layout, then the * function returns %FALSE; on an exact hit, it returns %TRUE. * * Return value: %TRUE if the coordinates were inside text, %FALSE otherwise. **/gbooleanpango_layout_xy_to_index (PangoLayout *layout,			  int          x,			  int          y,			  int         *index,			  gint        *trailing){  PangoLayoutIter *iter;  PangoLayoutLine *prev_line = NULL;  PangoLayoutLine *found = NULL;  int found_line_x = 0;  int prev_last = 0;  int prev_line_x = 0;  gboolean retval = FALSE;  gboolean outside = FALSE;  g_return_val_if_fail (PANGO_IS_LAYOUT (layout), FALSE);  iter = pango_layout_get_iter (layout);  do    {      PangoRectangle line_logical;      int first_y, last_y;      pango_layout_iter_get_line_extents (iter, NULL, &line_logical);      pango_layout_iter_get_line_yrange (iter, &first_y, &last_y);      if (y < first_y)	{	  if (prev_line && y < (prev_last + (first_y - prev_last) / 2))	    {	      found = prev_line;	      found_line_x = prev_line_x;	    }	  else	    {	      if (prev_line == NULL)		outside = TRUE; /* off the top */	      found = _pango_layout_iter_get_line (iter);	      found_line_x = x - line_logical.x;	    }	}      else if (y >= first_y &&	       y < last_y)	{	  found = _pango_layout_iter_get_line (iter);	  found_line_x = x - line_logical.x;	}      prev_line = _pango_layout_iter_get_line (iter);      prev_last = last_y;      prev_line_x = x - line_logical.x;      if (found != NULL)	break;    }  while (pango_layout_iter_next_line (iter));  pango_layout_iter_free (iter);  if (found == NULL)    {      /* Off the bottom of the layout */      outside = TRUE;      found = prev_line;      found_line_x = prev_line_x;    }  retval = pango_layout_line_x_to_index (found,					 found_line_x,					 index, trailing);  if (outside)    retval = FALSE;  return retval;}/** * pango_layout_index_to_pos: * @layout: a #PangoLayout * @index_: byte index within @layout * @pos: rectangle in which to store the position of the grapheme * * Converts from an index within a #PangoLayout to the onscreen position * corresponding to the grapheme at that index, which is represented * as rectangle.  Note that <literal>pos->x</literal> is always the leading * edge of the grapheme and <literal>pos->x + pos->width</literal> the trailing * edge of the grapheme. If the directionality of the grapheme is right-to-left, * then <literal>pos->width</literal> will be negative. **/voidpango_layout_index_to_pos (PangoLayout    *layout,			   int             index,			   PangoRectangle *pos){  PangoRectangle logical_rect;  PangoLayoutIter *iter;  PangoLayoutLine *layout_line = NULL;  int x_pos;  g_return_if_fail (layout != NULL);  g_return_if_fail (index >= 0);  g_return_if_fail (pos != NULL);  iter = pango_layout_get_iter (layout);  if (!ITER_IS_INVALID (iter))    {      while (TRUE)	{	  PangoLayoutLine *tmp_line = _pango_layout_iter_get_line (iter);	  if (tmp_line->start_index > index)	    {	      /* index is in the paragraph delimiters, move to	       * end of previous line	       */	      index = layout_line->start_index + layout_line->length;	      break;	    }	  layout_line = tmp_line;	  pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);	  if (layout_line->start_index + layout_line->length > index)	    break;	  if (!pango_layout_iter_next_line (iter))	    {	      index = layout_line->start_index + layout_line->length;	      break;	    }	}      pos->y = logical_rect.y;      pos->height = logical_rect.height;      pango_layout_line_index_to_x (layout_line, index, 0, &x_pos);      pos->x = logical_rect.x + x_pos;      if (index < layout_line->start_index + layout_line->length)	{	  pango_layout_line_index_to_x (layout_line, index, 1, &x_pos);	  pos->width = (logical_rect.x + x_pos) - pos->x;	}      else	pos->width = 0;    }  pango_layout_iter_free (iter);}static voidpango_layout_line_get_range (PangoLayoutLine *line,			     char           **start,			     char           **end){  char *p;  p = line->layout->text + line->start_index;  if (start)    *start = p;  if (end)    *end = p + line->length;}static int *pango_layout_line_get_vis2log_map (PangoLayoutLine *line,				   gboolean         strong){  PangoLayout *layout = line->layout;  PangoDirection prev_dir;  PangoDirection cursor_dir;  GSList *tmp_list;  gchar *start, *end;  int *result;  int pos;  int n_chars;  pango_layout_line_get_range (line, &start, &end);  n_chars = g_utf8_strlen (start, end - start);  result = g_new (int, n_chars + 1);  if (strong)    cursor_dir = line->resolved_dir;  else    cursor_dir = (line->resolved_dir == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;  /* Handle the first visual position   */  if (line->resolved_dir == cursor_dir)    result[0] = line->resolved_dir == PANGO_DIRECTION_LTR ? 0 : end - start;  prev_dir = line->resolved_dir;  pos = 0;  tmp_list = line->runs;  while (tmp_list)    {      PangoLayoutRun *run = tmp_list->data;      int run_n_chars = run->item->num_chars;      PangoDirection run_dir = (run->item->analysis.level % 2) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;      char *p = layout->text + run->item->offset;      int i;      /* pos is the visual position at the start of the run */      /* p is the logical byte index at the start of the run */      if (run_dir == PANGO_DIRECTION_LTR)	{	  if ((cursor_dir == PANGO_DIRECTION_LTR) ||	      (prev_dir == run_dir))	    result[pos] = p - start;	  p = g_utf8_next_char (p);	  for (i = 1; i < run_n_chars; i++)	    {	      result[pos + i] = p - start;	      p = g_utf8_next_char (p);	    }	  if (cursor_dir == PANGO_DIRECTION_LTR)	    result[pos + run_n_chars] = p - start;	}      else	{	  if (cursor_dir == PANGO_DIRECTION_RTL)	    result[pos + run_n_chars] = p - start;	  p = g_utf8_next_char (p);	  for (i = 1; i < run_n_chars; i++)	    {	      result[pos + run_n_chars - i] = p - start;	      p = g_utf8_next_char (p);	    }	  if ((cursor_dir == PANGO_DIRECTION_RTL) ||	      (prev_dir == run_dir))	    result[pos] = p - start;	}      pos += run_n_chars;

⌨️ 快捷键说明

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