示例#1
0
文件: text.c 项目: polarcat/yad
static void
linkify_cb (GtkTextBuffer *buf, GRegex *regex)
{
  gchar *text;
  GtkTextIter start, end;
  GMatchInfo *match;

  gtk_text_buffer_get_bounds (buf, &start, &end);
  text = gtk_text_buffer_get_text (buf, &start, &end, FALSE);

  gtk_text_buffer_remove_all_tags (buf, &start, &end);

  if (g_regex_match (regex, text, G_REGEX_MATCH_NOTEMPTY, &match))
    {
      do
	{
	  gint sp, ep, spos, epos;

	  g_match_info_fetch_pos (match, 0, &sp, &ep);

	  /* positions are in bytes, not character, so here we must normalize it*/
	  spos = g_utf8_pointer_to_offset (text, text + sp);
	  epos = g_utf8_pointer_to_offset (text, text + ep);

	  gtk_text_buffer_get_iter_at_offset (buf, &start, spos);
	  gtk_text_buffer_get_iter_at_offset (buf, &end, epos);

	  gtk_text_buffer_apply_tag (buf, tag, &start, &end);
	}
      while (g_match_info_next (match, NULL));
    }
  g_match_info_free (match);

  g_free(text);
}
示例#2
0
static gboolean
complete_suggest(GntEntry *entry, const char *text)
{
	int offstart = 0, offend = 0;

	if (entry->word) {
		char *s = get_beginning_of_word(entry);
		const char *iter = text;
		offstart = g_utf8_pointer_to_offset(entry->start, s);
		while (*iter && toupper(*s) == toupper(*iter)) {
			*s++ = *iter++;
		}
		if (*iter) {
			gnt_entry_key_pressed(GNT_WIDGET(entry), iter);
		}
		offend = g_utf8_pointer_to_offset(entry->start, entry->cursor);
	} else {
		offstart = 0;
		gnt_entry_set_text_internal(entry, text);
		offend = g_utf8_strlen(text, -1);
	}

	g_signal_emit(G_OBJECT(entry), signals[SIG_COMPLETION], 0,
			entry->start + offstart, entry->start + offend);
	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
	return TRUE;
}
示例#3
0
void
_gtk_source_regex_fetch_named_pos (GtkSourceRegex *regex,
				   const gchar    *text,
				   const gchar    *name,
				   gint           *start_pos, /* character offsets */
				   gint           *end_pos)   /* character offsets */
{
	gint byte_start_pos, byte_end_pos;

	g_assert (regex->resolved);

	if (!g_match_info_fetch_named_pos (regex->u.regex.match, name, &byte_start_pos, &byte_end_pos))
	{
		if (start_pos != NULL)
			*start_pos = -1;
		if (end_pos != NULL)
			*end_pos = -1;
	}
	else
	{
		if (start_pos != NULL)
			*start_pos = g_utf8_pointer_to_offset (text, text + byte_start_pos);
		if (end_pos != NULL)
			*end_pos = g_utf8_pointer_to_offset (text, text + byte_end_pos);
	}
}
示例#4
0
文件: text.c 项目: polarcat/yad
/* searching */
static void 
do_search (GtkWidget *e, GtkWidget *w)
{
  static gchar *text = NULL;
  static guint offset;
  static GRegex *regex = NULL;
  GMatchInfo *match = NULL;
  GtkTextIter begin, end;

  g_free (pattern);
  pattern = g_strdup (gtk_entry_get_text (GTK_ENTRY (e)));
  gtk_widget_destroy (w);
  gtk_widget_queue_draw (text_view);

  if (new_search || gtk_text_buffer_get_modified (text_buffer))
    {
      /* get the text */
      g_free (text);
      gtk_text_buffer_get_bounds (text_buffer, &begin, &end);
      text = gtk_text_buffer_get_text (text_buffer, &begin, &end, FALSE);
      offset = 0;
      /* compile new regex */
      if (regex)
	g_regex_unref (regex);
      regex = g_regex_new (pattern, G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, NULL);
      new_search = FALSE;
    }

  /* search and select if found */
  if (g_regex_match (regex, text + offset, G_REGEX_MATCH_NOTEMPTY, &match))
    {
      gint sp, ep, spos, epos;

      g_match_info_fetch_pos (match, 0, &sp, &ep);

      /* positions are in bytes, not character, so here we must normalize it*/
      spos = g_utf8_pointer_to_offset (text, text + sp + offset);
      epos = g_utf8_pointer_to_offset (text, text + ep + offset);

      gtk_text_buffer_get_iter_at_offset (text_buffer, &begin, spos);
      gtk_text_buffer_get_iter_at_offset (text_buffer, &end, epos);

      gtk_text_buffer_select_range (text_buffer, &begin, &end);
      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text_view), &begin, 0, FALSE, 0, 0);

      offset += epos;
      
      g_match_info_free (match);
      match = NULL;
    }
  else
    new_search = TRUE;
}
示例#5
0
/* Splits a line into a set of (word,word_position) tuples. */
static GSList *
tokenize_line (GString * line)
{
	GSList * tokens = NULL;
	char *utf = (char *) line->str;

	GString * word;
	
	gunichar uc;
	size_t cur_pos = 0;
	size_t start_pos = 0;
	word = g_string_new (NULL);

	while (cur_pos < line->len && *utf) {
		int i;

	        /* Skip non-word characters. */
		cur_pos = g_utf8_pointer_to_offset ((const char*)line->str, utf);
		uc = g_utf8_get_char (utf);
		while (cur_pos < line->len && *utf && !is_word_char(uc,0)) {
		        utf = g_utf8_next_char (utf);
			uc = g_utf8_get_char (utf);
			cur_pos = g_utf8_pointer_to_offset ((const char*)line->str, utf);
		}
		start_pos = cur_pos;

		/* Skip over word. */
		while (cur_pos < line->len && *utf && is_word_char(uc,1)) {
			g_string_append_unichar (word, uc);
		        utf = g_utf8_next_char (utf);
			uc = g_utf8_get_char (utf);
			cur_pos = g_utf8_pointer_to_offset ((const char*)line->str, utf);
		}

	        /* Do not accept one or more  ' at the end of the word. */
		i = word->len-1;
	        while ((i >= 0) && (word->str[i] == '\'')) {
	                g_string_truncate (word, i);
			i--;
		}

		/* Save (word, position) tuple. */
                if (word->len) {
		        tokens = g_slist_append (tokens, g_string_new_len (word->str, word->len));
			tokens = g_slist_append (tokens, GINT_TO_POINTER(start_pos));
			g_string_truncate (word, 0);
		}
	}
	g_string_free (word, TRUE);

	return tokens;
}
示例#6
0
/**
 * utf8_byteoffset_to_charsoffset_cached:
 * @string: the gchar * you want to count
 * @byteoffset: glong with the byteoffset you want the charoffset for
 * 
 * this function calculates the UTF-8 character offset in a string for
 * a given byte offset
 * It uses caching to speedup multiple calls for the same buffer, the cache
 * is emptied if you change to another buffer. If you use the same buffer but 
 * change it inbetween calls, you have to reset it yourself using
 * the utf8_offset_cache_reset() function
 *
 **** the result is undefined if the provided byteoffset is in the middle of a UTF8 character ***
 * 
 * Return value: guint with character offset
 **/
