+ begp = bol;
+ goto label_skip_tail;
+ }
+ /* fall down ... */
+
+ case coding_type_sjis:
+ case coding_type_big5:
+ /* We can skip all ASCII characters at the head and tail. */
+ if (eol_conversion)
+ while (begp < endp && *begp < 0x80 && *begp != '\n') begp++;
+ else
+ while (begp < endp && *begp < 0x80) begp++;
+ label_skip_tail:
+ if (eol_conversion)
+ while (begp < endp && endp[-1] < 0x80 && endp[-1] != '\n') endp--;
+ else
+ while (begp < endp && *(endp - 1) < 0x80) endp--;
+ break;
+
+ default:
+ abort ();
+ }
+
+ *beg += begp - begp_orig;
+ *end += endp - endp_orig;
+ return;
+}
+
+/* As shrinking conversion region requires some overhead, we don't try
+ shrinking if the length of conversion region is less than this
+ value. */
+static int shrink_conversion_region_threshhold = 1024;
+
+#define SHRINK_CONVERSION_REGION(beg, end, coding, str, encodep) \
+ do { \
+ if (*(end) - *(beg) > shrink_conversion_region_threshhold) \
+ { \
+ if (encodep) shrink_encoding_region (beg, end, coding, str); \
+ else shrink_decoding_region (beg, end, coding, str); \
+ } \
+ } while (0)
+
+static Lisp_Object
+code_convert_region_unwind (dummy)
+ Lisp_Object dummy;
+{
+ inhibit_pre_post_conversion = 0;
+ return Qnil;
+}
+
+/* Store information about all compositions in the range FROM and TO
+ of OBJ in memory blocks pointed by CODING->cmp_data. OBJ is a
+ buffer or a string, defaults to the current buffer. */
+
+void
+coding_save_composition (coding, from, to, obj)
+ struct coding_system *coding;
+ int from, to;
+ Lisp_Object obj;
+{
+ Lisp_Object prop;
+ int start, end;
+
+ if (coding->composing == COMPOSITION_DISABLED)
+ return;
+ if (!coding->cmp_data)
+ coding_allocate_composition_data (coding, from);
+ if (!find_composition (from, to, &start, &end, &prop, obj)
+ || end > to)
+ return;
+ if (start < from
+ && (!find_composition (end, to, &start, &end, &prop, obj)
+ || end > to))
+ return;
+ coding->composing = COMPOSITION_NO;
+ do
+ {
+ if (COMPOSITION_VALID_P (start, end, prop))
+ {
+ enum composition_method method = COMPOSITION_METHOD (prop);
+ if (coding->cmp_data->used + COMPOSITION_DATA_MAX_BUNCH_LENGTH
+ >= COMPOSITION_DATA_SIZE)
+ coding_allocate_composition_data (coding, from);
+ /* For relative composition, we remember start and end
+ positions, for the other compositions, we also remember
+ components. */
+ CODING_ADD_COMPOSITION_START (coding, start - from, method);
+ if (method != COMPOSITION_RELATIVE)
+ {
+ /* We must store a*/
+ Lisp_Object val, ch;
+
+ val = COMPOSITION_COMPONENTS (prop);
+ if (CONSP (val))
+ while (CONSP (val))
+ {
+ ch = XCAR (val), val = XCDR (val);
+ CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch));
+ }
+ else if (VECTORP (val) || STRINGP (val))
+ {
+ int len = (VECTORP (val)
+ ? XVECTOR (val)->size : XSTRING (val)->size);
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ ch = (STRINGP (val)
+ ? Faref (val, make_number (i))
+ : XVECTOR (val)->contents[i]);
+ CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (ch));
+ }
+ }
+ else /* INTEGERP (val) */
+ CODING_ADD_COMPOSITION_COMPONENT (coding, XINT (val));
+ }
+ CODING_ADD_COMPOSITION_END (coding, end - from);
+ }
+ start = end;
+ }
+ while (start < to
+ && find_composition (start, to, &start, &end, &prop, obj)
+ && end <= to);
+
+ /* Make coding->cmp_data point to the first memory block. */
+ while (coding->cmp_data->prev)
+ coding->cmp_data = coding->cmp_data->prev;
+ coding->cmp_data_start = 0;
+}
+
+/* Reflect the saved information about compositions to OBJ.
+ CODING->cmp_data points to a memory block for the informaiton. OBJ
+ is a buffer or a string, defaults to the current buffer. */
+
+void
+coding_restore_composition (coding, obj)
+ struct coding_system *coding;
+ Lisp_Object obj;
+{
+ struct composition_data *cmp_data = coding->cmp_data;
+
+ if (!cmp_data)
+ return;
+
+ while (cmp_data->prev)
+ cmp_data = cmp_data->prev;
+
+ while (cmp_data)
+ {
+ int i;
+
+ for (i = 0; i < cmp_data->used; i += cmp_data->data[i])
+ {
+ int *data = cmp_data->data + i;
+ enum composition_method method = (enum composition_method) data[3];
+ Lisp_Object components;
+
+ if (method == COMPOSITION_RELATIVE)
+ components = Qnil;
+ else
+ {
+ int len = data[0] - 4, j;
+ Lisp_Object args[MAX_COMPOSITION_COMPONENTS * 2 - 1];
+
+ for (j = 0; j < len; j++)
+ args[j] = make_number (data[4 + j]);
+ components = (method == COMPOSITION_WITH_ALTCHARS
+ ? Fstring (len, args) : Fvector (len, args));
+ }
+ compose_text (data[1], data[2], components, Qnil, obj);