Beispiel #1
0
static uint32_t
text_entry_try_invoke_preedit_action(struct text_entry *entry,
				     int32_t x, int32_t y,
				     uint32_t button,
				     enum wl_pointer_button_state state)
{
	int index, trailing;
	uint32_t cursor;
	const char *text;

	if (!entry->preedit.text)
		return 0;

	pango_layout_xy_to_index(entry->layout,
				 x * PANGO_SCALE, y * PANGO_SCALE,
				 &index, &trailing);

	text = pango_layout_get_text(entry->layout);
	cursor = g_utf8_offset_to_pointer(text + index, trailing) - text;

	if (cursor < entry->cursor ||
	    cursor > entry->cursor + strlen(entry->preedit.text)) {
		return 0;
	}

	if (state == WL_POINTER_BUTTON_STATE_RELEASED)
		wl_text_input_invoke_action(entry->text_input,
					    button,
					    cursor - entry->cursor);

	return 1;
}
Beispiel #2
0
std::string ttext::get_token(const gui2::tpoint & position, const char * delim) const
{
	recalculate();

	// Get the index of the character.
	int index, trailing;
	if (!pango_layout_xy_to_index(layout_, position.x * PANGO_SCALE,
		position.y * PANGO_SCALE, &index, &trailing)) {
		return "";
	}

	std::string txt = pango_layout_get_text(layout_);

	std::string d(delim);

	if (index < 0 || (static_cast<size_t>(index) >= txt.size()) || d.find(txt.at(index)) != std::string::npos) {
		return ""; // if the index is out of bounds, or the index character is a delimiter, return nothing
	}

	size_t l = index;
	while (l > 0 && (d.find(txt.at(l-1)) == std::string::npos)) {
		--l;
	}

	size_t r = index + 1;
	while (r < txt.size() && (d.find(txt.at(r)) == std::string::npos)) {
		++r;
	}

	return txt.substr(l,r-l);
}
Beispiel #3
0
gui2::tpoint ttext::get_column_line(const gui2::tpoint& position) const
{
	recalculate();

	// Get the index of the character.
	int index, trailing;
	pango_layout_xy_to_index(layout_, position.x * PANGO_SCALE,
		position.y * PANGO_SCALE, &index, &trailing);

	// Extract the line and the offset in pixels in that line.
	int line, offset;
	pango_layout_index_to_line_x(layout_, index, trailing, &line, &offset);
	offset = PANGO_PIXELS(offset);

	// Now convert this offset to a column, this way is a bit hacky but haven't
	// found a better solution yet.

	/**
	 * @todo There's still a bug left. When you select a text which is in the
	 * ellipses on the right side the text gets reformatted with ellipses on
	 * the left and the selected character is not the one under the cursor.
	 * Other widget toolkits don't show ellipses and have no indication more
	 * text is available. Haven't found what the best thing to do would be.
	 * Until that time leave it as is.
	 */
	for(size_t i = 0; ; ++i) {
		const int pos = get_cursor_position(i, line).x;

		if(pos == offset) {
			return  gui2::tpoint(i, line);
		}
	}
}
static int
get_layout_index (MateIconTextItem *iti, int x, int y)
{
    int index;
    int trailing;
    const char *cluster;
    const char *cluster_end;

    MateIconTextItemPrivate *priv;
    PangoRectangle extents;

    trailing = 0;
    index = 0;
    priv = iti->_priv;

    pango_layout_get_extents (priv->layout, NULL, &extents);

    x = (x * PANGO_SCALE) + extents.x;
    y = (y * PANGO_SCALE) + extents.y;

    pango_layout_xy_to_index (priv->layout, x, y, &index, &trailing);

    cluster = gtk_entry_get_text (GTK_ENTRY (priv->entry)) + index;
    cluster_end = cluster;
    while (trailing) {
        cluster_end = g_utf8_next_char (cluster_end);
        --trailing;
    }
    index += (cluster_end - cluster);

    return index;
}
Beispiel #5
0
/* Given an x-y position, return the paragraph and offset
 * within the paragraph of the click.
 */