guint utf8_byteoffset_to_charsoffset_cached(gchar *string, glong byteoffset) {
	guint retval;
	gint i = UTF8_OFFSET_CACHE_SIZE-1;
	if (byteoffset ==0) return 0;

	if (string != utf8_offset_cache.last_buf) {
		utf8_offset_cache_reset();
		utf8_offset_cache.last_buf = string;
	}
#ifdef DEBUG
	DEBUG_MSG("utf8_byteoffset_to_charsoffset_cached, string %p has strlen %d, looking for byteoffset %ld, starting in cache at i=%d\n", string, strlen(string),byteoffset,i);
#endif

	while (i > 0 && utf8_offset_cache.last_byteoffset[i] > byteoffset) {
		i--;
	}
	
	if (i > 0) {
		if (utf8_offset_cache.last_byteoffset[i] == byteoffset) {
#ifdef DEBUG
	DEBUG_MSG("byteoffset %ld is in the cache at i=%d, returning %d\n",byteoffset,i,utf8_offset_cache.last_charoffset[i]);
#endif
			return utf8_offset_cache.last_charoffset[i];
       }
       /* if the byteoffset is in the middle of a multibyte character, this line will fail (but
	       we are not supposed to get called in the middle of a character)*/
		retval = g_utf8_pointer_to_offset(string+utf8_offset_cache.last_byteoffset[i], string+byteoffset)+utf8_offset_cache.last_charoffset[i];
#ifdef UTF8_BYTECHARDEBUG
		utf8_offset_cache.numbytes_parsed += (byteoffset - utf8_offset_cache.last_byteoffset[i]);
		utf8_offset_cache.numbytes_cached_parsed += (byteoffset - utf8_offset_cache.last_byteoffset[i]);
		utf8_offset_cache.numcalls_cached_since_reset++;
#endif
	} else {
		retval = g_utf8_pointer_to_offset(string, string+byteoffset);
#ifdef UTF8_BYTECHARDEBUG
		utf8_offset_cache.numbytes_parsed += byteoffset;
#endif
	}
	DEBUG_MSG(" and byteoffset %ld has charoffset %d\n",byteoffset,retval);
	if (i == (UTF8_OFFSET_CACHE_SIZE-1)) {
		/* add this new calculation to the cache */
		/* this is a nasty trick to move all guint entries one back in the array, so we can add the new one */
		memmove(&utf8_offset_cache.last_byteoffset[0], &utf8_offset_cache.last_byteoffset[1], (UTF8_OFFSET_CACHE_SIZE+UTF8_OFFSET_CACHE_SIZE-1)*sizeof(guint));

		utf8_offset_cache.last_byteoffset[UTF8_OFFSET_CACHE_SIZE-1] = byteoffset;
		utf8_offset_cache.last_charoffset[UTF8_OFFSET_CACHE_SIZE-1] = retval;
	}
#ifdef UTF8_BYTECHARDEBUG
	utf8_offset_cache.numcalls_since_reset++;
#endif
	return retval;
}
示例#7
0
static void
gnt_entry_draw(GntWidget *widget)
{
	GntEntry *entry = GNT_ENTRY(widget);
	int stop;
	gboolean focus;
	int curpos;

	if ((focus = gnt_widget_has_focus(widget)))
		wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_TEXT_NORMAL));
	else
		wbkgdset(widget->window, '\0' | gnt_color_pair(GNT_COLOR_HIGHLIGHT_D));

	if (entry->masked)
	{
		mvwhline(widget->window, 0, 0, gnt_ascii_only() ? '*' : ACS_BULLET,
				g_utf8_pointer_to_offset(entry->scroll, entry->end));
	}
	else
		mvwprintw(widget->window, 0, 0, "%s", C_(entry->scroll));

	stop = gnt_util_onscreen_width(entry->scroll, entry->end);
	if (stop < widget->priv.width)
		mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop);

	curpos = gnt_util_onscreen_width(entry->scroll, entry->cursor);
	if (focus)
		mvwchgat(widget->window, 0, curpos, 1, A_REVERSE, GNT_COLOR_TEXT_NORMAL, NULL);
	wmove(widget->window, 0, curpos);

	GNTDEBUG;
}
示例#8
0
// move word left
static void textbox_cursor_dec_word ( textbox *tb )
{
    // Find word boundaries, with pango_Break?
    gchar *n;
    gchar *c = g_utf8_offset_to_pointer ( tb->text, tb->cursor );
    while ( ( c = g_utf8_prev_char ( c ) ) && c != tb->text ) {
        gunichar          uc = g_utf8_get_char ( c );
        GUnicodeBreakType bt = g_unichar_break_type ( uc );
        if ( ( bt == G_UNICODE_BREAK_ALPHABETIC || bt == G_UNICODE_BREAK_HEBREW_LETTER ||
               bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION ) ) {
            break;
        }
    }
    if ( c != tb->text ) {
        while ( ( n = g_utf8_prev_char ( c ) ) ) {
            gunichar          uc = g_utf8_get_char ( n );
            GUnicodeBreakType bt = g_unichar_break_type ( uc );
            if ( !( bt == G_UNICODE_BREAK_ALPHABETIC || bt == G_UNICODE_BREAK_HEBREW_LETTER ||
                    bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION ) ) {
                break;
            }
            c = n;
            if ( n == tb->text ) {
                break;
            }
        }
    }
    int index = g_utf8_pointer_to_offset ( tb->text, c );
    textbox_cursor ( tb, index );
}
示例#9
0
// Move word right
static void textbox_cursor_inc_word ( textbox *tb )
{
    if ( tb->text == NULL ) {
        return;
    }
    // Find word boundaries, with pango_Break?
    gchar *c = g_utf8_offset_to_pointer ( tb->text, tb->cursor );
    while ( ( c = g_utf8_next_char ( c ) ) ) {
        gunichar          uc = g_utf8_get_char ( c );
        GUnicodeBreakType bt = g_unichar_break_type ( uc );
        if ( ( bt == G_UNICODE_BREAK_ALPHABETIC || bt == G_UNICODE_BREAK_HEBREW_LETTER ||
               bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION ) ) {
            break;
        }
    }
    if ( c == NULL || *c == '\0' ) {
        return;
    }
    while ( ( c = g_utf8_next_char ( c ) ) ) {
        gunichar          uc = g_utf8_get_char ( c );
        GUnicodeBreakType bt = g_unichar_break_type ( uc );
        if ( !( bt == G_UNICODE_BREAK_ALPHABETIC || bt == G_UNICODE_BREAK_HEBREW_LETTER ||
                bt == G_UNICODE_BREAK_NUMERIC || bt == G_UNICODE_BREAK_QUOTATION ) ) {
            break;
        }
    }
    int index = g_utf8_pointer_to_offset ( tb->text, c );
    textbox_cursor ( tb, index );
}
示例#10
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;
}
示例#11
0
static void test_utf8 (gconstpointer d)
{
  gint num_chars;
  const gchar **p;
  gint i, j;
  const gchar *string = d;

  g_assert (g_utf8_validate (string, -1, NULL));

  num_chars = g_utf8_strlen (string, -1);

  p = (const gchar **) g_malloc (num_chars * sizeof (gchar *));

  p[0] = string;
  for (i = 1; i < num_chars; i++)
    p[i] = g_utf8_next_char (p[i-1]);

  for (i = 0; i < num_chars; i++)
    for (j = 0; j < num_chars; j++)
      {
        g_assert (g_utf8_offset_to_pointer (p[i], j - i) == p[j]);
        g_assert (g_utf8_pointer_to_offset (p[i], p[j]) == j - i);
      }

  g_free (p);
}
示例#12
0
/**
 * g_utf8_offset_to_pointer:
 * @str: a UTF-8 encoded string
 * @offset: a character offset within @str
 *
 * Converts from an integer character offset to a pointer to a position
 * within the string.
 *
 * Since 2.10, this function allows to pass a negative @offset to
 * step backwards. It is usually worth stepping backwards from the end
 * instead of forwards if @offset is in the last fourth of the string,
 * since moving forward is about 3 times faster than moving backward.
 *
 * <note><para>
 * This function doesn't abort when reaching the end of @str. Therefore
 * you should be sure that @offset is within string boundaries before
 * calling that function. Call g_utf8_strlen() when unsure.
 *
 * This limitation exists as this function is called frequently during
 * text rendering and therefore has to be as fast as possible.
 * </para></note>
 *
 * Return value: the resulting pointer
 **/
