Exemple #1
0
// move word left
static void textbox_cursor_dec_word ( textbox *tb )
{
    // Find word boundaries, with pango_Break?
    gchar *n;
    gchar *c = &( 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 = c - tb->text;
    textbox_cursor ( tb, index );
}
static GeditDocumentNewlineType
get_newline_type (GtkTextIter *end)
{
	GeditDocumentNewlineType res;
	GtkTextIter copy;
	gunichar c;

	copy = *end;
	c = gtk_text_iter_get_char (&copy);

	if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN)
	{
		if (gtk_text_iter_forward_char (&copy) &&
		    g_unichar_break_type (gtk_text_iter_get_char (&copy)) == G_UNICODE_BREAK_LINE_FEED)
		{
			res = GEDIT_DOCUMENT_NEWLINE_TYPE_CR_LF;
		}
		else
		{
			res = GEDIT_DOCUMENT_NEWLINE_TYPE_CR;
		}
	}
	else
	{
		res = GEDIT_DOCUMENT_NEWLINE_TYPE_LF;
	}

	return res;
}
Exemple #3
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 = &( 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 ) {
        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 = c - tb->text;
    textbox_cursor ( tb, index );
}
Exemple #4
0
/**
 * gimp_utf8_strtrim:
 * @str: an UTF-8 encoded string (or %NULL)
 * @max_chars: the maximum number of characters before the string get
 * trimmed
 *
 * Creates a (possibly trimmed) copy of @str. The string is cut if it
 * exceeds @max_chars characters or on the first newline. The fact
 * that the string was trimmed is indicated by appending an ellipsis.
 *
 * Returns: A (possibly trimmed) copy of @str which should be freed
 * using g_free() when it is not needed any longer.
 **/
