+ /* In overwrite-mode, we substitute a character at point (C2,
+ hereafter) by C. For that, we delete C2 in advance. But,
+ just substituting C2 by C may move a remaining text in the
+ line to the right or to the left, which is not preferable.
+ So we insert more spaces or delete more characters in the
+ following cases: if C is narrower than C2, after deleting C2,
+ we fill columns with spaces, if C is wider than C2, we delete
+ C2 and several characters following C2. */
+
+ /* A code at `point'. Since this is checked only against
+ NEWLINE and TAB, we don't need a character code but only the
+ first byte of multi-byte form. */
+ unsigned char c2 = FETCH_BYTE (PT);
+ /* A column the cursor should be placed at after this insertion.
+ The correct value should be calculated only when necessary. */
+ int target_clm = 0;
+
+ /* Overwriting in binary-mode always substitute C2 by C. But,
+ overwriting in textual-mode does this substitution in the
+ case that C is not NEWLINE and C2 is not NEWLINE nor TAB. If
+ C2 is TAB, the substitution is done only when C2 is currently
+ expanded to 0 column, or more than 20 columns, or more than
+ the width of C. */
+ if (EQ (overwrite, Qoverwrite_mode_binary)
+ || (c != '\n'
+ && c2 != '\n'
+ && (target_clm = current_column() + WIDTH_BY_CHAR_HEAD (str[0]),
+ (c2 != '\t'
+ || XINT (current_buffer->tab_width) <= 0
+ || XFASTINT (current_buffer->tab_width) > 20
+ || !(target_clm % XFASTINT (current_buffer->tab_width))))))
+ {
+ if (target_clm == 0)
+ del_range (PT, forward_point (1));
+ else
+ {
+ int pos = point;
+ /* The actual cursor position after the trial of moving
+ to column TARGET_CLM. It is greater than TARGET_CLM
+ if the TARGET_CLM is middle of multi-column
+ character. In that case, the new point is set after
+ that character. */
+ int actual_clm = XFASTINT (Fmove_to_column (target_clm));
+
+ del_range (pos, PT);
+ if (actual_clm > target_clm)
+ {
+ /* We deleted too many columns. Let's fill columns
+ by spaces so that the remaining text won't move. */
+ insert(" ", actual_clm - target_clm);
+ SET_PT (pos);
+ }
+ }
+ hairy = 2;
+ }
+ hairy = 2;