gboolean
xy_to_cp (int width, int x, int y, Paragraph **para_return, int *index)
{
  GList *para_list;
  int height = 0;

  *para_return = NULL;

  para_list = paragraphs;
  while (para_list && height < y)
    {
      Paragraph *para = para_list->data;
      
      if (height + para->height >= y)
	{
	  gboolean result = pango_layout_xy_to_index (para->layout,
						      x * PANGO_SCALE,
						      (y - height) * PANGO_SCALE, 
						      index, NULL);
	  if (result && para_return)
	    *para_return = para;

	  return result;
	}
      
      height += para->height;
      para_list = para_list->next;
    }

  return FALSE;
}
Beispiel #6
0
static void
gimp_text_tool_xy_to_iter (GimpTextTool *text_tool,
                           gdouble       x,
                           gdouble       y,
                           GtkTextIter  *iter)
{
  PangoLayout *layout;
  gint         offset_x;
  gint         offset_y;
  gint         index;
  gint         trailing;

  gimp_text_tool_ensure_layout (text_tool);

  gimp_text_layout_untransform_point (text_tool->layout, &x, &y);

  gimp_text_layout_get_offsets (text_tool->layout, &offset_x, &offset_y);
  x -= offset_x;
  y -= offset_y;

  layout = gimp_text_layout_get_pango_layout (text_tool->layout);

  pango_layout_xy_to_index (layout,
                            x * PANGO_SCALE,
                            y * PANGO_SCALE,
                            &index, &trailing);

  gimp_text_buffer_get_iter_at_index (text_tool->buffer, iter, index, TRUE);

  if (trailing)
    gtk_text_iter_forward_char (iter);
}
Beispiel #7
0
int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const
{
#if USE(FREETYPE)
    if (!primaryFont()->platformData().m_pattern)
        return offsetForPositionForSimpleText(run, xFloat, includePartialGlyphs);
#endif
    // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers
    // to Font::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem.
    int x = static_cast<int>(xFloat);

    PangoLayout* layout = getDefaultPangoLayout(run);
    setPangoAttributes(this, run, layout);

    gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length());
    pango_layout_set_text(layout, utf8, -1);

    int index, trailing;
    pango_layout_xy_to_index(layout, x * PANGO_SCALE, 1, &index, &trailing);
    glong offset = g_utf8_pointer_to_offset(utf8, utf8 + index);
    if (includePartialGlyphs)
        offset += trailing;

    g_free(utf8);
    g_object_unref(layout);

    return offset;
}
Beispiel #8
0
/**
 * Find the position in a string where an x coordinate falls.
 *
 * \param[in] fstyle style for this text
 * \param[in] string UTF-8 string to measure
 * \param[in] length length of string, in bytes
 * \param[in] x coordinate to search for
 * \param[out] char_offset updated to offset in string of actual_x, [0..length]
 * \param[out] actual_x updated to x coordinate of character closest to x
 * \return NSERROR_OK and char_offset and actual_x updated or appropriate
 *          error code on faliure
 */