gchar *
gimp_utf8_strtrim (const gchar *str,
                   gint         max_chars)
{
  /* FIXME: should we make this translatable? */
  const gchar ellipsis[] = "...";
  const gint  e_len      = strlen (ellipsis);

  if (str)
    {
      const gchar *p;
      const gchar *newline = NULL;
      gint         chars   = 0;
      gunichar     unichar;

      for (p = str; *p; p = g_utf8_next_char (p))
        {
          if (++chars > max_chars)
            break;

          unichar = g_utf8_get_char (p);

          switch (g_unichar_break_type (unichar))
            {
            case G_UNICODE_BREAK_MANDATORY:
            case G_UNICODE_BREAK_LINE_FEED:
              newline = p;
              break;
            default:
              continue;
            }

          break;
        }

      if (*p)
        {
          gsize  len     = p - str;
          gchar *trimmed = g_new (gchar, len + e_len + 2);

          memcpy (trimmed, str, len);
          if (newline)
            trimmed[len++] = ' ';

          g_strlcpy (trimmed + len, ellipsis, e_len + 1);

          return trimmed;
        }

      return g_strdup (str);
    }

  return NULL;
}
static void lookup(const char *text, char ***pppWord, char ****ppppWordData)
{
	if ((text[0] == '&' && text[1] == '#' && g_str_has_suffix(text, ";")) || g_str_has_prefix(text, "U+")) {
		gunichar uc;
		if (text[0] == '&') {
			if (text[2] == 'x' || text[2] == 'X') {
				uc = htoi(text+3);
			} else {
				uc = atoi(text+2);
			}
		} else { // U+
			uc = htoi(text+2);
		}
		gchar utf8[7];
		gint n = g_unichar_to_utf8(uc, utf8);
		utf8[n] = '\0';

		*pppWord = (gchar **)g_malloc(sizeof(gchar *)*2);
		(*pppWord)[0] = g_strdup(text);
		(*pppWord)[1] = NULL;
		*ppppWordData = (gchar ***)g_malloc(sizeof(gchar **)*(1));
		(*ppppWordData)[0] = (gchar **)g_malloc(sizeof(gchar *)*2);
		(*ppppWordData)[0][0] =  build_dictdata('m', utf8);
		(*ppppWordData)[0][1] = NULL;
		return;
	}
	bool found;
	gunichar uc;
	if (g_utf8_strlen(text, -1) != 1) {
		found = false; // Don't query it.
	} else {
		uc = g_utf8_get_char(text);
		if (!gucharmap_unichar_validate (uc) || !gucharmap_unichar_isdefined (uc))
			found = false;
		else
			found = true;
	}
	if (!found) {
		*pppWord = NULL;
		return;
	}
	std::string definition;
	definition += "\n";
	gchar buf[12];
	int n = gucharmap_unichar_to_printable_utf8 (uc, buf);
	if (n == 0) {
		definition += _("[not a printable character]");
	} else {
		gchar *str = g_markup_escape_text(buf, n);
		definition += "<big><big><big><big>";
		definition += str;
		definition += "</big></big></big></big>";
		g_free(str);
	}
	definition += "\n\n";
	gchar *temp;
	/* character name */
	temp = g_strdup_printf ("U+%4.4X %s", uc, gucharmap_get_unicode_name (uc));
	definition += "<big><b>";
	definition += temp;
	definition += "</b></big>\n";
	g_free (temp);
	definition += "\n<b>";
	definition += _("General Character Properties");
	definition += "</b>\n\n";
	/* character category */
	definition += get_vanilla_detail(_("Unicode category:"), gucharmap_get_unicode_category_name (uc));
	/* canonical decomposition */
	gunichar *decomposition;
	gsize result_len;
	decomposition = gucharmap_unicode_canonical_decomposition (uc, &result_len);
	if (result_len != 1) {
		definition += _("Canonical decomposition:");
		definition += " ";
		definition += get_codepoint(decomposition[0]);
		for (gsize i = 1;  i < result_len;  i++) {
			definition += " + ";
			definition += get_codepoint(decomposition[i]);
		}
		definition += "\n";
	}
	g_free (decomposition);
	/* representations */
	if (g_unichar_break_type(uc) != G_UNICODE_BREAK_SURROGATE) {
		definition += "\n<b>";
		definition += _("Various Useful Representations");
		definition += "</b>\n\n";
		guchar utf8[7];
		gunichar2 *utf16;
		GString *gstemp;
		n = g_unichar_to_utf8 (uc, (gchar *)utf8);
		utf16 = g_ucs4_to_utf16 (&uc, 1, NULL, NULL, NULL);
		/* UTF-8 */
		gstemp = g_string_new (NULL);
		gint i;
		for (i = 0;  i < n;  i++)
			g_string_append_printf (gstemp, "0x%2.2X ", utf8[i]);
		g_string_erase (gstemp, gstemp->len - 1, -1);
		definition += get_vanilla_detail(_("UTF-8:"), gstemp->str);
		g_string_free (gstemp, TRUE);
		/* UTF-16 */
		gstemp = g_string_new (NULL);
		g_string_append_printf (gstemp, "0x%4.4X", utf16[0]);
		if (utf16[0] != '\0' && utf16[1] != '\0')
			g_string_append_printf (gstemp, " 0x%4.4X", utf16[1]);
		definition += get_vanilla_detail(_("UTF-16:"), gstemp->str);
		g_string_free (gstemp, TRUE);
		/* an empty line */
		definition += "\n";
		/* C octal \012\234 */
		gstemp = g_string_new (NULL);
		for (i = 0;  i < n;  i++)
			g_string_append_printf (gstemp, "\\%3.3o", utf8[i]);
		definition += get_vanilla_detail(_("C octal escaped UTF-8:"), gstemp->str);
		g_string_free (gstemp, TRUE);
		/* XML entity */
		if ((0x0001 <= uc && uc <= 0xD7FF) ||
			(0xE000 <= uc && uc <= 0xFFFD) ||
			(0x10000 <= uc && uc <= 0x10FFFF))
		{
			temp = g_strdup_printf ("<kref>&amp;#%d;</kref>", uc);
			definition += get_vanilla_detail(_("XML decimal entity:"), temp);
			g_free (temp);
			temp = g_strdup_printf ("<kref>&amp;#x%X;</kref>", uc);
			definition += get_vanilla_detail(_("XML hexadecimal entity:"), temp);
			g_free (temp);
		}
		g_free(utf16);
	}
	/* annotations */
	std::string annotations;
	/* nameslist equals (alias names) */
	const gchar **csarr;
	csarr = gucharmap_get_nameslist_equals (uc);
	if (csarr != NULL) {
		annotations += get_chocolate_detail(_("Alias names:"), csarr, FALSE);
		g_free (csarr);
	}
	/* nameslist stars (notes) */
	csarr = gucharmap_get_nameslist_stars (uc);
	if (csarr != NULL) {
		annotations += get_chocolate_detail(_("Notes:"), csarr, TRUE);
		g_free (csarr);
	}
	/* nameslist exes (see also) */
	gunichar *ucs;
	ucs = gucharmap_get_nameslist_exes (uc);
	if (ucs != NULL) {
		annotations += get_chocolate_detail_codepoints(_("See also:"), ucs);
		g_free (ucs);
	}
	/* nameslist pounds (approximate equivalents) */
	csarr = gucharmap_get_nameslist_pounds (uc);
	if (csarr != NULL) {
		annotations += get_chocolate_detail(_("Approximate equivalents:"), csarr, TRUE);
		g_free (csarr);
	}
	/* nameslist colons (equivalents) */
	csarr = gucharmap_get_nameslist_colons (uc);
	if (csarr != NULL) {
		annotations += get_chocolate_detail(_("Equivalents:"), csarr, TRUE);
		g_free (csarr);
	}
	if (!annotations.empty()) {
		definition += "\n<b>";
		definition += _("Annotations and Cross References");
		definition += "</b>\n\n";
		definition += annotations;
	}
	std::string unihan;
	const gchar *csp = gucharmap_get_unicode_kDefinition (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Definition in English:"), csp);
	csp = gucharmap_get_unicode_kMandarin (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Mandarin Pronunciation:"), csp);
	csp = gucharmap_get_unicode_kCantonese (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Cantonese Pronunciation:"), csp);
	csp = gucharmap_get_unicode_kJapaneseOn (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Japanese On Pronunciation:"), csp);
	csp = gucharmap_get_unicode_kJapaneseKun (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Japanese Kun Pronunciation:"), csp);
	csp = gucharmap_get_unicode_kTang (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Tang Pronunciation:"), csp);
	csp = gucharmap_get_unicode_kKorean (uc);
	if (csp)
		unihan += get_vanilla_detail(_("Korean Pronunciation:"), csp);
	if (!unihan.empty()) {
		definition += "\n<b>";
		definition += _("CJK Ideograph Information");
		definition += "</b>\n\n";
		definition += unihan;
	}
	n = definition.length();
	int l = n-1;
	while (l >= 0 && definition[l] == '\n') {
		l--;
	}
	if (l < n-1) {
		definition.erase(l+1, n-1-l);
	}
	*pppWord = (gchar **)g_malloc(sizeof(gchar *)*2);
	(*pppWord)[0] = g_strdup(text);
	(*pppWord)[1] = NULL;
	*ppppWordData = (gchar ***)g_malloc(sizeof(gchar **)*(1));
	(*ppppWordData)[0] = (gchar **)g_malloc(sizeof(gchar *)*2);
	(*ppppWordData)[0][0] =  build_dictdata('x', definition.c_str());
	(*ppppWordData)[0][1] = NULL;
}
static void
set_details (GucharmapCharmap *charmap,
             gunichar uc)
{
  GucharmapCharmapPrivate *priv = charmap->priv;
  GtkTextBuffer *buffer;
  GtkTextIter iter;
  GString *gstemp;
  gchar *temp;
  const gchar *csp;
  gchar buf[12];
  guchar utf8[7];
  gint n, i;
  const gchar **csarr;
  gunichar *ucs;
  gunichar2 *utf16;
  GucharmapUnicodeVersion version;

  buffer = gtk_text_view_get_buffer (priv->details_view);
  gtk_text_buffer_set_text (buffer, "", 0);

  gtk_text_buffer_get_start_iter (buffer, &iter);
  gtk_text_buffer_place_cursor (buffer, &iter);
  gtk_text_buffer_insert (buffer, &iter, "\n", -1);

  n = gucharmap_unichar_to_printable_utf8 (uc, buf);
  if (n == 0)
    gtk_text_buffer_insert (
            buffer, &iter, _("[not a printable character]"), -1);
  else
    gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, buf, n, 
                                              "gimongous", NULL);

  gtk_text_buffer_insert (buffer, &iter, "\n\n", -1);
                                             
  /* character name */
  temp = g_strdup_printf ("U+%4.4X %s\n", 
                          uc, gucharmap_get_unicode_name (uc));
  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, temp, -1,
                                            "big", "bold", NULL);
  g_free (temp);

  insert_heading (charmap, buffer, &iter, _("General Character Properties"));

  /* Unicode version */
  version = gucharmap_get_unicode_version (uc);
  if (version != GUCHARMAP_UNICODE_VERSION_UNASSIGNED)
    insert_vanilla_detail (charmap, buffer, &iter,
                           _("In Unicode since:"),
                           gucharmap_unicode_version_to_string (version));

  /* character category */
  insert_vanilla_detail (charmap, buffer, &iter, _("Unicode category:"),
                         gucharmap_get_unicode_category_name (uc));

  /* canonical decomposition */
  conditionally_insert_canonical_decomposition (charmap, buffer, &iter, uc);

  /* representations */
  if (g_unichar_break_type(uc) != G_UNICODE_BREAK_SURROGATE)
    {
      insert_heading (charmap, buffer, &iter, _("Various Useful Representations"));

      n = g_unichar_to_utf8 (uc, (gchar *)utf8);
      utf16 = g_ucs4_to_utf16 (&uc, 1, NULL, NULL, NULL);

      /* UTF-8 */
      gstemp = g_string_new (NULL);
      for (i = 0;  i < n;  i++)
	g_string_append_printf (gstemp, "0x%2.2X ", utf8[i]);
      g_string_erase (gstemp, gstemp->len - 1, -1);
      insert_vanilla_detail (charmap, buffer, &iter, _("UTF-8:"), gstemp->str);
      g_string_free (gstemp, TRUE);

      /* UTF-16 */
      gstemp = g_string_new (NULL);
      g_string_append_printf (gstemp, "0x%4.4X", utf16[0]);
      if (utf16[0] != '\0' && utf16[1] != '\0')
	g_string_append_printf (gstemp, " 0x%4.4X", utf16[1]);
      insert_vanilla_detail (charmap, buffer, &iter, _("UTF-16:"), gstemp->str);
      g_string_free (gstemp, TRUE);

      /* an empty line */
      gtk_text_buffer_insert (buffer, &iter, "\n", -1);

      /* C octal \012\234 */
      gstemp = g_string_new (NULL);
      for (i = 0;  i < n;  i++)
	g_string_append_printf (gstemp, "\\%3.3o", utf8[i]);
      insert_vanilla_detail (charmap, buffer, &iter, 
			     _("C octal escaped UTF-8:"), gstemp->str);
      g_string_free (gstemp, TRUE);

      /* XML decimal entity */
      if ((0x0001 <= uc && uc <= 0xD7FF) ||
	  (0xE000 <= uc && uc <= 0xFFFD) ||
	  (0x10000 <= uc && uc <= 0x10FFFF))
	{
	  temp = g_strdup_printf ("&#%d;", uc);
	  insert_vanilla_detail (charmap, buffer, &iter, 
				 _("XML decimal entity:"), temp);
	  g_free (temp);
	}

      g_free(utf16);
    }

  /* annotations */
  if (_gucharmap_unicode_has_nameslist_entry (uc))
    {
      insert_heading (charmap, buffer, &iter, 
                      _("Annotations and Cross References"));

      /* nameslist equals (alias names) */
      csarr = gucharmap_get_nameslist_equals (uc);
      if (csarr != NULL)
        {
          insert_chocolate_detail (charmap, buffer, &iter,
                                   _("Alias names:"), csarr, FALSE);
          g_free (csarr);
        }

      /* nameslist stars (notes) */
      csarr = gucharmap_get_nameslist_stars (uc);
      if (csarr != NULL)
        {
          insert_chocolate_detail (charmap, buffer, &iter,
                                   _("Notes:"), csarr, TRUE);
          g_free (csarr);
        }

      /* nameslist exes (see also) */
      ucs = gucharmap_get_nameslist_exes (uc);
      if (ucs != NULL)
        {
          insert_chocolate_detail_codepoints (charmap, buffer, &iter,
                                              _("See also:"), ucs);
          g_free (ucs);
        }

      /* nameslist pounds (approximate equivalents) */
      csarr = gucharmap_get_nameslist_pounds (uc);
      if (csarr != NULL)
        {
          insert_chocolate_detail (charmap, buffer, &iter,
                                   _("Approximate equivalents:"), csarr, TRUE);
          g_free (csarr);
        }

      /* nameslist colons (equivalents) */
      csarr = gucharmap_get_nameslist_colons (uc);
      if (csarr != NULL)
        {
          insert_chocolate_detail (charmap, buffer, &iter,
                                   _("Equivalents:"), csarr, TRUE);
          g_free (csarr);
        }
    }

#if ENABLE_UNIHAN

  /* this isn't so bad efficiency-wise */
  if (gucharmap_get_unicode_kDefinition (uc)
      || gucharmap_get_unicode_kCantonese (uc)
      || gucharmap_get_unicode_kMandarin (uc)
      || gucharmap_get_unicode_kJapaneseOn (uc)
      || gucharmap_get_unicode_kJapaneseKun (uc)
      || gucharmap_get_unicode_kTang (uc)
      || gucharmap_get_unicode_kKorean (uc))
    {
      insert_heading (charmap, buffer, &iter, _("CJK Ideograph Information"));

      csp = gucharmap_get_unicode_kDefinition (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Definition in English:"), csp);
    
      csp = gucharmap_get_unicode_kMandarin (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Mandarin Pronunciation:"), csp);
    
      csp = gucharmap_get_unicode_kCantonese (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Cantonese Pronunciation:"), csp);
    
      csp = gucharmap_get_unicode_kJapaneseOn (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Japanese On Pronunciation:"), csp);
    
      csp = gucharmap_get_unicode_kJapaneseKun (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Japanese Kun Pronunciation:"), csp);
    
      csp = gucharmap_get_unicode_kTang (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Tang Pronunciation:"), csp);
    
      csp = gucharmap_get_unicode_kKorean (uc);
      if (csp)
        insert_vanilla_detail (charmap, buffer, &iter,
                               _("Korean Pronunciation:"), csp);
    }
#endif /* #if ENABLE_UNIHAN */
}
Exemple #7
0
static void
check_line_char (gunichar      wc,
		 gunichar      prev_wc,
		 gunichar      next_wc,
		 GUnicodeType  type,
		 GUnicodeType  prev_type,
		 GUnicodeType  next_type,
		 PangoLogAttr *attr,
		 PangoLogAttr *prev_attr,
		 PangoLogAttr *next_attr,
		 gpointer      data)
{
  GUnicodeBreakType break_type;
  GUnicodeBreakType prev_break_type;

  break_type = g_unichar_break_type (wc);
  if (prev_wc)
    prev_break_type = g_unichar_break_type (prev_wc);
  else
    prev_break_type = G_UNICODE_BREAK_UNKNOWN;

  if (wc == '\n')
    {
      if (prev_wc == '\r')
	{
	  if (attr->is_line_break)
	    fail ("line break between \\r and \\n");
	}

      if (next_attr && !next_attr->is_line_break)
	fail ("no line break after \\n");
    }

  if (attr->is_line_break && prev_wc == 0)
    fail ("first char in string should not be marked as a line break");

  if (break_type == G_UNICODE_BREAK_SPACE)
    {
      if (attr->is_line_break && prev_attr != NULL &&
	  !attr->is_mandatory_break &&
	  !(next_wc && g_unichar_break_type (next_wc) == G_UNICODE_BREAK_COMBINING_MARK))
	fail ("can't break lines before a space unless a mandatory break char precedes it or a combining mark follows; prev char was " CHFORMAT, prev_wc);
    }

  if (attr->is_mandatory_break && !attr->is_line_break)
    fail ("mandatory breaks must also be marked as regular breaks");



  /* FIXME use the break tables from break.c to automatically
   * check invariants for each cell in the table. Shouldn't
   * be that hard to do.
   */

  if (break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION &&
      prev_break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION &&
      attr->is_line_break &&
      !attr->is_mandatory_break)
    fail ("can't break between two open punctuation chars");

  if (break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION &&
      prev_break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION &&
      attr->is_line_break &&
      !attr->is_mandatory_break)
    fail ("can't break between two close punctuation chars");

  if (break_type == G_UNICODE_BREAK_QUOTATION &&
      prev_break_type == G_UNICODE_BREAK_ALPHABETIC &&
      attr->is_line_break &&
      !attr->is_mandatory_break)
    fail ("can't break letter-quotemark sequence");
}