/* textprop.c -- text property module.
- Copyright (C) 2003, 2004
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H15PRO112
You should have received a copy of the GNU Lesser General Public
License along with the m17n library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
02111-1307, USA. */
/***en
if (diff < 0)
{
- /* Adjust end poistions of properties starting before HEAD. */
+ /* Adjust end positions of properties starting before HEAD. */
for (i = 0; i < head->nprops; i++)
{
prop = head->stack[i];
}
-/* Delete volatile text properties between FROM and TO. If KEY is
- Mnil, we are going to delete text, thus both strongly and weakly
- volatile properties must be deleted. Otherwise we are going to
- modify a text property KEY, thus only strongly volatile properties
- whose key is not KEY must be deleted. */
+/* Delete volatile text properties between FROM and TO. If DELETING
+ is nonzero, we are going to delete text, thus both strongly and
+ weakly volatile properties must be deleted. Otherwise we are going
+ to modify a text property KEY, thus only strongly volatile
+ properties whose key is not KEY must be deleted. */
static void
-prepare_to_modify (MText *mt, int from, int to, MSymbol key)
+prepare_to_modify (MText *mt, int from, int to, MSymbol key, int deleting)
{
MTextPlist *plist = mt->plist, *prev = NULL;
int mask_bits = MTEXTPROP_VOLATILE_STRONG;
- int deleting = (key == Mnil) && (from < to);
- if (key == Mnil)
+ if (deleting)
mask_bits |= MTEXTPROP_VOLATILE_WEAK;
while (plist)
{
memset (prefix, 32, indent);
prefix[indent] = 0;
- fprintf (stderr, "(interval %d-%d (%d)", interval->start, interval->end,
- interval->nprops);
+ fprintf (mdebug__output, "(interval %d-%d (%d)",
+ interval->start, interval->end, interval->nprops);
for (i = 0; i < interval->nprops; i++)
- fprintf (stderr, "\n%s (%d %d/%d %d-%d 0x%x)",
+ fprintf (mdebug__output, "\n%s (%d %d/%d %d-%d 0x%x)",
prefix, i,
interval->stack[i]->control.ref_count,
interval->stack[i]->attach_count,
interval->stack[i]->start, interval->stack[i]->end,
(unsigned) interval->stack[i]->val);
- fprintf (stderr, ")");
+ fprintf (mdebug__output, ")");
}
void
memset (prefix, 32, indent);
prefix[indent] = 0;
- fprintf (stderr, "(properties");
+ fprintf (mdebug__output, "(properties");
if (! plist)
- fprintf (stderr, ")\n");
+ fprintf (mdebug__output, ")\n");
else
{
- fprintf (stderr, "\n");
+ fprintf (mdebug__output, "\n");
while (plist)
{
MInterval *interval = plist->head;
- fprintf (stderr, "%s (%s", prefix, msymbol_name (plist->key));
+ fprintf (mdebug__output, "%s (%s", prefix, msymbol_name (plist->key));
while (interval)
{
- fprintf (stderr, " (%d %d", interval->start, interval->end);
+ fprintf (mdebug__output, " (%d %d",
+ interval->start, interval->end);
if (interval->nprops > 0)
{
int i;
for (i = 0; i < interval->nprops; i++)
- fprintf (stderr, " 0x%x", (int) interval->stack[i]->val);
+ fprintf (mdebug__output, " 0x%x",
+ (int) interval->stack[i]->val);
}
- fprintf (stderr, ")");
+ fprintf (mdebug__output, ")");
interval = interval->next;
}
- fprintf (stderr, ")\n");
+ fprintf (mdebug__output, ")\n");
xassert (check_plist (plist, 0) == 0);
plist = plist->next;
}
int
mtext__prop_init ()
{
- text_property_table.count = 0;
+ M17N_OBJECT_ADD_ARRAY (text_property_table, "Text property");
Mtext_prop_serializer = msymbol ("text-prop-serializer");
Mtext_prop_deserializer = msymbol ("text-prop-deserializer");
return 0;
pool = next;
}
interval_pool_root.next = NULL;
- mdebug__report_object ("Text property", &text_property_table);
}
}
to = pos + len;
- prepare_to_modify (mt, pos, to, Mnil);
+ prepare_to_modify (mt, pos, to, Mnil, 1);
for (plist = mt->plist; plist; plist = plist->next)
{
MInterval *interval = pop_all_properties (plist, pos, to);
return;
}
if (pos > 0 && pos < mtext_nchars (mt))
- prepare_to_modify (mt, pos, pos, Mnil);
+ prepare_to_modify (mt, pos, pos, Mnil, 0);
for (pl_last = NULL, pl = mt->plist; pl; pl_last = pl, pl = pl->next)
{
}
}
+/* len1 > 0 && len2 > 0 */
+
void
-mtext__adjust_plist_for_change (MText *mt, int from, int to)
+mtext__adjust_plist_for_change (MText *mt, int pos, int len1, int len2)
{
- MTextPlist *plist;
+ int pos2 = pos + len1;
- prepare_to_modify (mt, from, to, Mnil);
- for (plist = mt->plist; plist; plist = plist->next)
+ prepare_to_modify (mt, pos, pos2, Mnil, 0);
+
+ if (len1 < len2)
{
- pop_all_properties (plist, from, to);
- xassert (check_plist (plist, 0) == 0);
+ int diff = len2 - len1;
+ MTextPlist *plist;
+
+ for (plist = mt->plist; plist; plist = plist->next)
+ {
+ MInterval *head = find_interval (plist, pos2);
+ MInterval *tail = plist->tail;
+ MTextProperty *prop;
+ int i;
+
+ if (head)
+ {
+ if (head->start == pos2)
+ head = head->prev;
+ while (tail != head)
+ {
+ for (i = 0; i < tail->nprops; i++)
+ {
+ prop = tail->stack[i];
+ if (prop->start == tail->start)
+ prop->start += diff, prop->end += diff;
+ }
+ tail->start += diff;
+ tail->end += diff;
+ tail = tail->prev;
+ }
+ }
+ for (i = 0; i < tail->nprops; i++)
+ tail->stack[i]->end += diff;
+ tail->end += diff;
+ }
+ }
+ else if (len1 > len2)
+ {
+ mtext__adjust_plist_for_delete (mt, pos + len2, len1 - len2);
}
}
M_CHECK_RANGE (mt, from, to, -1, 0);
- prepare_to_modify (mt, from, to, key);
+ prepare_to_modify (mt, from, to, key, 0);
plist = get_plist_create (mt, key, 1);
interval = pop_all_properties (plist, from, to);
prop = new_text_property (mt, from, to, key, val, 0);
M_CHECK_RANGE (mt, from, to, -1, 0);
- prepare_to_modify (mt, from, to, key);
+ prepare_to_modify (mt, from, to, key, 0);
plist = get_plist_create (mt, key, 1);
interval = pop_all_properties (plist, from, to);
if (num > 0)
M_CHECK_RANGE (mt, from, to, -1, 0);
- prepare_to_modify (mt, from, to, key);
+ prepare_to_modify (mt, from, to, key, 0);
plist = get_plist_create (mt, key, 1);
/* Find an interval that covers the position FROM. */
/* No property to pop. */
return 0;
- prepare_to_modify (mt, from, to, key);
+ prepare_to_modify (mt, from, to, key, 0);
/* If the found interval starts before FROM and has value(s), divide
it at FROM. */
M17N_OBJECT_REF (prop);
if (prop->mt)
mtext_detach_property (prop);
- prepare_to_modify (mt, from, to, prop->key);
+ prepare_to_modify (mt, from, to, prop->key, 0);
plist = get_plist_create (mt, prop->key, 1);
xassert (check_plist (plist, 0) == 0);
interval = pop_all_properties (plist, from, to);
if (! prop->mt)
return 0;
- prepare_to_modify (prop->mt, start, end, prop->key);
+ prepare_to_modify (prop->mt, start, end, prop->key, 0);
plist = get_plist_create (prop->mt, prop->key, 0);
xassert (plist);
detach_property (plist, prop, NULL);
M17N_OBJECT_REF (prop);
if (prop->mt)
mtext_detach_property (prop);
- prepare_to_modify (mt, from, to, prop->key);
+ prepare_to_modify (mt, from, to, prop->key, 0);
plist = get_plist_create (mt, prop->key, 1);
prop->mt = mt;
prop->start = from;
pointer to an appropriate serializer function.
@seealso
- mtext_serialize (), MTextPropSerializeFunc
+ mtext_serialize (), #MTextPropSerializeFunc
*/
/***ja
¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¡£
@seealso
- mtext_serialize (), MTextPropSerializeFunc
+ mtext_serialize (), #MTextPropSerializeFunc
*/
MSymbol Mtext_prop_serializer;
pointer to an appropriate deserializer function.
@seealso
- mtext_deserialize (), MTextPropSerializeFunc
+ mtext_deserialize (), #MTextPropSerializeFunc
*/
/***ja
¥Ý¥¤¥ó¥¿¤òÃͤȤ¹¤ë¥·¥ó¥Ü¥ë¥×¥í¥Ñ¥Æ¥£¤ò»ØÄꤹ¤ë¡£
@seealso
- mtext_deserialize (), MTextPropSerializeFunc
+ mtext_deserialize (), #MTextPropSerializeFunc
*/
MSymbol Mtext_prop_deserializer;
error code to the external variable #merror_code.
@seealso
- mtext_deserialize (), Mtext_prop_serializer */
+ mtext_deserialize (), #Mtext_prop_serializer */
/***ja
@brief M-text Ãæ¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥·¥ê¥¢¥é¥¤¥º¤¹¤ë.
¤òÀßÄꤹ¤ë¡£
@seealso
- mtext_deserialize (), Mtext_prop_serializer */
+ mtext_deserialize (), #Mtext_prop_serializer */
MText *
mtext_serialize (MText *mt, int from, int to, MPlist *property_list)
int n;
M_CHECK_RANGE (mt, from, to, NULL, NULL);
+ if (mt->format != MTEXT_FORMAT_US_ASCII
+ && mt->format != MTEXT_FORMAT_UTF_8)
+ mtext__adjust_format (mt, MTEXT_FORMAT_UTF_8);
+ if (MTEXT_DATA (mt)[mtext_nbytes (mt)] != 0)
+ MTEXT_DATA (mt)[mtext_nbytes (mt)] = 0;
doc = xmlParseMemory (XML_TEMPLATE, strlen (XML_TEMPLATE) + 1);
node = xmlDocGetRootElement (doc);
{
MSymbol key = MPLIST_VAL (pl);
- func = (MTextPropSerializeFunc) msymbol_get (key, Mtext_prop_serializer);
+ func = ((MTextPropSerializeFunc)
+ msymbol_get_func (key, Mtext_prop_serializer));
if (func)
extract_text_properties (mt, from, to, key, plist);
}
MPlist *serialized_plist;
xmlNodePtr child;
- func = (MTextPropSerializeFunc) msymbol_get (prop->key,
- Mtext_prop_serializer);
+ func = ((MTextPropSerializeFunc)
+ msymbol_get_func (prop->key, Mtext_prop_serializer));
serialized_plist = (func) (prop->val);
if (! serialized_plist)
continue;
mtext_reset (work);
- mplist__serialize (work, serialized_plist);
+ mplist__serialize (work, serialized_plist, 0);
child = xmlNewChild (node, NULL, (xmlChar *) "property", NULL);
xmlSetProp (child, (xmlChar *) "key",
(xmlChar *) MSYMBOL_NAME (prop->key));
@brief Deserialize text properties in an M-text.
The mtext_deserialize () function deserializes M-text $MT. $MT
- must be an XML having the followng DTD.
+ must be an XML having the following DTD.
@verbatim
<!DOCTYPE mtext [
code to the external variable #merror_code.
@seealso
- mtext_serialize (), Mtext_prop_deserializer */
+ mtext_serialize (), #Mtext_prop_deserializer */
/***ja
@brief M-text Ãæ¤Î¥Æ¥¥¹¥È¥×¥í¥Ñ¥Æ¥£¤ò¥Ç¥·¥ê¥¢¥é¥¤¥º¤¹¤ë.
¥³¡¼¥É¤òÀßÄꤹ¤ë¡£
@seealso
- mtext_serialize (), Mtext_prop_deserializer */
+ mtext_serialize (), #Mtext_prop_deserializer */
MText *
mtext_deserialize (MText *mt)
key = msymbol ((char *) key_str);
func = ((MTextPropDeserializeFunc)
- msymbol_get (key, Mtext_prop_deserializer));
+ msymbol_get_func (key, Mtext_prop_deserializer));
if (! func)
continue;
plist = mplist__from_string (val_str, strlen ((char *) val_str));