static nserror
nsfont_position_in_string(const plot_font_style_t *fstyle,
			  const char *string,
			  size_t length,
			  int x,
			  size_t *char_offset,
			  int *actual_x)
{
	int index;
	PangoFontDescription *desc;
	PangoRectangle pos;

	nsfont_pango_check();

	desc = nsfont_style_to_description(fstyle);
	pango_layout_set_font_description(nsfont_pango_layout, desc);
	pango_font_description_free(desc);

	pango_layout_set_text(nsfont_pango_layout, string, length);

	if (pango_layout_xy_to_index(nsfont_pango_layout,
				     x * PANGO_SCALE, 
				     0, &index, 0) == FALSE) {
		index = length;
	}

	pango_layout_index_to_pos(nsfont_pango_layout, index, &pos);

	*char_offset = index;
	*actual_x = PANGO_PIXELS(pos.x);

	return NSERROR_OK;
}
Beispiel #9
0
static gint
gtk_label_accessible_get_offset_at_point (AtkText      *atk_text,
                                          gint          x,
                                          gint          y,
                                          AtkCoordType  coords)
{
  GtkWidget *widget;
  GtkLabel *label;
  const gchar *text;
  gint index, x_layout, y_layout;
  gint x_window, y_window;
  gint x_local, y_local;
  GdkWindow *window;

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
  if (widget == NULL)
    return -1;

  label = GTK_LABEL (widget);

  gtk_label_get_layout_offsets (label, &x_layout, &y_layout);

  window = gtk_widget_get_window (widget);
  gdk_window_get_origin (window, &x_window, &y_window);

  x_local = x - x_layout - x_window;
  y_local = y - y_layout - y_window;

  if (coords == ATK_XY_WINDOW)
    {
      window = gdk_window_get_toplevel (window);
      gdk_window_get_origin (window, &x_window, &y_window);

      x_local += x_window;
      y_local += y_window;
    }

  if (!pango_layout_xy_to_index (gtk_label_get_layout (label),
                                 x_local * PANGO_SCALE,
                                 y_local * PANGO_SCALE,
                                 &index, NULL))
    {
      if (x_local < 0 || y_local < 0)
        index = 0;
      else
        index = -1;
    }

  if (index != -1)
    {
      text = gtk_label_get_text (label);
      return g_utf8_pointer_to_offset (text, text + index);
    }

  return -1;
}
Beispiel #10
0
static VALUE
rg_xy_to_index(VALUE self, VALUE x, VALUE y)
{
    int index, trailing;
    gboolean ret = pango_layout_xy_to_index(_SELF(self), 
                                            NUM2INT(x), NUM2INT(y), 
                                            &index, &trailing);

    return rb_ary_new3(3, CBOOL2RVAL(ret), INT2NUM(index), INT2NUM(trailing));
}
Beispiel #11
0
static gint
gtk_icon_view_item_accessible_get_offset_at_point (AtkText      *text,
                                                   gint          x,
                                                   gint          y,
                                                   AtkCoordType coord_type)
{
  GtkIconViewItemAccessible *item;
  gint offset = 0;
#if 0
  GtkIconView *icon_view;
  const gchar *item_text;
  gint index;
  gint l_x, l_y;
#endif

  item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (text);

  if (!GTK_IS_ICON_VIEW (item->widget))
    return -1;

  if (atk_state_set_contains_state (item->state_set, ATK_STATE_DEFUNCT))
    return -1;

#if 0
  icon_view = GTK_ICON_VIEW (item->widget);
      /* FIXME we probably have to use GailTextCell to salvage this */
  gtk_icon_view_update_item_text (icon_view, item->item);
  atk_component_get_position (ATK_COMPONENT (text), &l_x, &l_y, coord_type);
  x -= l_x + item->item->layout_x - item->item->x;
  x +=  ((item->item->width - item->item->layout_width) / 2) + (MAX (item->item->pixbuf_width, icon_view->priv->item_width) - item->item->width) / 2,
  y -= l_y + item->item->layout_y - item->item->y;
  item_text = pango_layout_get_text (icon_view->priv->layout);
  if (!pango_layout_xy_to_index (icon_view->priv->layout, 
                                x * PANGO_SCALE,
                                y * PANGO_SCALE,
                                &index, NULL))
    {
      if (x < 0 || y < 0)
        index = 0;
      else
        index = -1;
    } 
  if (index == -1)
    offset = g_utf8_strlen (item_text, -1);
  else
    offset = g_utf8_pointer_to_offset (item_text, item_text + index);
#endif
  return offset;
}
Beispiel #12
0
int Font::offsetForPositionForComplexText(const TextRun& run, const TextStyle& style, int x, bool includePartialGlyphs) const
{
    PangoLayout* layout = getDefaultPangoLayout(run);
    setPangoAttributes(this, run, layout, style.rtl());

    gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length());
    pango_layout_set_text(layout, utf8, -1);

    int index, trailing;
    pango_layout_xy_to_index(layout, x * PANGO_SCALE, 1, &index, &trailing);
    glong offset = g_utf8_pointer_to_offset(utf8, utf8 + index);
    g_object_unref(layout);
    g_free(utf8);

    return offset;
}
Beispiel #13
0
static int 
_get_string_index (GtkEntry *entry, 
                   gint      x, 
                   gint      y)
{
    //Declarations
    int layout_index;
    int entry_index;
    int trailing;
    PangoLayout *layout;

    //Initalizations
    layout = gtk_entry_get_layout (GTK_ENTRY (entry));
    if (pango_layout_xy_to_index (layout, x * PANGO_SCALE, y * PANGO_SCALE, &layout_index, &trailing))
      entry_index = gtk_entry_layout_index_to_text_index (GTK_ENTRY (entry), layout_index);
    else
      entry_index = -1;

    return entry_index;
}
Beispiel #14
0
static void
text_entry_set_anchor_position(struct text_entry *entry,
			       int32_t x, int32_t y)
{
	int index, trailing;
	const char *text;

	pango_layout_xy_to_index(entry->layout,
				 x * PANGO_SCALE, y * PANGO_SCALE,
				 &index, &trailing);

	text = pango_layout_get_text(entry->layout);
	entry->anchor = g_utf8_offset_to_pointer(text + index, trailing) - text;

	text_entry_update_layout(entry);

	widget_schedule_redraw(entry->widget);

	text_entry_update(entry);
}
Beispiel #15
0
/**
 * gail_misc_get_index_at_point_in_layout:
 * @widget: A #GtkWidget
 * @layout: The #PangoLayout from which to get the index at the
 *   specified point.
 * @x_layout: The x-offset at which the widget displays the
 *   #PangoLayout, relative to @widget
 * @y_layout: The y-offset at which the widget displays the
 *   #PangoLayout, relative to @widget
 * @x: The x-coordinate relative to @coords at which to
 *   calculate the index
 * @y: The y-coordinate relative to @coords at which to
 *   calculate the index
 * @coords: An #AtkCoordType enumeration
 *
 * Gets the byte offset at the specified @x and @y in a #PangoLayout.
 *
 * Returns: the byte offset at the specified @x and @y in a
 *   #PangoLayout
 **/