gchar *
g_utf8_offset_to_pointer  (const gchar *str,
			   glong        offset)
{
  const gchar *s = str;

  if (offset > 0) 
    while (offset--)
      s = g_utf8_next_char (s);
  else
    {
      const char *s1;

      /* This nice technique for fast backwards stepping 
       * through a UTF-8 string was dubbed "stutter stepping" 
       * by its inventor, Larry Ewing.
       */
      while (offset)
	{
	  s1 = s;
	  s += offset;
	  while ((*s & 0xc0) == 0x80)
	    s--;

	  offset += g_utf8_pointer_to_offset (s, s1);
	}
    }

  return (gchar *)s;
}
示例#13
0
文件: gaillabel.c 项目: BYC/gtk
static gint 
gail_label_get_offset_at_point (AtkText      *text,
                                gint         x,
                                gint         y,
			        AtkCoordType coords)
{ 
  GtkWidget *widget;
  GtkLabel *label;
  const gchar *label_text;
  gint index, x_layout, y_layout;

  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
  if (widget == NULL)
    /* State is defunct */
    return -1;
  label = GTK_LABEL (widget);
  
  gtk_label_get_layout_offsets (label, &x_layout, &y_layout);
  
  index = gail_misc_get_index_at_point_in_layout (widget, 
                                              gtk_label_get_layout (label), 
                                              x_layout, y_layout, x, y, coords);
  label_text = gtk_label_get_text (label);
  if (index == -1)
    {
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
        return g_utf8_strlen (label_text, -1);

      return index;  
    }
  else
    return g_utf8_pointer_to_offset (label_text, label_text + index);
}
示例#14
0
static gint
go_load_pango_byte_to_char (gchar const *str, gint byte)
{
	if (byte >= (gint)strlen (str))
		return g_utf8_strlen (str, -1);
	return g_utf8_pointer_to_offset (str, g_utf8_prev_char (str + byte + 1));
}
示例#15
0
static gint 
gail_notebook_page_get_offset_at_point (AtkText      *text,
                                        gint         x,
                                        gint         y,
	          		        AtkCoordType coords)
{ 
  GtkWidget *label;
  GailNotebookPage *notebook_page;
  gint index, x_layout, y_layout;
  const gchar *label_text;

  notebook_page = GAIL_NOTEBOOK_PAGE (text);
  label = get_label_from_notebook_page (notebook_page);

  if (!GTK_IS_LABEL(label))
    return -1;
  
  gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout);
  
  index = gail_misc_get_index_at_point_in_layout (label, 
                                              gtk_label_get_layout (GTK_LABEL (label)), 
                                              x_layout, y_layout, x, y, coords);
  label_text = gtk_label_get_text (GTK_LABEL (label));
  if (index == -1)
    {
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
        return g_utf8_strlen (label_text, -1);

      return index;  
    }
  else
    return g_utf8_pointer_to_offset (label_text, label_text + index);  
}
示例#16
0
static void buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old_status, PurpleStatus *status) {
        PurplePlugin *prpl;
        PurplePluginProtocolInfo *prpl_info = NULL;
 	char *sip_from = find_sip_user(buddy->name);
	int d = hashtable_get_counter(buddy->name);
	PurpleStatusPrimitive primitive;
	enum purple_publish_basic basic;
	enum purple_publish_activity activity;
       	char *statustext = NULL, *tmp = NULL, *new;
	const char *end;

	LM_DBG("buddy <%s> has changed status\n", buddy->name);
	if ((sip_from) && (d>0)) {
		primitive = purple_status_type_get_primitive(purple_status_get_type(status));
		primitive_parse(primitive, &basic, &activity);


//		char *note = purple_status_get_attr_string(status, "message");

	        prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));

		if (prpl != NULL)
			prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);

		if (prpl_info && prpl_info->status_text && buddy->account->gc) {
			tmp = prpl_info->status_text(buddy);

			if(tmp && !g_utf8_validate(tmp, -1, &end)) {
				new = g_strndup(tmp, g_utf8_pointer_to_offset(tmp, end));
				g_free(tmp);
				tmp = new;
			}
static void
thunar_text_renderer_grab_focus (GtkWidget          *entry,
                                 ThunarTextRenderer *text_renderer)
{
  const gchar *text;
  const gchar *dot;
  glong        offset;

  /* determine the text from the entry widget */
  text = gtk_entry_get_text (GTK_ENTRY (entry));

  /* lookup the last dot in the text */
  dot = strrchr (text, '.');
  if (G_LIKELY (dot != NULL))
    {
      /* determine the UTF-8 char offset */
      offset = g_utf8_pointer_to_offset (text, dot);

      /* select the text prior to the dot */
      if (G_LIKELY (offset > 0))
        gtk_entry_select_region (GTK_ENTRY (entry), 0, offset);
    }

  /* disconnect the grab-focus handler, so we change the selection only once */
  g_signal_handlers_disconnect_by_func (G_OBJECT (entry), thunar_text_renderer_grab_focus, text_renderer);
}
示例#18
0
/* Search regular expression in text, return TRUE and matching part as start and
 * end integer position */
static gboolean
search_regex_in_text (const gchar* search_entry, const gchar* editor_text, gboolean search_forward, gint * start_pos, gint * end_pos)
{
	GRegex * regex;
	GMatchInfo *match_info;
	gboolean found;
	GError * err = NULL;

	regex = g_regex_new (search_entry, 0, 0, &err);
	if (err)
	{
		g_message ("%s",err->message);
		g_error_free (err);
		g_regex_unref(regex);
		return FALSE;
	}

	found = g_regex_match (regex, editor_text, 0, &match_info);

	if (found)
	{
		if (search_forward)
			g_match_info_fetch_pos(match_info, 0, start_pos, end_pos);
		else
		{
			do
			{
				g_match_info_fetch_pos(match_info, 0, start_pos, end_pos);
			}
			while (g_match_info_next(match_info, NULL));
		}

		*start_pos = g_utf8_pointer_to_offset(editor_text, &editor_text[*start_pos]);
		*end_pos = g_utf8_pointer_to_offset(editor_text, &editor_text[*end_pos]);
	}

	if (regex)
		g_regex_unref(regex);
	if (match_info)
		g_match_info_free (match_info);

	return found;

}
示例#19
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;
}
示例#20
0
文件: ostring.c 项目: htrb/ngraph-gtk
static int 
string_rindex(struct objlist *obj,N_VALUE *inst,N_VALUE *rval,int argc,char **argv)
{
  int pos, size, len;
  char *str, *pattern, *ptr, *find;

  rval->i = -1;

  pattern = (char *) argv[2];
  pos = * (int *) argv[3];

  if (pattern == NULL || pattern[0] == '\0') {
    return 1;
  }

  if (_getobj(obj, "length", inst, &size)) {
    return 2;
  }

  if (! g_utf8_validate(pattern, -1, NULL)) {
    error(obj, ERR_INVALID_UTF8);
    return 2;
  }

  if (pos < 0) {
    pos += size;
  }

  if (pos < 0 || pos >= size) {
    return 1;
  }

  if (_getobj(obj, "@", inst, &str)) {
    return 1;
  }

  if(str == NULL || str[0] == '\0') {
    return 1;
  }

  ptr = g_utf8_offset_to_pointer(str, pos);
  len = ptr - str + 1;
  if (len < 1) {
    return 1;
  }

  find = g_strrstr_len(str, len, pattern);
  if (find == NULL) {
    return 1;
  }

  rval->i = g_utf8_pointer_to_offset(str, find);

  return 0;
}
示例#21
0
static gint      
gail_text_cell_get_offset_at_point (AtkText          *text,
                                    gint             x,
                                    gint             y,
                                    AtkCoordType     coords)
{
  AtkObject *parent;
  GailRendererCell *gail_renderer; 
  GtkCellRendererText *gtk_renderer;
  GtkWidget *widget;
  GdkRectangle rendered_rect;
  PangoLayout *layout;
  gint x_offset, y_offset, index;
 
  if (!GAIL_TEXT_CELL (text)->cell_text)
    return -1;

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

  g_return_val_if_fail (gtk_renderer->text, -1);
  if (GAIL_IS_CONTAINER_CELL (parent))
    parent = atk_object_get_parent (parent);

  widget = GTK_ACCESSIBLE (parent)->widget;

  g_return_val_if_fail (GAIL_IS_CELL_PARENT (parent), -1);
  gail_cell_parent_get_cell_area (GAIL_CELL_PARENT (parent), GAIL_CELL (text),
                                  &rendered_rect);
  gtk_cell_renderer_get_size (GTK_CELL_RENDERER (gtk_renderer), widget,
     &rendered_rect, &x_offset, &y_offset, NULL, NULL);

  layout = create_pango_layout (gtk_renderer, widget);
   
  index = gail_misc_get_index_at_point_in_layout (widget, layout,
        x_offset + rendered_rect.x + gail_renderer->renderer->xpad,
        y_offset + rendered_rect.y + gail_renderer->renderer->ypad,
        x, y, coords);
  g_object_unref (layout);
  if (index == -1)
    {
      if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN)
        return g_utf8_strlen (gtk_renderer->text, -1);
    
      return index;  
    }
  else
    return g_utf8_pointer_to_offset (gtk_renderer->text,
       gtk_renderer->text + index);  
}
示例#22
0
/**
 * Retrieve a possible address (or a part) from an entry box. To make life
 * easier, we only look at the last valid address component; address
 * completion only works at the last string component in the entry box.
 *
 * \param entry Address entry field.
 * \param start_pos Address of start position of address.
 * \return Possible address.
 */
