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