Backspace sends DEL instead of ^H.
[spft.git] / Run.cpp
bloba24147dd9c49cb7524b401cbf115284f7cca1cec
1 #include "Run.h"
2 #include "UTF8.h"
3 #include <stdlib.h>
4 #include <string.h>
7 Run::Run(Style style_in)
8 : style(style_in), is_tab(false), characters(nullptr)
13 Run::Run(char* initial_characters, Style style_in)
14 : style(style_in), is_tab(false), characters(initial_characters)
19 Run::~Run()
21 free((void*) characters);
25 int Run::num_characters()
27 if (characters == nullptr)
28 return 0;
29 return UTF8::num_characters(characters, strlen(characters));
33 void Run::append_characters(const char* new_chars, int num_bytes)
35 int old_length = 0;
36 if (characters) {
37 old_length = strlen(characters);
38 characters = (char*) realloc(characters, old_length + num_bytes + 1);
40 else
41 characters = (char*) malloc(num_bytes + 1);
42 memcpy(characters + old_length, new_chars, num_bytes);
43 characters[old_length + num_bytes] = 0;
47 void Run::replace_characters(int column, const char* new_chars, int num_bytes)
49 int old_length = 0;
50 int start_index = 0;
51 int replaced_bytes = 0;
52 if (characters) {
53 old_length = strlen(characters);
54 start_index = UTF8::bytes_for_n_characters(characters, old_length, column);
55 int num_chars = UTF8::num_characters(new_chars, num_bytes);
56 replaced_bytes =
57 UTF8::bytes_for_n_characters(
58 characters + start_index, old_length - start_index, num_chars);
60 char* new_bytes = (char*) malloc(old_length + num_bytes - replaced_bytes + 1);
62 // Build the new string.
63 // Initial old characters.
64 if (start_index > 0)
65 memcpy(new_bytes, characters, start_index);
66 // New characters.
67 memcpy(new_bytes + start_index, new_chars, num_bytes);
68 // Any bytes left after the replaced characters.
69 int bytes_left = old_length - (start_index + replaced_bytes);
70 if (bytes_left > 0) {
71 memcpy(
72 new_bytes + start_index + num_bytes,
73 characters + start_index + replaced_bytes,
74 bytes_left);
75 new_bytes[start_index + num_bytes + bytes_left] = 0;
77 else
78 new_bytes[start_index + num_bytes] = 0;
80 free(characters);
81 characters = new_bytes;
85 void Run::insert_characters(int column, const char* new_chars, int num_bytes)
87 if (characters == nullptr) {
88 append_characters(new_chars, num_bytes);
89 return;
92 // Build the new string.
93 int old_length = strlen(characters);
94 int start_index = UTF8::bytes_for_n_characters(characters, old_length, column);
95 char* new_bytes = (char*) malloc(old_length + num_bytes + 1);
96 // Initial old characters.
97 if (start_index > 0)
98 memcpy(new_bytes, characters, start_index);
99 // New characters.
100 memcpy(new_bytes + start_index, new_chars, num_bytes);
101 // Any bytes left after the replaced characters.
102 int bytes_left = old_length - start_index;
103 if (bytes_left > 0) {
104 memcpy(
105 new_bytes + start_index + num_bytes,
106 characters + start_index,
107 bytes_left);
108 new_bytes[start_index + num_bytes + bytes_left] = 0;
110 else
111 new_bytes[start_index + num_bytes] = 0;
113 free(characters);
114 characters = new_bytes;
118 void Run::append_spaces(int num_spaces)
120 int old_length = 0;
121 if (characters) {
122 old_length = strlen(characters);
123 characters = (char*) realloc(characters, old_length + num_spaces + 1);
125 else
126 characters = (char*) malloc(num_spaces + 1);
127 memset(characters + old_length, ' ', num_spaces);
128 characters[old_length + num_spaces] = 0;
132 void Run::shorten_to(int new_length)
134 // Don't bother to reallocate.
135 int end_index =
136 UTF8::bytes_for_n_characters(characters, strlen(characters), new_length);
137 characters[end_index] = 0;
141 void Run::delete_first_characters(int num_chars)
143 int old_num_bytes = strlen(characters);
144 int index =
145 UTF8::bytes_for_n_characters(characters, old_num_bytes, num_chars);
146 memmove(characters, characters + index, old_num_bytes - index + 1); // Include terminating zero byte.
147 characters = (char*) realloc(characters, old_num_bytes - index + 1);
151 void Run::delete_characters(int column, int num_chars)
153 // This is not called unless it has been determined that the deletion is
154 // entirely within the run.
155 int old_num_bytes = strlen(characters);
156 int start_index =
157 UTF8::bytes_for_n_characters(characters, old_num_bytes, column);
158 int end_index =
159 start_index +
160 UTF8::bytes_for_n_characters(
161 characters + start_index, old_num_bytes - start_index, num_chars);
162 memmove(
163 characters + start_index,
164 characters + end_index,
165 old_num_bytes - end_index);
166 characters[old_num_bytes - (end_index - start_index)] = 0;