static gchar *get_address_from_edit(GtkEntry *entry, gint *start_pos)
{
	const gchar *edit_text, *p;
	gint cur_pos;
	gboolean in_quote = FALSE;
	gboolean in_bracket = FALSE;
	gchar *str;

	edit_text = gtk_entry_get_text(entry);
	if (edit_text == NULL) return NULL;

	cur_pos = gtk_editable_get_position(GTK_EDITABLE(entry));

	/* scan for a separator. doesn't matter if walk points at null byte. */
	for (p = g_utf8_offset_to_pointer(edit_text, cur_pos);
	     p > edit_text;
	     p = g_utf8_prev_char(p)) {
		if (*p == '"') {
			in_quote = TRUE;
		} else if (!in_quote) {
			if (!in_bracket && *p == ',') {
				break;
			} else if (*p == '<')
				in_bracket = TRUE;
			else if (*p == '>')
				in_bracket = FALSE;
		}
	}

	/* have something valid */
	if (g_utf8_strlen(p, -1) == 0)
		return NULL;

#define IS_VALID_CHAR(x) \
	(g_ascii_isalnum(x) || (x) == '"' || (x) == '<' || (((unsigned char)(x)) > 0x7f))

	/* now scan back until we hit a valid character */
	for (; *p && !IS_VALID_CHAR(*p); p = g_utf8_next_char(p))
		;

#undef IS_VALID_CHAR

	if (g_utf8_strlen(p, -1) == 0)
		return NULL;

	if (start_pos) *start_pos = g_utf8_pointer_to_offset(edit_text, p);

	str = g_strdup(p);

	return str;
} 
示例#23
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;
}
示例#24
0
/* Search string in text, return TRUE and matching part as start and
 * end integer position */
