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"
23 extern void mathed_set_font(short type, int style);
24 extern int mathed_char_width(short type, int style, byte c);
25 extern int mathed_string_width(short type, int style, byte const* s, int ls);
26 extern int mathed_string_height(short, int, byte const*, int, int&, int&);
27 extern int mathed_char_height(short, int, byte, int&, int&);
29 GC canvasGC=0, mathGC=0, mathLineGC=0, latexGC=0, cursorGC=0, mathFrameGC=0;
32 long unsigned int MathedInset::pm;
35 MathSpaceInset::Draw(int x, int y)
38 // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
40 // Sadly, HP-UX CC can't handle that kind of initialization.
43 p[0].x = ++x; p[0].y = y-3;
44 p[1].x = x; p[1].y = y;
45 p[2].x = x+width-2; p[2].y = y;
46 p[3].x = x+width-2; p[3].y = y-3;
48 XDrawLines(fl_display,pm,(space) ? latexGC: mathGC,p,4,CoordModeOrigin);
53 MathParInset::Draw(int x, int y)
57 int asc=df_asc, des=0;
61 if (!array || array->Empty()) {
62 mathed_set_font(LM_TC_VAR, 1);
64 MathedXIter data(this);
67 XDrawRectangle(fl_display,pm,mathLineGC,x,y-df_asc, df_width, df_asc);
71 MathedXIter data(this);
77 byte *s = data.GetString(ls);
78 drawStr(data.FCode(), size, x, y, s, ls);
79 mathed_char_height(data.FCode(), size, s[ls-1], asc, des);
83 if (MathIsInset(cx)) {
85 MathedInset *p = data.GetInset();
88 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
89 yy -= (asc + p->Descent()+4);
91 yy -= (p->Descent()>asc) ? p->Descent()+4: asc;
95 x -= (xp>p->Width()) ? p->Width()+(xp-p->Width())/2: xp;
96 yy += des + p->Ascent() + 2;
98 yy += des + p->Ascent()/2;
104 if (cx!=LM_TC_UP && cx!=LM_TC_DOWN) {
105 limits = p->GetLimits();
106 if (limits) xp = p->Width();
111 if ((cxp==cx || cxp==LM_TC_CR || data.IsFirst())) { // && objtype==L
112 XDrawRectangle(fl_display,pm,mathLineGC,
113 x,y-df_asc, df_width, df_asc);
121 if (cxp==LM_TC_TAB || cxp==LM_TC_CR || data.IsFirst()) { // && objtype==LM_OT_MATRIX) {
122 XDrawRectangle(fl_display,pm,mathLineGC,x,y-df_asc, df_width, df_asc);
128 fprintf(stderr, "GMathed Error: Unrecognized code[%d]\n", cx);
134 if (cxp==LM_TC_TAB || cxp==LM_TC_CR) { // && objtype==LM_OT_MATRIX) {
136 XDrawRectangle(fl_display,pm,mathLineGC,x,y-df_asc, df_width, df_asc);
143 MathParInset::Metrics()
147 int asc=df_asc, des=0;
152 ascent = df_asc;//mathed_char_height(LM_TC_VAR, size, 'I', asc, des);
156 if (array->Empty()) return;
159 MathedXIter data(this);
164 s = data.GetString(ls);
165 mathed_string_height(data.FCode(), size, s, ls, asc, des);
166 if (asc > ascent) ascent = asc;
167 if (des > descent) descent = des;
170 if (MathIsInset(cx)) {
171 MathedInset *p = data.GetInset();
175 asc += (limits) ? p->Height()+4: p->Ascent() +
176 ((p->Descent()>asc) ? p->Descent()-asc+4: 0);
178 if (cx==LM_TC_DOWN) {
179 des += ((limits) ? p->Height()+4: p->Height()-p->Ascent()/2);
184 if (asc > ascent) ascent = asc;
185 if (des > descent) descent = des;
186 if (cx!=LM_TC_UP && cx!=LM_TC_DOWN)
187 limits = p->GetLimits();
192 data.GetIncPos(x, y);
193 if (data.IsFirst() || cxp==LM_TC_TAB || cxp==LM_TC_CR) {
194 if (ascent<df_asc) ascent = df_asc;
197 data.setTab(x-tb, tab);
206 data.GetIncPos(x, y);
207 if (data.IsFirst() || cxp==LM_TC_TAB || cxp==LM_TC_CR) {
208 if (ascent<df_asc) ascent = df_asc;
211 data.setTab(x-tb, tab);
212 } else //if (GetColumns()==1)
215 data.GetIncPos(x, y);
217 if (ascent<df_asc) ascent = df_asc;
220 data.subMetrics(ascent, descent);
226 fprintf(stderr, "Mathed Error: Unrecognized code[%d]\n", cx);
231 data.GetIncPos(width, ls);
233 // No matter how simple is a matrix, it is NOT a subparagraph
235 if (cxp==LM_TC_TAB) {
236 if (ascent<df_asc) ascent = df_asc;
239 data.setTab(width-tb, tab);
243 data.subMetrics(ascent, descent);
248 MathSqrtInset::Draw(int x, int y)
250 MathParInset::Draw(x+hmax+2, y);
251 int h=ascent, d=descent, h2=Height()/2, w2 = (Height()>4*hmax)?hmax:hmax/2;
253 p[0].x = x + hmax + wbody, p[0].y = y-h;
254 p[1].x = x+hmax, p[1].y = y-h;
255 p[2].x = x+w2, p[2].y = y+d;
256 p[3].x = x, p[3].y = y+d-h2;
257 XDrawLines(fl_display, pm, mathLineGC,p, 4, CoordModeOrigin);
262 MathSqrtInset::Metrics()
264 MathParInset::Metrics();
268 hmax = mathed_char_height(LM_TC_VAR, size, 'I',a, b);
269 if (hmax<10) hmax = 10;
275 MathFracInset::Draw(int x, int y)
281 if (size==LM_ST_DISPLAY) size++;
282 MathParInset::Draw(x+(width-w0)/2, y - des0);
283 den->Draw(x+(width-w1)/2, y + den->Ascent() + 2 - dh);
285 if (objtype==LM_OT_FRAC)
286 XDrawLine(fl_display, pm, mathLineGC, x+2, y-dh, x+width-4, y - dh);
292 MathFracInset::Metrics()
296 dh = mathed_char_height(LM_TC_CONST, size, 'I', a, b)/2;
301 if (size==LM_ST_DISPLAY) size++;
302 MathParInset::Metrics();
305 int as = Height() + 2 + dh;
306 des0 = Descent() + 2 + dh;
309 width = ((w0 > w1) ? w0: w1) + 12;
311 descent = den->Height()+ 2 - dh;
317 MathBigopInset::Draw(int x, int y)
324 if (sym<256 || sym==LM_oint) {
326 c = (sym==LM_oint) ? LM_int: sym;
334 mathed_set_font(t, size);
336 XDrawArc(fl_display, pm, mathLineGC, x,y-5*width/4,width,width,0,23040);
340 XDrawString(fl_display, pm, mathGC, x, y, s, ls);
345 MathBigopInset::Metrics()
352 if (sym<256 || sym==LM_oint) {
354 c = (sym==LM_oint) ? LM_int: sym;
362 mathed_set_font(t, size);
363 mathed_string_height(t, size, (unsigned char const *)s, ls, ascent, descent);
364 width = mathed_string_width(t, size, (unsigned char const *)s, ls);
365 if (sym==LM_oint) width += 2;