]> git.lyx.org Git - features.git/blob - src/mathed/array.C
0cec697b09b2cac159cfd75d439c0ba75e19f167
[features.git] / src / mathed / array.C
1
2 #include <config.h>
3
4 #ifdef __GNUG__
5 #pragma implementation
6 #endif
7
8 #include "debug.h"
9 #include "array.h"
10 #include "math_iter.h"
11 #include "math_inset.h"
12 #include "math_macro.h"
13
14 #include "support/LOstream.h"
15
16 using std::ostream;
17 using std::endl;
18
19 namespace {
20
21 inline
22 void * my_memcpy(void * ps_in, void const * pt_in, size_t n)
23 {
24         char * ps = static_cast<char *>(ps_in);
25         char const * pt = static_cast<char const *>(pt_in);
26         while (n--) *ps++ = *pt++;
27         return ps_in;
28 }
29
30 } // namespace anon
31
32
33 MathedArray::MathedArray()
34         : bf_(1, '\0'), last_(0)
35 {}
36
37
38 MathedArray::~MathedArray()
39 {
40         // deep destruction
41         // let's leak for a while... 
42 /*
43         MathedIter it;
44         it.SetData(this);
45         while (it.OK()) {
46                 if (it.IsInset()) {
47                         MathedInset * inset = it.GetInset();
48                         delete inset;
49                 }
50                 it.Next();
51         }
52 */
53 }
54
55
56 MathedArray::MathedArray(MathedArray const & array)
57 {
58         // this "implementation" is obviously wrong: MathedIter should be
59         // implemented by MathedArray (not the other way round) but I think
60         // getting the _interface_ of MathedArray right is more important right
61         // now (Andre')
62
63         // shallow copy
64         bf_   = array.bf_;
65         last_ = array.last_;
66
67         // deep copy
68         deep_copy();
69 }
70
71 void MathedArray::deep_copy()
72 {
73         MathedIter it(this);
74         while (it.OK()) {
75                 if (it.IsInset()) {
76                         MathedInset * inset = it.GetInset();
77                         inset = inset->Clone();
78                         raw_pointer_insert(inset, it.getPos() + 1);
79                 }
80                 it.Next();
81         }
82 }
83
84 void MathedArray::substitute(MathMacro * m)
85 {
86         if (m->nargs() == 0)
87                 return;
88
89         MathedIter it(this);
90         while (it.OK()) {
91                 if (it.IsInset()) {
92                         MathedInset * inset = it.GetInset();
93                         if (inset->GetType() == LM_OT_MACRO_ARG) {
94                                 int n = static_cast<MathMacroArgument *>(inset)->number() - 1;
95                                 //lyxerr << "substituting an argument inset: " << n << "\n";
96                                 inset = m->arg(n)->Clone();
97                         } else {
98                                 inset->substitute(m);
99                                 //lyxerr << "substituting in an ordinary inset\n";
100                         }
101                         raw_pointer_insert(inset, it.getPos() + 1);
102                 }
103                 it.Next();
104         }
105 }
106
107
108 MathedArray & MathedArray::operator=(MathedArray const & array)
109 {
110         MathedArray tmp(array);
111         swap(tmp);
112         return *this;
113 }
114
115 void MathedArray::clear()
116 {
117         last_ = 0;
118         bf_.resize(1);
119         bf_[0] = 0;
120 }
121
122 void MathedArray::swap(MathedArray & array)
123 {
124         if (this != &array) {
125                 bf_.swap(array.bf_);
126                 std::swap(last_, array.last_);
127         }
128 }
129
130
131 MathedArray::iterator MathedArray::begin() 
132 {
133         return bf_.begin();
134 }
135
136
137 MathedArray::iterator MathedArray::end() 
138 {
139         return bf_.end();
140 }
141
142
143 MathedArray::const_iterator MathedArray::begin() const
144 {
145         return bf_.begin();
146 }
147
148
149 MathedArray::const_iterator MathedArray::end() const
150 {
151         return bf_.end();
152 }
153
154
155 int MathedArray::empty() const
156 {
157         return (last_ == 0);
158 }
159    
160
161 int MathedArray::last() const
162 {
163         return last_;
164 }
165
166
167 void MathedArray::last(int l)
168 {
169         last_ = l;
170 }
171
172
173 void MathedArray::need_size(int needed)
174 {
175         if (needed >= static_cast<int>(bf_.size()))
176                 resize(needed);
177 }
178
179
180 void MathedArray::resize(int newsize)
181 {
182         // still a bit smelly...
183         ++newsize;
184         bf_.resize(newsize + 1);
185         if (last_ >= newsize)
186                 last_ = newsize - 1;
187         bf_[last_] = 0;
188 }
189
190
191 void MathedArray::move(int p, int shift)
192 {
193         if (p <= last_) {
194                 need_size(last_ + shift);
195                 memmove(&bf_[p + shift], &bf_[p], last_ - p);
196                 last_ += shift;
197                 bf_[last_] = 0;
198         }
199 }
200
201
202
203 void MathedArray::shrink(int pos1, int pos2)
204 {
205         if (pos1 == 0 && pos2 >= last())        
206                 return;
207
208         short fc = 0;
209         if (pos1 > 0 && bf_[pos1] > ' ') {
210                 for (int p = pos1; p >= 0; --p) {
211                         if (MathIsFont(bf_[p])) {
212                                 if (p != pos1 - 1)
213                                         fc = bf_[p];
214                                 else
215                                         --pos1;
216                                 break;
217                         }
218                 }
219         }
220
221         if (pos2 > 0 && bf_[pos2] >= ' ' && MathIsFont(bf_[pos2 - 1]))
222                 --pos2;
223
224         int dx = pos2 - pos1;
225         MathedArray a;
226         a.resize(dx + 1);
227         strange_copy(&a, (fc) ? 1 : 0, pos1, dx);
228         if (fc) {
229                 a[0] = fc;
230                 ++dx;
231         }
232         a.last(dx);
233         a[dx] = '\0';
234
235         swap(a);
236         deep_copy();
237 }
238
239
240 #if 0
241 void MathedArray::insert(MathedArray::iterator pos,
242                          MathedArray::const_iterator beg,
243                          MathedArray::const_iterator end)
244 {
245         bf_.insert(pos, beg, end);
246         last_ = bf_.size() - 1;
247 }
248 #else
249 void MathedArray::merge(MathedArray const & a, int p)
250 {
251         my_memcpy(&bf_[p], &a.bf_[0], a.last());
252 }
253 #endif
254
255
256 void MathedArray::raw_pointer_copy(MathedInset ** p, int pos) const
257 {
258         my_memcpy(p, &bf_[pos], sizeof(MathedInset*));
259 }
260
261
262 #if 0
263 void MathedArray::insertInset(int pos, MathedInset * p, int type)
264 {
265         //bf_.insert(pos, type);
266         InsetTable tmp(pos, p);
267         insetList_.push_back(tmp);
268 }
269
270
271 MathedInset * MathedArray::getInset(int pos) 
272 {
273         InsetList::const_iterator cit = insetList_.begin();
274         InsetList::const_iterator end = insetList_.end();
275         for (; cit != end; ++cit) {
276                 if ((*cit).pos == pos)
277                         return (*cit).inset;
278         }
279         // not found
280         return 0;
281         // We would really like to throw an exception instead... (Lgb)
282         // throw inset_not_found();
283 }
284
285 #else
286 void MathedArray::raw_pointer_insert(void * p, int pos)
287 {
288         my_memcpy(&bf_[pos], &p, sizeof(p));
289 }
290 #endif
291
292
293 void MathedArray::strange_copy(MathedArray * dest, int dpos,
294                                 int spos, int len)
295 {
296         my_memcpy(&dest->bf_[dpos], &bf_[spos], len);
297 }
298
299
300 byte MathedArray::operator[](int i) const
301 {
302         return bf_[i];
303 }
304
305
306 byte & MathedArray::operator[](int i)
307 {
308         return bf_[i];
309 }
310
311
312 void MathedArray::dump2(ostream & os) const
313 {
314         buffer_type::const_iterator cit = bf_.begin();
315         buffer_type::const_iterator end = bf_.end();
316         for (; cit != end; ++cit) {
317                 os << (*cit);
318         }
319         os << endl;
320 }
321
322 void MathedArray::dump(ostream & os) const
323 {
324         MathedIter it( const_cast<MathedArray*>(this) );
325         while (it.OK()) {
326                 if (it.IsInset()) {
327                         MathedInset * inset = it.GetInset();
328                         os << "<inset: " << inset << ">";
329                 } 
330                 else if (it.IsTab())
331                         os << "<tab>";
332                 else if (it.IsCR())
333                         os << "<cr>";
334                 else if (it.IsScript())
335                         os << "<script>";
336                 else if (it.IsFont())
337                         os << "<font: " << int(it.at()) << ">";
338                 else if (it.at() >= 32 && it.at() < 127)
339                         os << it.at();
340                 else
341                         os << "<unknown: " << int(it.at()) << ">";
342                 it.Next();
343         }
344 }
345
346