static gboolean
search_str_in_text (const gchar* search_entry, const gchar* editor_text, gboolean case_sensitive, gint * start_pos, gint * end_pos)
{
	gboolean found;
	
	if (strlen (editor_text) >= strlen (search_entry))
	{
		gchar* selected_text_case;
		gchar* search_text_case;

		if (case_sensitive)
		{
			selected_text_case = g_strdup (editor_text);
			search_text_case = g_strdup (search_entry);
		}
		else
		{
			selected_text_case = g_utf8_casefold (editor_text, strlen (editor_text));
			search_text_case = g_utf8_casefold (search_entry, strlen (search_entry));
		}

		gchar* strstr = g_strstr_len (selected_text_case, -1, search_text_case);

		if (strstr)
		{
			*start_pos = g_utf8_pointer_to_offset(selected_text_case, strstr);
			*end_pos = g_utf8_pointer_to_offset(selected_text_case, strstr + strlen (search_entry));
			found = TRUE;
		}

		g_free (selected_text_case);
		g_free (search_text_case);
	}

	return found;
}
示例#25
0
static gboolean midorator_entry_key_press_event_cb (MidoratorEntry* e, GdkEventKey* event) {
	if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_a) {
		gtk_editable_set_position(GTK_EDITABLE(e), 0);
	} else if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_e) {
		gtk_editable_set_position(GTK_EDITABLE(e), -1);
	} else if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_f) {
		gtk_editable_set_position(GTK_EDITABLE(e), gtk_editable_get_position(GTK_EDITABLE(e)) + 1);
	} else if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_b) {
		gtk_editable_set_position(GTK_EDITABLE(e), gtk_editable_get_position(GTK_EDITABLE(e)) - 1);
	} else if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_p) {
		gtk_editable_set_position(GTK_EDITABLE(e), 0);
		midorator_entry_history_up(e);
	} else if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_n) {
		gtk_editable_set_position(GTK_EDITABLE(e), 0);
		midorator_entry_history_down(e);
	} else if ((event->state & GDK_CONTROL_MASK) && event->keyval == GDK_w) {
		const char *t = gtk_entry_get_text(GTK_ENTRY(e));
		int pos = gtk_editable_get_position(GTK_EDITABLE(e));
		char *i;
		for (i = g_utf8_offset_to_pointer(t, pos) - 1; i >= t && *i == ' '; i--);
		for (; i >= t && *i != ' '; i--);
		i++;
		int newpos = g_utf8_pointer_to_offset(t, i);
		gtk_editable_delete_text(GTK_EDITABLE(e), newpos, pos);
		gtk_editable_set_position(GTK_EDITABLE(e), newpos);
	} else if (event->keyval == GDK_Escape) {
		g_signal_emit(e, signals[SIG_CANCEL], 0);
	} else if (event->keyval == GDK_Tab) {
		midorator_entry_perform_completion(e);
	} else if (event->keyval == GDK_Up) {
		midorator_entry_history_up(e);
	} else if (event->keyval == GDK_Down) {
		midorator_entry_history_down(e);
	} else if (event->keyval == GDK_Page_Up) {
		gtk_editable_set_position(GTK_EDITABLE(e), 0);
		midorator_entry_history_up(e);
	} else if (event->keyval == GDK_Page_Down) {
		gtk_editable_set_position(GTK_EDITABLE(e), 0);
		midorator_entry_history_down(e);
	} else if (event->keyval == GDK_Return) {
		char *t = g_strdup(gtk_entry_get_text(GTK_ENTRY(e)));
		g_signal_emit(e, signals[SIG_EXECUTE], 0, t);
		midorator_entry_history_add(e, t);
		g_free(t);
	} else
		return false;
	return true;
}
示例#26
0
/* stolen from gtkfilechooserentry.c */
static gboolean
entry_select_filename_in_focus_cb (GtkWidget * entry, GdkEventFocus * event) {
    const gchar *str, *ext;
    glong len = -1;

    str = gtk_entry_get_text (GTK_ENTRY (entry));
    ext = g_strrstr (str, ".");

    if (ext)
        len = g_utf8_pointer_to_offset (str, ext);

    gtk_editable_select_region (GTK_EDITABLE (entry), 0, (gint) len);

    (void) event;
    return TRUE;
}
示例#27
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;
}
示例#28
0
文件: gui-entry.c 项目: Adam-/irssi
void gui_entry_insert_text(GUI_ENTRY_REC *entry, const char *str)
{
        unichar chr;
	int i, len;
	const char *ptr;

        g_return_if_fail(entry != NULL);
	g_return_if_fail(str != NULL);

        gui_entry_redraw_from(entry, entry->pos);

	if (entry->utf8) {
		g_utf8_validate(str, -1, &ptr);
		len = g_utf8_pointer_to_offset(str, ptr);
	} else if (term_type == TERM_TYPE_BIG5)
		len = strlen_big5((const unsigned char *)str);
	else
		len = strlen(str);
        entry_text_grow(entry, len);

        /* make space for the string */
	g_memmove(entry->text + entry->pos + len, entry->text + entry->pos,
		  (entry->text_len-entry->pos + 1) * sizeof(unichar));

	if (!entry->utf8) {
		if (term_type == TERM_TYPE_BIG5) {
			chr = entry->text[entry->pos + len];
			big5_to_unichars(str, entry->text + entry->pos);
			entry->text[entry->pos + len] = chr;
		} else {
			for (i = 0; i < len; i++)
				entry->text[entry->pos + i] = str[i];
		}
	} else {
		ptr = str;
		for (i = 0; i < len; i++) {
			entry->text[entry->pos + i] = g_utf8_get_char(ptr);
			ptr = g_utf8_next_char(ptr);
		}
	}

	entry->text_len += len;
        entry->pos += len;

	gui_entry_fix_cursor(entry);
	gui_entry_draw(entry);
}
示例#29
0
/**
 * g_utf8_pointer_to_offset:
 * @str: a UTF-8 encoded string
 * @pos: a pointer to a position within @str
 * 
 * Converts from a pointer to position within a string to a integer
 * character offset.
 *
 * Since 2.10, this function allows @pos to be before @str, and returns
 * a negative offset in this case.
 * 
 * Return value: the resulting character offset
 **/