gint
gail_misc_get_index_at_point_in_layout (GtkWidget   *widget,
                                        PangoLayout *layout,
                                        gint        x_layout,
                                        gint        y_layout,
                                        gint        x,
                                        gint        y,
                                        AtkCoordType coords)
{
  gint index, x_window, y_window, x_toplevel, y_toplevel;
  gint x_temp, y_temp;
  gboolean ret;

  gail_misc_get_origins (widget, &x_window, &y_window, 
                         &x_toplevel, &y_toplevel);
  x_temp =  x - x_layout - x_window;
  y_temp =  y - y_layout - y_window;
  if (coords == ATK_XY_WINDOW)
    {
      x_temp += x_toplevel;  
      y_temp += y_toplevel;
    }
  else if (coords != ATK_XY_SCREEN)
    return -1;

  ret = pango_layout_xy_to_index (layout, 
                                  x_temp * PANGO_SCALE,
                                  y_temp * PANGO_SCALE,
                                  &index, NULL);
  if (!ret)
    {
      if (x_temp < 0 || y_temp < 0)
        index = 0;
      else
        index = -1; 
    }
  return index;
}
Beispiel #16
0
static void
text_entry_set_cursor_position(struct text_entry *entry,
			       int32_t x, int32_t y,
			       bool move_anchor)
{
	int index, trailing;
	const char *text;
	uint32_t cursor;

	pango_layout_xy_to_index(entry->layout,
				 x * PANGO_SCALE, y * PANGO_SCALE,
				 &index, &trailing);

	text = pango_layout_get_text(entry->layout);

	cursor = g_utf8_offset_to_pointer(text + index, trailing) - text;

	if (move_anchor)
		entry->anchor = cursor;

	if (text_entry_has_preedit(entry)) {
		text_entry_commit_and_reset(entry);

		assert(!text_entry_has_preedit(entry));
	}

	if (entry->cursor == cursor)
		return;

	entry->cursor = cursor;

	text_entry_update_layout(entry);

	widget_schedule_redraw(entry->widget);

	text_entry_update(entry);
}
static gint
gtk_text_cell_accessible_get_offset_at_point (AtkText      *text,
                                              gint          x,
                                              gint          y,
                                              AtkCoordType  coords)
{
  AtkObject *parent;
  GtkRendererCellAccessible *gail_renderer;
  GtkCellRendererText *gtk_renderer;
  GtkRequisition min_size;
  GtkWidget *widget;
  GdkRectangle rendered_rect;
  PangoLayout *layout;
  gchar *renderer_text;
  gfloat xalign, yalign;
  gint x_offset, y_offset, index;
  gint xpad, ypad;
  gint x_window, y_window, x_toplevel, y_toplevel;
  gint x_temp, y_temp;
  gboolean ret;

  if (!GTK_TEXT_CELL_ACCESSIBLE (text)->cell_text)
    return -1;

  gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text);
  gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer);
  parent = atk_object_get_parent (ATK_OBJECT (text));

  g_object_get (gtk_renderer, "text", &renderer_text, NULL);
  if (text == NULL)
    {
      g_free (renderer_text);
      return -1;
    }

  if (GTK_IS_CONTAINER_CELL_ACCESSIBLE (parent))
    parent = atk_object_get_parent (parent);

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent));

  g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent), -1);
  _gtk_cell_accessible_parent_get_cell_area (GTK_CELL_ACCESSIBLE_PARENT (parent),
                                             GTK_CELL_ACCESSIBLE (text),
                                             &rendered_rect);

  gtk_cell_renderer_get_preferred_size (GTK_CELL_RENDERER (gtk_renderer),
                                        widget,
                                        &min_size, NULL);
  gtk_cell_renderer_get_alignment (GTK_CELL_RENDERER (gtk_renderer), &xalign, &yalign);
  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
    xalign = 1.0 - xalign;
  x_offset = MAX (0, xalign * (rendered_rect.width - min_size.width));
  y_offset = MAX (0, yalign * (rendered_rect.height - min_size.height));

  layout = create_pango_layout (GTK_TEXT_CELL_ACCESSIBLE (text));

  gtk_cell_renderer_get_padding (gail_renderer->renderer, &xpad, &ypad);

  get_origins (widget, &x_window, &y_window, &x_toplevel, &y_toplevel);

  x_temp =  x - (x_offset + rendered_rect.x + xpad) - x_window;
  y_temp =  y - (y_offset + rendered_rect.y + ypad) - y_window;
  if (coords == ATK_XY_WINDOW)
    {
      x_temp += x_toplevel;
      y_temp += y_toplevel;
    }
  else if (coords != ATK_XY_SCREEN)
    index = -1;

  ret = pango_layout_xy_to_index (layout,
                                  x_temp * PANGO_SCALE,
                                  y_temp * PANGO_SCALE,
                                  &index, NULL);
  if (!ret)
    {
      if (x_temp < 0 || y_temp < 0)
        index = 0;
      else
        index = -1;
    }

  g_object_unref (layout);
  if (index == -1)
    {
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
        {
          glong length;

          length = g_utf8_strlen (renderer_text, -1);
          g_free (renderer_text);

          return length;
        }

      g_free (renderer_text);

      return index;
    }
  else
    {
      glong offset;

      offset = g_utf8_pointer_to_offset (renderer_text,
                                         renderer_text + index);
      g_free (renderer_text);

      return offset;
    }
}
Beispiel #18
0
/* split a text buffer into chunks using the passed Pango layout */
GList *
split_for_layout(PangoLayout * layout, const gchar * text,
		 PangoAttrList * attributes, BalsaPrintSetup * psetup,
		 gboolean is_header, GArray ** offsets)
{
    GList *split_list = NULL;
    PangoLayoutIter *iter;
    const gchar *start;
    gint p_offset;
    gboolean add_tab;
    gint p_y0;
    gint p_y1;
    gint p_y_pos;
    gint p_height;

    /* set the text and its attributes, then get an iter */
    pango_layout_set_text(layout, text, -1);
    if (attributes)
	pango_layout_set_attributes(layout, attributes);
    if (offsets)
	*offsets = g_array_new(FALSE, FALSE, sizeof(guint));
    iter = pango_layout_get_iter(layout);

    /* loop over lines */
    start = text;
    p_offset = 0;
    add_tab = FALSE;
    p_y_pos = C_TO_P(psetup->c_y_pos);
    p_height = C_TO_P(psetup->c_height);
    do {
	pango_layout_iter_get_line_yrange(iter, &p_y0, &p_y1);
	if (p_y_pos + p_y1 - p_offset > p_height) {
	    gint index;
	    gint tr;
	    gchar *chunk;
	    gboolean ends_with_nl;

	    if (offsets) {
		guint offs = start - text;

		*offsets = g_array_append_val(*offsets, offs);
	    }
	    pango_layout_xy_to_index(layout, 0, p_y0, &index, &tr);
	    ends_with_nl = text[index - 1] == '\n';
	    if (ends_with_nl)
		index--;
	    chunk = g_strndup(start, text + index - start);
	    if (add_tab)
		split_list =
		    g_list_append(split_list,
				  g_strconcat("\t", chunk, NULL));
	    else
		split_list = g_list_append(split_list, g_strdup(chunk));
	    add_tab = is_header && !ends_with_nl;
	    g_free(chunk);
	    start = text + index;
	    if (ends_with_nl)
		start++;
	    if (*start == '\0')
		p_y_pos = p_height;
	    else {
		p_y_pos = 0;
		psetup->page_count++;
	    }
	    p_offset = p_y0;
	}
    } while (pango_layout_iter_next_line(iter));
    pango_layout_iter_free(iter);

    /* append any remaining stuff */
    if (*start != '\0') {
	p_y_pos += p_y1 - p_offset;
	if (offsets) {
	    guint offs = start - text;

	    *offsets = g_array_append_val(*offsets, offs);
	}
	if (add_tab)
	    split_list =
		g_list_append(split_list, g_strconcat("\t", start, NULL));
	else
	    split_list = g_list_append(split_list, g_strdup(start));
    }

    /* remember the new y position in cairo units */
    psetup->c_y_pos = P_TO_C(p_y_pos);

    /* return the list */
    return split_list;
}