/** * pango_language_includes_script: * @language: a PangoLanguage * @script: a #PangoScript * * Determines if @script is one of the scripts used to * write @language. The returned value is conservative; * if nothing is known about the language tag @language, * %TRUE will be returned, since, as far as Pango knows, * @script might be used to write @language. * * This routine is used in Pango's itemization process when * determining if a supplied language tag is relevant to * a particular section of text. It probably is not useful for * applications in most circumstances. * * Return value: %TRUE if @script is one of the scripts used * to write @language, or if nothing is known about @language. * * Since: 1.4 **/ gboolean pango_language_includes_script (PangoLanguage *language, PangoScript script) { PangoScriptForLang *script_for_lang; unsigned int j; g_return_val_if_fail (language != NULL, FALSE); if (!REAL_SCRIPT (script)) return TRUE; /* This bsearch could be optimized to occur only once if * we store the pointer to the PangoScriptForLang in the * same block as the string value for the PangoLanguage. */ script_for_lang = bsearch (pango_language_to_string (language), pango_script_for_lang, G_N_ELEMENTS (pango_script_for_lang), sizeof (PangoScriptForLang), script_for_lang_compare); if (!script_for_lang) return TRUE; for (j = 0; j < G_N_ELEMENTS (script_for_lang->scripts); j++) if (script_for_lang->scripts[j] == script) return TRUE; return FALSE; }
/** * pango_script_iter_next: * @iter: a #PangoScriptIter * * Advances a #PangoScriptIter to the next range. If @iter * is already at the end, it is left unchanged and %FALSE * is returned. * * Return value: %TRUE if @iter was successfully advanced. * * Since: 1.4 **/ gboolean pango_script_iter_next (PangoScriptIter *iter) { int start_sp; if (iter->script_end == iter->text_end) return FALSE; start_sp = iter->paren_sp; iter->script_code = PANGO_SCRIPT_COMMON; iter->script_start = iter->script_end; for (; iter->script_end < iter->text_end; iter->script_end = g_utf8_next_char (iter->script_end)) { gunichar ch = g_utf8_get_char (iter->script_end); PangoScript sc; int pair_index; sc = pango_script_for_unichar (ch); if (sc != PANGO_SCRIPT_COMMON) pair_index = -1; else pair_index = get_pair_index (ch); /* * Paired character handling: * * if it's an open character, push it onto the stack. * if it's a close character, find the matching open on the * stack, and use that script code. Any non-matching open * characters above it on the stack will be poped. */ if (pair_index >= 0) { if (IS_OPEN (pair_index)) { /* * If the paren stack is full, empty it. This * means that deeply nested paired punctuation * characters will be ignored, but that's an unusual * case, and it's better to ignore them than to * write off the end of the stack... */ if (++iter->paren_sp >= PAREN_STACK_DEPTH) iter->paren_sp = 0; iter->paren_stack[iter->paren_sp].pair_index = pair_index; iter->paren_stack[iter->paren_sp].script_code = iter->script_code; } else if (iter->paren_sp >= 0) { int pi = pair_index & ~1; while (iter->paren_sp >= 0 && iter->paren_stack[iter->paren_sp].pair_index != pi) iter->paren_sp--; if (iter->paren_sp < start_sp) start_sp = iter->paren_sp; if (iter->paren_sp >= 0) sc = iter->paren_stack[iter->paren_sp].script_code; } } if (SAME_SCRIPT (iter->script_code, sc)) { if (!REAL_SCRIPT (iter->script_code) && REAL_SCRIPT (sc)) { iter->script_code = sc; /* * now that we have a final script code, fix any open * characters we pushed before we knew the script code. */ while (start_sp < iter->paren_sp) iter->paren_stack[++start_sp].script_code = iter->script_code; } /* * if this character is a close paired character, * pop it from the stack */ if (pair_index >= 0 && !IS_OPEN (pair_index) && iter->paren_sp >= 0) { iter->paren_sp--; if (iter->paren_sp < start_sp) start_sp = iter->paren_sp; } } else { /* Different script, we're done */ break; } } return TRUE; }