3 * Purpose: Implementation of insets for mathed
4 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5 * Created: January 1996
8 * Dependencies: Xlib, XForms
10 * Copyright: 1996, Alejandro Aguilar Sierra
14 * You are free to use and modify this code under the terms of
15 * the GNU General Public Licence version 2 or later.
21 #pragma implementation
24 #include "math_iter.h"
26 #include "math_inset.h"
27 #include "symbol_def.h"
28 #include "support/lstrings.h"
30 #include "mathed/support.h"
34 const int SizeInset = sizeof(char*) + 2;
36 //extern int mathed_char_width(short type, int style, byte c);
37 //extern int mathed_string_width(short type, int style, string const & s);
38 //extern int mathed_char_height(short, int, byte, int &, int &);
41 MathedIter::MathedIter()
42 : flags(0), fcode_(0), pos(0), row(0), col(0), ncols(0), array(0)
46 MathedArray * MathedIter::GetData() const
52 short MathedIter::fcode() const
58 void MathedIter::fcode(short c) const
63 byte MathedIter::at() const
68 byte MathedIter::at(int p) const
73 byte & MathedIter::at(int p)
78 int MathedIter::Empty() const
80 return array->last() <= 1;
84 int MathedIter::OK() const
86 return array && (pos < array->last());
90 void MathedIter::Reset()
92 if (array->last() > 0 && MathIsFont(at(0))) {
104 byte MathedIter::GetChar() const
114 string const MathedIter::GetString() const
122 for (; at(pos) >= ' ' && pos < array->last(); ++pos)
129 MathedInset * MathedIter::GetInset() const
133 array->raw_pointer_copy(&p, pos + 1);
136 lyxerr << "Math Error: This is not an inset["
137 << at(pos) << "]" << endl;
143 // An active math inset MUST be derived from MathParInset because it
144 // must have at least one paragraph to edit
145 MathParInset * MathedIter::GetActiveInset() const
148 return reinterpret_cast<MathParInset*>(GetInset());
150 lyxerr << "Math Error: This is not an active inset" << endl;
155 bool MathedIter::Next()
171 pos += sizeof(char*) + 2;
182 bool MathedIter::goNextCode(MathedTextCodes code)
193 void MathedIter::goPosAbs(int p)
196 while (pos < p && Next())
201 void MathedIter::insert(byte c, MathedTextCodes t)
206 if (t == LM_TC_TAB && col >= ncols - 1)
209 // Never more than one space // array->bf[pos-1] gives error from purify:
210 // Reading 1 byte from 0x47b857 in the heap.
212 // Address 0x47b857 is 1 byte before start of malloc'd block at
213 // 0x47b858 of 16 bytes.
215 if (c == ' ' && (at(pos) == ' ' || at(pos - 1) == ' '))
218 if (IsFont() && at(pos) == t) {
222 if (t != fcode() && pos > 0 && MathIsFont(at(pos - 1))) {
225 for (; k >= 0 && at(k) >= ' '; --k)
227 fcode( (k >= 0 && MathIsFont(at(k))) ? at(k) : -1 );
231 short const f = (at(pos) < ' ') ? 0 : fcode();
232 int shift = (t == fcode()) ? 1 : ((f) ? 3 : 2);
234 if (t == LM_TC_TAB || t == LM_TC_CR) {
244 if (pos < array->last())
245 array->move(pos, shift);
247 array->need_size(array->last() + shift);
248 array->last(array->last() + shift);
249 at(array->last()) = '\0';
254 at(pos + shift - 1) = fcode();
267 // Prepare to insert a non-char object
268 void MathedIter::split(int shift)
270 if (pos < array->last()) {
273 if (at(pos) >= ' ') {
274 if (pos> 0 && MathIsFont(at(pos - 1)))
282 array->move(pos, shift);
285 at(pos + shift - 1) = fcode();
289 array->need_size(array->last() + shift);
290 array->last(array->last() + shift);
293 at(array->last()) = '\0';
297 // I assume that both pos and pos2 are legal positions
298 void MathedIter::join(int pos2)
300 if (!OK() || pos2 <= pos)
304 if (pos > 0 && at(pos) >= ' ' && MathIsFont(at(pos - 1)))
307 if (MathIsFont(at(pos2 - 1)))
310 if (at(pos2) >= ' ') {
311 for (int p = pos2; p > 0; --p) {
312 if (MathIsFont(at(p))) {
320 array->move(pos2, pos - pos2);
324 void MathedIter::insertInset(MathedInset * p, int type)
327 if (!MathIsInset(type))
330 array->insertInset(pos, p, type);
334 int const shift = SizeInset;
336 if (!MathIsInset(type))
342 array->raw_pointer_insert(p, pos + 1);
345 at(array->last()) = '\0';
351 bool MathedIter::Delete()
357 byte const c = GetChar();
360 if (MathIsFont(at(pos - 1)) && at(pos + 1) < ' ') {
364 for (; i > 0 && !MathIsFont(at(i)); --i)
366 if (i > 0 && MathIsFont(at(i)))
373 if (MathIsInset(at(pos)))
374 shift = sizeof(char*) + 2;
375 else if (c == LM_TC_TAB || c == LM_TC_CR) {
377 // lyxerr <<"Es un tab.";
379 lyxerr << "Math Warning: expected inset." << endl;
385 array->move(pos + shift, -shift);
386 if (pos >= array->last())
387 pos = (array->last() > 0) ? array->last() : 0;
393 // Check consistency of tabs and crs
394 void MathedIter::checkTabs()
398 // MathedIter:Reset();
400 if ((IsTab() && col >= ncols - 1) || (IsCR() && !(MthIF_CR & flags))) {
405 if (IsCR() && col < ncols - 2)
406 insert(' ', LM_TC_TAB);
412 insert(' ', LM_TC_TAB);
418 // Try to adjust tabs in the expected place, as used in eqnarrays
420 // - If there are a relation operator, put tabs around it
421 // - If tehre are not a relation operator, put everything in the
423 void MathedIter::adjustTabs()
427 bool MathedIter::IsInset() const
429 return MathIsInset(at(pos));
433 bool MathedIter::IsActive() const
435 return MathIsActive(at(pos));
439 bool MathedIter::IsFont() const
441 return MathIsFont(at(pos));
445 bool MathedIter::IsScript() const
447 return MathIsScript(at(pos));
451 bool MathedIter::IsTab() const
453 return (at(pos) == LM_TC_TAB);
457 bool MathedIter::IsCR() const
459 return (at(pos) == LM_TC_CR);
463 MathedIter::MathedIter(MathedArray * d)
469 fcode( (array && IsFont()) ? at(0) : 0 );
473 void MathedIter::ipush()
475 stck.fcode = fcode();
482 void MathedIter::ipop()