glong    
g_utf8_pointer_to_offset (const gchar *str,
			  const gchar *pos)
{
  const gchar *s = str;
  glong offset = 0;    

  if (pos < str) 
    offset = - g_utf8_pointer_to_offset (pos, str);
  else
    while (s < pos)
      {
	s = g_utf8_next_char (s);
	offset++;
      }
  
  return offset;
}
示例#30
0
文件: thai.c 项目: fcitx/fcitx-thai
static void
FcitxThaiGetPrevCell(FcitxThai* thai, struct thcell_t* res)
{
    th_init_cell(res);

    if (is_client_support_surrounding(IBUS_ENGINE(libthai_engine))) {
        IBusText* surrounding;
        guint     cursor_pos;
        guint     anchor_pos;
        const gchar* s;
        gchar*    tis_text = NULL;

        ibus_engine_get_surrounding_text(IBUS_ENGINE(libthai_engine),
                                         &surrounding, &cursor_pos, &anchor_pos);
        s = ibus_text_get_text(surrounding);
        cursor_pos = g_utf8_offset_to_pointer(s, cursor_pos) - s;
        while (*s) {
            const gchar* t;

            tis_text = g_convert(s, cursor_pos, "TIS-620", "UTF-8",
                                 NULL, NULL, NULL);
            if (tis_text)
                break;

            t = g_utf8_next_char(s);
            cursor_pos -= (t - s);
            s = t;
        }
        if (tis_text) {
            gint char_index;

            char_index = g_utf8_pointer_to_offset(s, s + cursor_pos);
            th_prev_cell((thchar_t*) tis_text, char_index, res, TRUE);
            g_free(tis_text);
        }
    } else {
        /* retrieve from the fallback buffer */
        th_prev_cell(libthai_engine->char_buff, libthai_engine->buff_tail,
                     res, TRUE);
    }
}