if (gtk_check_algorithmically (keysyms, n_compose, output))
{ if (strcmp (value, output->str) == 0)
remove_sequence = TRUE;
}
next: if (remove_sequence)
g_hash_table_iter_remove (&iter);
}
g_string_free (output, TRUE);
}
staticvoid
parser_compute_max_compose_len (GtkComposeParser *parser, int *max_compose_len, int *n_first, int *size)
{
GHashTableIter iter;
gunichar *sequence; char *value; int max = 0; int count = 0;
GHashTable *first;
p = contents; if (g_ascii_strncasecmp (p, GTK_COMPOSE_TABLE_MAGIC,
strlen (GTK_COMPOSE_TABLE_MAGIC)) != 0)
{
g_warning ("The file is not a GtkComposeTable cache file %s", path); goto out_load_cache;
}
p += strlen (GTK_COMPOSE_TABLE_MAGIC); if (p - contents > total_length)
{
g_warning ("Broken cache content %s at head", path); goto out_load_cache;
}
GET_GUINT16 (version); if (version != GTK_COMPOSE_TABLE_VERSION)
{ if (version < GTK_COMPOSE_TABLE_VERSION)
*found_old_cache = TRUE; goto out_load_cache;
}
static GtkComposeTable *
parser_get_compose_table (GtkComposeParser *parser)
{
guint16 *data;
GtkComposeTable *table;
guint16 encoded_value;
GString *char_data; int max_compose_len;
GList *sequences;
GList *list; int i; int size; int n_first; int first_pos; int rest_pos; int index_rowstride; int n_sequences;
gunichar current_first;
parser_remove_duplicates (parser);
if (g_hash_table_size (parser->sequences) == 0) return NULL;
for (list = sequences; list != NULL; list = list->next)
{
gunichar *sequence = list->data; char *value = g_hash_table_lookup (parser->sequences, sequence); int len = sequence_length (sequence);
g_assert (1 <= len && len <= max_compose_len);
/* Encode the value. If the value is a single *characterwithavaluesmallerthan1<<15, *wejustuseitdirectly. *Otherwise,westorethevalueasstringand *puttheoffsetintothetable,withthehigh *bitset.
*/ if (g_utf8_strlen (value, -1) == 1 &&
g_utf8_get_char (value) < 0x8000)
{
encoded_value = (guint16) g_utf8_get_char (value);
} else
{ if (char_data->len > 0)
g_string_append_c (char_data, 0);
if (char_data->len >= 0x8000)
{
g_warning ("GTK can't handle compose tables this large (%s)", parser->compose_file ? parser->compose_file : "");
g_free (data);
g_string_free (char_data, TRUE); return NULL;
}
static gboolean
rewrite_compose_file (constchar *compose_file)
{ staticconstchar *prefix = "# GTK has rewritten this file to add the line:\n" "\n" "include \"%L\"\n" "\n" "# This is necessary to add your own Compose sequences\n" "# in addition to the builtin sequences of GTK. If this\n" "# is not what you want, just remove that line.\n" "#\n" "# A backup of the previous file contents has been made.\n" "\n" "\n";
/* This is where we apply heuristics to avoid breaking users existing configurations *withthechangetonotalwaysaddthedefaultsequences. * *Ifwefindacachethatwasgeneratedbefore4.4,andtheComposefile *doesnothaveaninclude,anddoesn'tcontainsomanysequencesthatit *isprobablyacopyofthesystemone,wetakestepstokeepthingsworking, *andthelltheuseraboutit.
*/ if (found_old_cache && !found_include &&
compose_table != NULL && compose_table->n_sequences < 100)
{ if (rewrite_compose_file (compose_file))
{
g_warning ("\nSince GTK 4.4, Compose files replace the builtin\n" "compose sequences. To keep them and add your own\n" "sequences on top, the line:\n" "\n" " include \"%%L\"\n" "\n" "has been added to the Compose file\n%s.\n", compose_file); goto parse;
} else
{
g_warning ("\nSince GTK 4.4, Compose files replace the builtin\n" "compose sequences. To keep them and add your own\n" "sequences on top, you need to add the line:\n" "\n" " include \"%%L\"\n" "\n" "to the Compose file\n%s.\n", compose_file);
}
}
if (compose_table != NULL)
gtk_compose_table_save_cache (compose_table);
return compose_table;
}
GtkComposeTable *
gtk_compose_table_new_with_data (const guint16 *data, int max_seq_len, int n_seqs)
{
GtkComposeParser *parser;
GtkComposeTable *compose_table; int i;
parser = parser_new ();
for (i = 0; i < n_seqs; i++)
{ const guint16 *seq = data + i * (max_seq_len + 2);
guint16 *sequence;
gunichar ch; char buf[8] = { 0, };
if (compose_finish)
*compose_finish = FALSE; if (compose_match)
*compose_match = FALSE;
/* Will never match, if the sequence in the compose buffer is longer *thanthesequencesinthetable.Further,compare_seq(key,val) *willoverrunvalifkeyislongerthanval.
*/ if (n_compose > table->max_seq_len) returnFALSE;
if (seq)
{ if (i == n_compose - 1)
{
value = seq[len - 1];
if ((value & (1 << 15)) != 0)
g_string_append (output, &table->char_data[value & ~(1 << 15)]); else
g_string_append_unichar (output, value);
match = TRUE;
} else
{ if (match)
{ if (compose_match)
*compose_match = TRUE;
}
returnTRUE;
}
}
}
}
if (match)
{ if (compose_match)
*compose_match = TRUE; if (compose_finish)
*compose_finish = TRUE;
returnTRUE;
}
returnFALSE;
}
void
gtk_compose_table_get_prefix (const GtkComposeTable *table, const guint *compose_buffer, int n_compose, int *prefix)
{ int index_stride = table->max_seq_len + 2; int p = 0;
sequence[0] = seq_index[0]; for (int k = 1; k < len; k++)
sequence[k] = (gunichar) table->data[j + k - 1];
sequence[len] = 0;
encoded_value = table->data[j + len - 1];
g_assert (encoded_value != 0); if ((encoded_value & (1 << 15)) != 0)
{ int char_offset = encoded_value & ~(1 << 15);
g_assert (char_offset < table->n_chars);
value = &table->char_data[char_offset];
} else
{
g_unichar_to_utf8 ((gunichar)encoded_value, buf);
value = buf;
}
callback (sequence, len, value, data);
}
}
}
}
/* Checks if a keysym is a dead key. *Deadkeykeysymvaluesaredefinedin../gdk/gdkkeysyms.handthe *firstisGDK_KEY_dead_grave.AsX.Orgisupdated,moredeadkeys *areaddedandweneedtoupdatetheupperlimit.
*/ #define IS_DEAD_KEY(k) \
((k) >= GDK_KEY_dead_grave && (k) <= GDK_KEY_dead_hamza)
gboolean
gtk_check_algorithmically (const guint *compose_buffer, int n_compose,
GString *output)
{ int i;
g_string_set_size (output, 0);
for (i = 0; i < n_compose && IS_DEAD_KEY (compose_buffer[i]); i++)
;
/* Can't combine if there's no base character: incomplete sequence */ if (i == n_compose) returnTRUE;
if (i > 0 && i == n_compose - 1)
{
GString *input; char *nfc;
gunichar ch;
ch = gdk_keyval_to_unicode (compose_buffer[i]);
/* We don't allow combining with non-letters */ if (!g_unichar_isalpha (ch)) returnFALSE;
input = g_string_sized_new (4 * n_compose);
g_string_append_unichar (input, ch);
i--; while (i >= 0)
{ switch (compose_buffer[i])
{ #defineCASE(keysym, unicode) \ case GDK_KEY_dead_##keysym: g_string_append_unichar (input, unicode); break
CASE (grave, 0x0300); CASE (acute, 0x0301); CASE (circumflex, 0x0302); case GDK_KEY_dead_tilde: if (g_unichar_get_script (ch) == G_UNICODE_SCRIPT_GREEK)
g_string_append_unichar (input, 0x342); /* combining perispomeni */ else
g_string_append_unichar (input, 0x303); /* combining tilde */ break; CASE (macron, 0x0304); CASE (breve, 0x0306); CASE (abovedot, 0x0307); CASE (diaeresis, 0x0308); CASE (abovering, 0x30A); CASE (hook, 0x0309); CASE (doubleacute, 0x030B); CASE (caron, 0x030C); CASE (cedilla, 0x0327); CASE (ogonek, 0x0328); /* Legacy use for dasia, 0x314.*/ CASE (iota, 0x0345); CASE (voiced_sound, 0x3099); /* Per Markus Kuhn keysyms.txt file. */ CASE (semivoiced_sound, 0x309A); /* Per Markus Kuhn keysyms.txt file. */ CASE (belowdot, 0x0323); CASE (horn, 0x031B); /* Legacy use for psili, 0x313 (or 0x343). */ CASE (stroke, 0x335); CASE (abovecomma, 0x0313); /* Equivalent to psili */ CASE (abovereversedcomma, 0x0314); /* Equivalent to dasia */ CASE (doublegrave, 0x30F); CASE (belowring, 0x325); CASE (belowmacron, 0x331); CASE (belowcircumflex, 0x32D); CASE (belowtilde, 0x330); CASE (belowbreve, 0x32e); CASE (belowdiaeresis, 0x324); CASE (invertedbreve, 0x32f); CASE (belowcomma, 0x326); CASE (lowline, 0x332); CASE (aboveverticalline, 0x30D); CASE (belowverticalline, 0x329); CASE (longsolidusoverlay, 0x338); CASE (a, 0x363); CASE (A, 0x363); CASE (e, 0x364); CASE (E, 0x364); CASE (i, 0x365); CASE (I, 0x365); CASE (o, 0x366); CASE (O, 0x366); CASE (u, 0x367); CASE (U, 0x367); CASE (small_schwa, 0x1DEA); CASE (capital_schwa, 0x1DEA); CASE (hamza, 0x654); #undefCASE default:
g_string_append_unichar (input, gdk_keyval_to_unicode (compose_buffer[i]));
}
i--;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.