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"
24 extern void mathed_set_font(short type, int style);
25 extern int mathed_char_width(short type, int style, byte c);
26 extern int mathed_string_width(short type, int style, byte const* s, int ls);
27 extern int mathed_string_height(short, int, byte const*, int, int&, int&);
28 extern int mathed_char_height(short, int, byte, int&, int&);
30 GC canvasGC= 0, mathGC= 0, mathLineGC= 0, latexGC= 0, cursorGC= 0, mathFrameGC= 0;
33 long unsigned int MathedInset::pm;
36 MathSpaceInset::Draw(int x, int y)
39 // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
41 // Sadly, HP-UX CC can't handle that kind of initialization.
44 p[0].x = ++x; p[0].y = y-3;
45 p[1].x = x; p[1].y = y;
46 p[2].x = x+width-2; p[2].y = y;
47 p[3].x = x+width-2; p[3].y = y-3;
49 XDrawLines(fl_display, pm,(space) ? latexGC: mathGC, p, 4, CoordModeOrigin);
54 MathParInset::Draw(int x, int y)
58 int asc= df_asc, des= 0;
62 if (!array || array->empty()) {
63 mathed_set_font(LM_TC_VAR, 1);
65 MathedXIter data(this);
68 XDrawRectangle(fl_display, pm, mathLineGC, x, y-df_asc, df_width, df_asc);
72 MathedXIter data(this);
78 byte *s = data.GetString(ls);
79 drawStr(data.FCode(), size, x, y, s, ls);
80 mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
84 if (MathIsInset(cx)) {
86 MathedInset *p = data.GetInset();
89 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
90 yy -= (asc + p->Descent()+4);
92 yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
94 if (cx == LM_TC_DOWN) {
96 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
97 yy += des + p->Ascent() + 2;
99 yy += des + p->Ascent()/2;
105 if (cx!= LM_TC_UP && cx!= LM_TC_DOWN) {
106 limits = p->GetLimits();
107 if (limits) xp = p->Width();
111 if (cx == LM_TC_TAB) {
112 if ((cxp == cx || cxp == LM_TC_CR || data.IsFirst())) { // && objtype == L
113 XDrawRectangle(fl_display, pm, mathLineGC,
114 x, y-df_asc, df_width, df_asc);
121 if (cx == LM_TC_CR) {
122 if (cxp == LM_TC_TAB || cxp == LM_TC_CR || data.IsFirst()) { // && objtype == LM_OT_MATRIX) {
123 XDrawRectangle(fl_display, pm, mathLineGC, x, y-df_asc, df_width, df_asc);
129 lyxerr << "GMathed Error: Unrecognized code[" << cx
136 if (cxp == LM_TC_TAB || cxp == LM_TC_CR) { // && objtype == LM_OT_MATRIX) {
138 XDrawRectangle(fl_display, pm, mathLineGC, x, y-df_asc, df_width, df_asc);
145 MathParInset::Metrics()
149 int asc= df_asc, des= 0;
154 ascent = df_asc;//mathed_char_height(LM_TC_VAR, size, 'I', asc, des);
158 if (array->empty()) return;
161 MathedXIter data(this);
166 s = data.GetString(ls);
167 mathed_string_height(data.FCode(), size, s, ls, asc, des);
168 if (asc > ascent) ascent = asc;
169 if (des > descent) descent = des;
171 mathed_char_height(LM_TC_CONST, size, 'y', asc, des);
173 if (MathIsInset(cx)) {
174 MathedInset *p = data.GetInset();
177 if (cx == LM_TC_UP) {
178 asc += (limits) ? p->Height()+4: p->Ascent() +
179 ((p->Descent()>asc) ? p->Descent()-asc+4: 0);
181 if (cx == LM_TC_DOWN) {
182 des += ((limits) ? p->Height()+4: p->Height()-p->Ascent()/2);
187 if (asc > ascent) ascent = asc;
188 if (des > descent) descent = des;
189 if (cx!= LM_TC_UP && cx!= LM_TC_DOWN)
190 limits = p->GetLimits();
193 if (cx == LM_TC_TAB) {
195 data.GetIncPos(x, y);
196 if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
197 if (ascent<df_asc) ascent = df_asc;
200 data.setTab(x-tb, tab);
206 if (cx == LM_TC_CR) {
209 data.GetIncPos(x, y);
210 if (data.IsFirst() || cxp == LM_TC_TAB || cxp == LM_TC_CR) {
211 if (ascent<df_asc) ascent = df_asc;
214 data.setTab(x-tb, tab);
215 } else //if (GetColumns() == 1)
218 data.GetIncPos(x, y);
220 if (ascent<df_asc) ascent = df_asc;
223 data.subMetrics(ascent, descent);
229 lyxerr << "Mathed Error: Unrecognized code[" << cx
235 data.GetIncPos(width, ls);
237 // No matter how simple is a matrix, it is NOT a subparagraph
239 if (cxp == LM_TC_TAB) {
240 if (ascent<df_asc) ascent = df_asc;
243 data.setTab(width-tb, tab);
247 data.subMetrics(ascent, descent);
252 MathSqrtInset::Draw(int x, int y)
254 MathParInset::Draw(x+hmax+2, y);
255 int h= ascent, d= descent, h2= Height()/2, w2 = (Height()>4*hmax)?hmax:hmax/2;
257 p[0].x = x + hmax + wbody, p[0].y = y-h;
258 p[1].x = x+hmax, p[1].y = y-h;
259 p[2].x = x+w2, p[2].y = y+d;
260 p[3].x = x, p[3].y = y+d-h2;
261 XDrawLines(fl_display, pm, mathLineGC, p, 4, CoordModeOrigin);
266 MathSqrtInset::Metrics()
268 MathParInset::Metrics();
272 hmax = mathed_char_height(LM_TC_VAR, size, 'I', a, b);
273 if (hmax<10) hmax = 10;
279 MathFracInset::Draw(int x, int y)
285 if (size == LM_ST_DISPLAY) size++;
286 MathParInset::Draw(x+(width-w0)/2, y - des0);
287 den->Draw(x+(width-w1)/2, y + den->Ascent() + 2 - dh);
289 if (objtype == LM_OT_FRAC)
290 XDrawLine(fl_display, pm, mathLineGC, x+2, y-dh, x+width-4, y - dh);
296 MathFracInset::Metrics()
300 dh = mathed_char_height(LM_TC_CONST, size, 'I', a, b)/2;
305 if (size == LM_ST_DISPLAY) size++;
306 MathParInset::Metrics();
309 int as = Height() + 2 + dh;
310 des0 = Descent() + 2 + dh;
313 width = ((w0 > w1) ? w0: w1) + 12;
315 descent = den->Height()+ 2 - dh;
321 MathBigopInset::Draw(int x, int y)
328 if (sym<256 || sym == LM_oint) {
330 c = (sym == LM_oint) ? LM_int: sym;
338 mathed_set_font(t, size);
339 if (sym == LM_oint) {
340 XDrawArc(fl_display, pm, mathLineGC, x, y-5*width/4, width, width, 0, 23040);
344 XDrawString(fl_display, pm, mathGC, x, y, s, ls);
349 MathBigopInset::Metrics()
356 if (sym<256 || sym == LM_oint) {
358 c = (sym == LM_oint) ? LM_int: sym;
366 mathed_set_font(t, size);
367 mathed_string_height(t, size, reinterpret_cast<const unsigned char*>(s), ls, ascent, descent);
368 width = mathed_string_width(t, size, reinterpret_cast<const unsigned char*>(s), ls);
369 if (sym == LM_oint) width += 2;