+int
+mtext__lowercase (MText *mt, int pos, int end)
+{
+ int opos = pos;
+ int c;
+ MText *orig = NULL;
+ MSymbol lang;
+
+ if (lowercase_precheck (mt, pos, end))
+ orig = mtext_dup (mt);
+
+ for (; pos < end; opos++)
+ {
+ c = mtext_ref_char (mt, pos);
+ lang = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
+
+ if (c == 0x03A3 && final_sigma (orig, opos))
+ REPLACE (gr03A3);
+
+ else if (lang == Mlt)
+ {
+ if (c == 0x00CC)
+ REPLACE (lt00CC);
+ else if (c == 0x00CD)
+ REPLACE (lt00CD);
+ else if (c == 0x0128)
+ REPLACE (lt0128);
+ else if (orig && more_above (orig, opos))
+ {
+ if (c == 0x0049)
+ REPLACE (lt0049);
+ else if (c == 0x004A)
+ REPLACE (lt004A);
+ else if (c == 0x012E)
+ REPLACE (lt012E);
+ else
+ LOOKUP;
+ }
+ else
+ LOOKUP;
+ }
+
+ else if (lang == Mtr || lang == Maz)
+ {
+ if (c == 0x0130)
+ REPLACE (tr0130);
+ else if (c == 0x0307 && after_i (orig, opos))
+ DELETE;
+ else if (c == 0x0049 && ! before_dot (orig, opos))
+ REPLACE (tr0049);
+ else
+ LOOKUP;
+ }
+
+ else
+ LOOKUP;
+ }
+
+ if (orig)
+ m17n_object_unref (orig);
+
+ return end;
+}
+
+int
+mtext__titlecase (MText *mt, int pos, int end)
+{
+ int opos = pos;
+ int c;
+ MText *orig = NULL;
+ MSymbol lang;
+ MPlist *pl;
+
+ /* Precheck for titlecase is identical to that for uppercase. */
+ if (uppercase_precheck (mt, pos, end))
+ orig = mtext_dup (mt);
+
+ for (; pos < end; opos++)
+ {
+ c = mtext_ref_char (mt, pos);
+ lang = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
+
+ if ((lang == Mtr || lang == Maz) && c == 0x0069)
+ REPLACE (tr0069);
+
+ else if (lang == Mlt && c == 0x0307 && after_soft_dotted (orig, opos))
+ DELETE;
+
+ else if ((pl = (MPlist *) mchartable_lookup (case_mapping, c)))
+ {
+ /* Titlecase is the 2nd element. */
+ MText *title
+ = (MText *) mplist_value (mplist_next (mplist_value (pl)));
+ int tlen = mtext_len (title);
+
+ if (mtext_ref_char (title, 0) != c || tlen > 1)
+ {
+ mtext_replace (mt, pos, pos + 1, title, 0, tlen);
+ pos += tlen;
+ end += tlen - 1;
+ }
+
+ else
+ pos++;
+ }
+
+ else
+ pos++;
+ }
+
+ if (orig)
+ m17n_object_unref (orig);
+
+ return end;
+}
+
+int
+mtext__uppercase (MText *mt, int pos, int end)
+{
+ int opos = pos;
+ int c;
+ MText *orig = NULL;
+ MSymbol lang;
+ MPlist *pl;
+
+ CASE_CONV_INIT (-1);
+
+ if (uppercase_precheck (mt, 0, end))
+ orig = mtext_dup (mt);
+
+ for (; pos < end; opos++)
+ {
+ c = mtext_ref_char (mt, pos);
+ lang = (MSymbol) mtext_get_prop (mt, pos, Mlanguage);
+
+ if (lang == Mlt && c == 0x0307 && after_soft_dotted (orig, opos))
+ DELETE;
+
+ else if ((lang == Mtr || lang == Maz) && c == 0x0069)
+ REPLACE (tr0069);
+
+ else
+ {
+ if ((pl = (MPlist *) mchartable_lookup (case_mapping, c)) != NULL)
+ {
+ MText *upper;
+ int ulen;
+
+ /* Uppercase is the 3rd element. */
+ upper = (MText *) mplist_value (mplist_next (mplist_next (mplist_value (pl))));
+ ulen = mtext_len (upper);
+
+ if (mtext_ref_char (upper, 0) != c || ulen > 1)
+ {
+ mtext_replace (mt, pos, pos + 1, upper, 0, ulen);
+ pos += ulen;
+ end += ulen - 1;
+ }
+
+ else
+ pos++;
+ }
+
+ else /* pl == NULL */
+ pos++;
+ }
+ }
+
+ if (orig)
+ m17n_object_unref (orig);
+
+ return end;
+}
+