3 * Purpose: Interaction and drawing for mathed
4 * Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
5 * Created: January 1996
6 * Description: Math drawing and interaction for a WYSIWYG math editor.
8 * Dependencies: Xlib, XForms
10 * Copyright: (c) 1996, Alejandro Aguilar Sierra
12 * Version: 0.8beta, Mathed & Lyx project.
14 * You are free to use and modify this code under the terms of
15 * the GNU General Public Licence version 2 or later.
19 #include FORMS_H_LOCATION
20 #include "math_cursor.h"
21 #include "math_parser.h"
26 extern LyXFont mathed_get_font(short type, int size);
27 extern int mathed_char_width(short type, int style, byte c);
28 extern int mathed_string_width(short type, int style, byte const* s, int ls);
29 extern int mathed_string_height(short, int, byte const*, int, int&, int&);
30 extern int mathed_char_height(short, int, byte, int&, int&);
33 MathSpaceInset::draw(Painter & pain, int x, int y)
36 // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
38 // Sadly, HP-UX CC can't handle that kind of initialization.
43 xp[0] = ++x; yp[0] = y - 3;
45 xp[2] = x + width - 2; yp[2] = y;
46 xp[3] = x + width - 2; yp[3] = y - 3;
48 pain.lines(xp, yp, 4, (space) ? LColor::latex : LColor::math);
53 MathParInset::draw(Painter & pain, int x, int y)
57 int asc = df_asc, des = 0;
61 if (!array || array->empty()) {
63 MathedXIter data(this);
66 pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
69 MathedXIter data(this);
75 byte * s = data.GetString(ls);
76 drawStr(pain, data.FCode(), size, x, y, s, ls);
77 mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
81 if (MathIsInset(cx)) {
83 MathedInset * p = data.GetInset();
86 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
87 yy -= (asc + p->Descent()+4);
89 yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
91 if (cx == LM_TC_DOWN) {
93 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
94 yy += des + p->Ascent() + 2;
96 yy += des + p->Ascent()/2;
101 p->draw(pain, x, yy);
102 if (cx!= LM_TC_UP && cx!= LM_TC_DOWN) {
103 limits = p->GetLimits();
104 if (limits) xp = p->Width();
108 if (cx == LM_TC_TAB) {
109 if ((cxp == cx || cxp == LM_TC_CR || data.IsFirst())) { // && objtype == L
110 pain.rectangle(x, y - df_asc, df_width, df_asc,
116 if (cx == LM_TC_CR) {
117 if (cxp == LM_TC_TAB || cxp == LM_TC_CR || data.IsFirst()) { // && objtype == LM_OT_MATRIX) {
118 pain.rectangle(x, y - df_asc, df_width, df_asc,
125 lyxerr << "GMathed Error: Unrecognized code[" << cx
132 if (cxp == LM_TC_TAB || cxp == LM_TC_CR) { // && objtype == LM_OT_MATRIX) {
134 pain.rectangle(x, y - df_asc, df_width, df_asc, LColor::mathline);
140 MathParInset::Metrics()
144 int asc= df_asc, des= 0;
149 ascent = df_asc;//mathed_char_height(LM_TC_VAR, size, 'I', asc, des);
153 if (array->empty()) return;
156 MathedXIter data(this);
161 s = data.GetString(ls);
162 mathed_string_height(data.FCode(), size, s, ls, asc, des);
163 if (asc > ascent) ascent = asc;
164 if (des > descent) descent = des;
166 mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
168 if (MathIsInset(cx)) {
169 MathedInset *p = data.GetInset();
172 if (cx == LM_TC_UP) {
173 asc += (limits) ? p->Height()+4: p->Ascent() +
174 ((p->Descent()>asc) ? p->Descent()-asc+4: 0);
176 if (cx == LM_TC_DOWN) {
177 des += ((limits) ? p->Height()+4: p->Height()-p->Ascent()/2);
182 if (asc > ascent) ascent = asc;
183 if (des > descent) descent = des;
184 if (cx!= LM_TC_UP && cx!= LM_TC_DOWN)
185 limits = p->GetLimits();
188 if (cx == LM_TC_TAB) {
190 data.GetIncPos(x, y);
191 if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
192 if (ascent<df_asc) ascent = df_asc;
195 data.setTab(x-tb, tab);
201 if (cx == LM_TC_CR) {
204 data.GetIncPos(x, y);
205 if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
206 if (ascent<df_asc) ascent = df_asc;
209 data.setTab(x-tb, tab);
210 } else //if (GetColumns() == 1)
213 data.GetIncPos(x, y);
215 if (ascent<df_asc) ascent = df_asc;
218 data.subMetrics(ascent, descent);
224 lyxerr << "Mathed Error: Unrecognized code[" << cx
230 data.GetIncPos(width, ls);
232 // No matter how simple is a matrix, it is NOT a subparagraph
234 if (cxp == LM_TC_TAB) {
235 if (ascent<df_asc) ascent = df_asc;
238 data.setTab(width-tb, tab);
242 data.subMetrics(ascent, descent);
247 MathSqrtInset::draw(Painter & pain, int x, int y)
249 MathParInset::draw(pain, x + hmax + 2, y);
252 int h2 = Height() / 2;
253 int w2 = (Height() > 4 * hmax) ? hmax : hmax / 2;
255 xp[0] = x + hmax + wbody; yp[0] = y - h;
256 xp[1] = x + hmax; yp[1] = y - h;
257 xp[2] = x + w2; yp[2] = y + d;
258 xp[3] = x; yp[3] = y + d - h2;
259 pain.lines(xp, yp, 4, LColor::mathline);
264 MathSqrtInset::Metrics()
266 MathParInset::Metrics();
270 hmax = mathed_char_height(LM_TC_VAR, size, 'I', a, b);
271 if (hmax < 10) hmax = 10;
278 MathFracInset::draw(Painter & pain, int x, int y)
284 if (size == LM_ST_DISPLAY) ++size;
285 MathParInset::draw(pain, x + (width - w0) / 2, y - des0);
286 den->draw(pain, x + (width - w1) / 2, y + den->Ascent() + 2 - dh);
288 if (objtype == LM_OT_FRAC)
289 pain.line(x + 2, y - dh, x + width - 4, y - dh, LColor::mathline);
295 MathFracInset::Metrics()
299 dh = mathed_char_height(LM_TC_CONST, size, 'I', a, b)/2;
304 if (size == LM_ST_DISPLAY) ++size;
305 MathParInset::Metrics();
308 int as = Height() + 2 + dh;
309 des0 = Descent() + 2 + dh;
312 width = ((w0 > w1) ? w0: w1) + 12;
314 descent = den->Height()+ 2 - dh;
320 MathBigopInset::draw(Painter & pain, int x, int y)
327 if (sym < 256 || sym == LM_oint) {
329 c = (sym == LM_oint) ? LM_int : sym;
337 if (sym == LM_oint) {
338 pain.arc(x, y - 5 * width / 4, width, width, 0, 360*64,
342 pain.text(x, y, s, ls, mathed_get_font(t, size));
347 MathBigopInset::Metrics()
354 if (sym < 256 || sym == LM_oint) {
356 c = (sym == LM_oint) ? LM_int: sym;
364 mathed_string_height(t, size,
365 reinterpret_cast<const unsigned char*>(s),
366 ls, ascent, descent);
367 width = mathed_string_width(t, size,
368 reinterpret_cast<const unsigned char*>(s),
370 if (sym == LM_oint) width += 2;