static INT parse_vowel_syllable(LPCWSTR input, INT cChar, INT start, INT next, lexical_function lex) { if ((next < cChar) && lex(input[next]) == lex_Nukta) next++; if ((next < cChar) && is_joiner( lex(input[next]) ) && lex(input[next+1])==lex_Halant && is_consonant( lex(input[next+2]) )) next+=3; else if ((next < cChar) && lex(input[next])==lex_Halant && is_consonant( lex(input[next+1]) )) next+=2; else if ((next < cChar) && lex(input[next])==lex_ZWJ && is_consonant( lex(input[next+1]) )) next+=2; if ((next < cChar) && is_matra( lex(input[next]) )) { while((next < cChar) && is_matra( lex(input[next]) )) next++; if ((next < cChar) && lex(input[next]) == lex_Nukta) next++; if ((next < cChar) && lex(input[next]) == lex_Halant) next++; } if ((next < cChar) && lex(input[next]) == lex_Modifier) next++; if ((next < cChar) && lex(input[next]) == lex_Vedic) next++; return next; }
static int ends_double_consonant(wchar_t *word, int len) { /* Word must contain at least two characters in order to pass this * test */ if(len < 2) { return 0; } /* Run the test */ return (towlower(word[len-1]) == towlower(word[len-2]) && is_consonant(word, len-1) && is_consonant(word, len-2)); }
CFSWString syllabify2(CFSWString s) { CFSWString res; for (INTPTR i = 0; i < s.GetLength(); i++) { CFSWString c = s.GetAt(i); if (is_consonant(c) && is_vowel(s.GetAt(i - 1)) && is_vowel(s.GetAt(i + 1))) res += d; if (is_vowel(c) && is_vowel(s.GetAt(i - 1)) && is_vowel(s.GetAt(i + 1)) && c.ToLower() == s.GetAt(i + 1)) res += d; if (is_consonant(c) && is_consonant(s.GetAt(i - 1)) && is_vowel(s.GetAt(i + 1)) && has_vowel(res)) //küsitav res += d; res += c; } return res; }
/* Computes the measure of a string of characters. If we denote a * vowel to be v, a consonant to be c, a list of consecutive vowels to * be V and a list of consecutive consonants to be C, then the measure * m of a string is computed as [C](VC)^(m)[V] */ static int compute_measure(wchar_t* word, int len) { int measure, state, is_vowel; int i; measure = 0; /* state is 1 for vowel and 0 for consonant */ state = 0; for(i=0; i<len; i++) { /* Bit of error checking. Just ensure that we've not been passed * sentence rather than a word */ is_vowel = !is_consonant(word, i); if(is_vowel < 0) { return -1; } if( is_vowel ) { state = 1; } else { if(state == 1) { measure++; } state = 0; } } return measure; }
/* Checks if the character at index idx is a consonant. Here, the * definition of a consonant is a letter other than A, E, I, O, U and * other than Y preceded by a consonant */ static int is_consonant(wchar_t *word, int idx) { int i; if(idx < 0) { return 0; } /* Make sure we haven't been passed a character that is not a * letter*/ if(!isalpha(word[idx])) { return -1; } /* First check the non-conditional vowels */ for( i=0; i<wcslen(vowels); i++ ) { if( towlower(word[idx]) == vowels[i] ) { return 0; } } /* Check Y, our special case character */ if( towlower(word[idx]) == 'y' && is_consonant(word, --idx) ) { return 0; } return 1; }
static int FindBaseConsonant(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPCWSTR input, IndicSyllable *s, lexical_function lex, BOOL modern) { int i; BOOL blwf = FALSE; BOOL pref = FALSE; /* remove ralf from consideration */ if (Consonent_is_ralf(hdc, psa, psc, input, s, lex)) { s->ralf = s->start; s->start+=2; } /* try to find a base consonant */ if (!is_consonant( lex(input[s->base]) )) { for (i = s->end; i >= s->start; i--) if (is_consonant( lex(input[i]) )) { s->base = i; break; } } while ((blwf = Consonent_is_below_base_form(hdc, psa, psc, input, s, lex, modern)) || Consonent_is_post_base_form(hdc, psa, psc, input, s, lex, modern) || (pref = Consonent_is_pre_base_form(hdc, psa, psc, input, s, lex, modern))) { if (blwf && s->blwf == -1) s->blwf = s->base - 1; if (pref && s->pref == -1) s->pref = s->base - 1; for (i = s->base-1; i >= s->start; i--) if (is_consonant( lex(input[i]) )) { s->base = i; break; } } if (s->ralf >= 0) s->start = s->ralf; if (s->ralf == s->base) s->ralf = -1; return s->base; }
int main() { //check if it is a vowel printf("%d == %d\n", is_vowel('a'), true); printf("%d == %d\n", is_vowel('h'), false); //check if it is a lettere printf("%d == %d\n", is_letter('a'), true); printf("%d == %d\n", is_letter('#'), false); //checks if it is a consonant printf("%d == %d\n", is_consonant('a'), false); printf("%d == %d\n", is_consonant('c'), true); printf("%d == %d\n", is_consonant('Z'),true); printf("%d == %d\n", is_consonant('1'), false); return false; }
static int contains_vowel(wchar_t *word, int len) { int i; for(i=0; i<len; i++) { if(is_consonant(word, i) == 0) { return 1; } } return 0; }
static int contains_compound_consonant(char *x) { char *p, *q, *s; if (strlen(x) < 2) { return 0; } p = x; do { q = p + 1; s = q + 1; if (is_consonant(*p)) { if (is_consonant(*q)) return 1; if ((*q == 'y') && (is_consonant(*s))) return 1; } p++; } while (*p); return 0; }
static void pango_indic_engine_shape (PangoFont * font, const char *text, int length, PangoAnalysis * analysis, PangoGlyphString * glyphs) { PangoXSubfont subfont; int n_chars, n_glyph; int lvl; int i; gunichar *wc; int sb; int n_syls; gunichar **syls = g_new (gunichar *, 2); g_return_if_fail (font != NULL); g_return_if_fail (text != NULL); g_return_if_fail (length >= 0); g_return_if_fail (analysis != NULL); n_chars = n_glyph = g_utf8_strlen (text, length); lvl = pango_x_find_first_subfont (font, &default_charset, 1, &subfont); if (!lvl) { pango_x_fallback_shape (font, glyphs, text, n_chars); return; } pango_indic_split_out_characters (&script, text, n_chars, &wc, &n_glyph, glyphs); pango_indic_convert_vowels (&script, TRUE, &n_glyph, wc, pango_x_has_glyph (font, PANGO_X_MAKE_GLYPH(subfont, 0xc93e))); n_syls = 1; syls[0] = wc; sb = glyphs->log_clusters[0]; for (i = 0; i < n_chars; i++) { if (i && (is_consonant (wc[i]) | is_ind_vowel (wc[i])) && wc[i - 1] != VIRAMA) { syls = g_renew (gunichar *, syls, n_syls + 2); syls[n_syls] = wc + i; n_syls++; sb = glyphs->log_clusters[i]; } glyphs->log_clusters[i] = sb; }
static INT consonant_header(LPCWSTR input, INT cChar, INT start, INT next, lexical_function lex) { if (!is_consonant( lex(input[next]) )) return -1; next++; if ((next < cChar) && lex(input[next]) == lex_Nukta) next++; if ((next < cChar) && lex(input[next])==lex_Halant) { next++; if((next < cChar) && is_joiner( lex(input[next]) )) next++; if ((next < cChar) && is_consonant( lex(input[next]) )) return next; } else if ((next < cChar) && is_joiner( lex(input[next]) ) && lex(input[next+1])==lex_Halant) { next+=2; if ((next < cChar) && is_consonant( lex(input[next]) )) return next; } return -1; }
static int ends_consonant_vowel_consonant(wchar_t *word, int len) { int i; static const wchar_t exclude[] = L"wxy"; /* Word must contain at least three characters in order to pass this * test */ if(len < 3) { return 0; } /* Check if the last character in the string is on our exclusion * list. If so, then it will fail this test */ for(i=0; i<wcslen(exclude); i++) { if(word[len-1] == exclude[i]) { return 0; } } /* Run the test and return the result */ return (is_consonant(word, len-3) && !is_consonant(word, len-2) && is_consonant(word, len-1)); }
static void pango_indic_make_ligs (gunichar * start, gunichar * end) { int i; for (i = 0; i < (end-start-2);i++) { if (is_consonant (start[i])) { if (start[i+2]==RA && start[i+1]==VIRAMA) { start[i+1] = 0; start[i+2] = RA_SUBSCRIPT; } } } }
static BOOL Consonent_is_pre_base_form(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPCWSTR pwChar, IndicSyllable *s, lexical_function lexical, BOOL modern) { if (is_consonant(lexical(pwChar[s->base])) && s->base > s->start && lexical(pwChar[s->base-1]) == lex_Halant) { if (modern) return (SHAPE_does_GSUB_feature_apply_to_chars(hdc, psa, psc, &pwChar[s->base-1], 1, 2, "pref") > 0); else { WCHAR cc[2]; cc[0] = pwChar[s->base]; cc[1] = pwChar[s->base-1]; return (SHAPE_does_GSUB_feature_apply_to_chars(hdc, psa, psc, cc, 1, 2, "pref") > 0); } } return FALSE; }
static INT parse_consonant_syllable(LPCWSTR input, INT cChar, INT start, INT *main, INT next, lexical_function lex) { int check; int headers = 0; do { check = consonant_header(input,cChar,start,next,lex); if (check != -1) { next = check; headers++; } } while (check != -1); if (headers || is_consonant( lex(input[next]) )) { *main = next; next++; } else return -1; if ((next < cChar) && lex(input[next]) == lex_Nukta) next++; if ((next < cChar) && lex(input[next]) == lex_Anudatta) next++; if ((next < cChar) && lex(input[next]) == lex_Halant) { next++; if((next < cChar) && is_joiner( lex(input[next]) )) next++; } else if (next < cChar) { while((next < cChar) && is_matra( lex(input[next]) )) next++; if ((next < cChar) && lex(input[next]) == lex_Nukta) next++; if ((next < cChar) && lex(input[next]) == lex_Halant) next++; } if ((next < cChar) && lex(input[next]) == lex_Modifier) next++; if ((next < cChar) && lex(input[next]) == lex_Vedic) next++; return next; }
static void pango_indic_make_ligs (gunichar * start, gunichar * end) { int num = end - start; int i; for (i = 0; i < (end - start); i++) { gunichar t0 = pango_indic_get_char (start + i, end); gunichar t1 = pango_indic_get_char (start + 1 + i, end); if (is_consonant (t0) && t1 == VIRAMA) { start[i+0] = t0 + INTERMEDIATE_HALF_FORM_OFFSET; start[i+1] = 0; } } if (num > 2 && start[0] == INTERMEDIATE_HALF_FORM_OFFSET + RA) { for (i=1;i<num;i++) start[i-1] = start[i]; start[num-1] = RA_SUPERSCRIPT; } dev_mini_shuffle (start, end); for (i = 0; i < (end - start - 1); i++) if (is_intermediate_form (start[i])) { if (start[i+1] == RA) { start[i] = nominal_form (start[i]); start[i+1] = RA_SUBSCRIPT; } else if (start[i+1] == (RA + INTERMEDIATE_HALF_FORM_OFFSET)) { start[i] = nominal_form (start[i]); start[i+1] = RA_SUBSCRIPT; shuffle_one_along (start+2, end); start[i+2] = VIRAMA; } } }
CFSWString shift_pattern(CFSWString s) { if (s == L'j') return L'j'; else if (s == L'h') return L'h'; else if (s == L'v') return L'v'; else if (s.FindOneOf(L"sS") > -1) return L's'; else if (s.FindOneOf(L"lmnrLN") > -1) return L'L'; else if (s.FindOneOf(L"kptfšT") > -1) return L'Q'; else if (is_vowel(s)) return L'V'; else if (is_consonant(s)) return L'C'; return s; }
static int IC(char c) { return is_consonant(c); }
static char * split_lujvo (char *x) { static char result[2048]; int first=1; /* At start, so we can handle r and n hyphens */ result[0] = 0; while (1) { /* Advance x to look at the tail of the string. */ int len = strlen(x); switch (len) { case 0: case 1: case 2: /* Impossible */ return NULL; break; case 3: case 4: { char *comp = lookup_component(x); if (comp) { if (!first) strcat(result, "+"); strcat(result,comp); } return result; } break; case 5: if (!first) strcat(result, "+"); strcat(result, x); return result; break; default: { if (x[3] == 'y') { strip_leading_rafsi(&x, 3, 1, first, result); } else if (x[4] == 'y') { strip_leading_rafsi(&x, 4, 1, first, result); } else if (x[5] == 'y') { /* Handle cultural rafsi of form CCVVCy */ strip_leading_rafsi(&x, 5, 1, first, result); } else if ((x[6] == 'y') && (x[3] == '\'')) { /* Handle cultural rafsi of form CCV'VCy */ strip_leading_rafsi(&x, 6, 1, first, result); } else { /* Have to decide if there's an r/n hyphen */ if (!is_consonant(x[0])) return NULL; /* can't ever happen */ if (IC(x[1]) && IV(x[2])) { /* CCV at start */ strip_leading_rafsi(&x, 3, 0, first, result); } else if (IV(x[1]) && IC(x[2])) { strip_leading_rafsi(&x, 3, 0, first, result); } else if (IV(x[1])) { if (x[2] == '\'') { /* Everything pushed up by 1 */ if (IV(x[3])) { if (((x[4] == 'r') && (IC(x[5]))) || ((x[4] == 'n') && (x[5] == 'r'))) { /* This pattern can only occur if a hyphen is there. */ strip_leading_rafsi(&x, 4, 1, first, result); } else { strip_leading_rafsi(&x, 4, 0, first, result); } } else { /* CV'C form, impossible. */ return NULL; } } else { if (IV(x[2])) { if (((x[3] == 'r') && (IC(x[4]))) || ((x[3] == 'n') && (x[4] == 'r'))) { /* This pattern can only occur if a hyphen is there. */ strip_leading_rafsi(&x, 3, 1, first, result); } else { strip_leading_rafsi(&x, 3, 0, first, result); } } else { /* CVC form, no r/n hyphen */ strip_leading_rafsi(&x, 3, 0, first, result); } } } else { /* Impossible */ return NULL; } } } break; } first = 0; } }
static int is_consonantal_form (int q) { return (q == PANGO_ZERO_WIDTH_JOINER) || is_consonant (q) || (q >= 0xd000); }