]> git.lyx.org Git - features.git/blob - src/mathed/InsetMathFrac.cpp
Fix bug 1527
[features.git] / src / mathed / InsetMathFrac.cpp
1 /**
2  * \file InsetMathFracBase.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alejandro Aguilar Sierra
7  * \author André Pönitz
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetMathFrac.h"
15
16 #include "Cursor.h"
17 #include "LaTeXFeatures.h"
18 #include "MathData.h"
19 #include "MathStream.h"
20 #include "MathSupport.h"
21 #include "MetricsInfo.h"
22 #include "TextPainter.h"
23
24 #include "frontends/Painter.h"
25
26 using namespace std;
27
28 namespace lyx {
29
30 /////////////////////////////////////////////////////////////////////
31 //
32 // InsetMathFracBase
33 //
34 /////////////////////////////////////////////////////////////////////
35
36
37 InsetMathFracBase::InsetMathFracBase(idx_type ncells)
38         : InsetMathNest(ncells)
39 {}
40
41
42 bool InsetMathFracBase::idxUpDown(Cursor & cur, bool up) const
43 {
44         InsetMath::idx_type target = !up; // up ? 0 : 1, since upper cell has idx 0
45         if (cur.idx() == target)
46                 return false;
47         cur.idx() = target;
48         cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
49         return true;
50 }
51
52
53
54 /////////////////////////////////////////////////////////////////////
55 //
56 // InsetMathFrac
57 //
58 /////////////////////////////////////////////////////////////////////
59
60
61 InsetMathFrac::InsetMathFrac(Kind kind, InsetMath::idx_type ncells)
62         : InsetMathFracBase(ncells), kind_(kind)
63 {}
64
65
66 Inset * InsetMathFrac::clone() const
67 {
68         return new InsetMathFrac(*this);
69 }
70
71
72 InsetMathFrac * InsetMathFrac::asFracInset()
73 {
74         return kind_ == ATOP ? 0 : this;
75 }
76
77
78 InsetMathFrac const * InsetMathFrac::asFracInset() const
79 {
80         return kind_ == ATOP ? 0 : this;
81 }
82
83
84 bool InsetMathFrac::idxForward(Cursor & cur) const
85 {
86         InsetMath::idx_type target = 0;
87         if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
88                 if (nargs() == 3)
89                         target = 0;
90                 else if (nargs() == 2)
91                         target = 1;
92         } else
93                 return false;
94         if (cur.idx() == target)
95                 return false;
96         cur.idx() = target;
97         cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
98         return true;
99 }
100
101
102 bool InsetMathFrac::idxBackward(Cursor & cur) const
103 {
104         InsetMath::idx_type target = 0;
105         if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
106                 if (nargs() == 3)
107                         target = 2;
108                 else if (nargs() == 2)
109                         target = 0;
110         } else
111                 return false;
112         if (cur.idx() == target)
113                 return false;
114         cur.idx() = target;
115         cur.pos() = cell(target).x2pos(&cur.bv(), cur.x_target());
116         return true;
117 }
118
119
120 void InsetMathFrac::metrics(MetricsInfo & mi, Dimension & dim) const
121 {
122         Dimension dim0, dim1, dim2;
123
124         if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
125                 if (nargs() == 1) {
126                         ShapeChanger dummy2(mi.base.font, UP_SHAPE);
127                         cell(0).metrics(mi, dim0);
128                         dim.wid = dim0.width()+ 3;
129                         dim.asc = dim0.asc;
130                         dim.des = dim0.des;
131                 } else if (nargs() == 2) {
132                         cell(0).metrics(mi, dim0);
133                         ShapeChanger dummy2(mi.base.font, UP_SHAPE);
134                         cell(1).metrics(mi, dim1);
135                         dim.wid = dim0.width() + dim1.wid + 5;
136                         dim.asc = max(dim0.asc, dim1.asc);
137                         dim.des = max(dim0.des, dim1.des);
138                 } else {
139                         cell(2).metrics(mi, dim2);
140                         ShapeChanger dummy2(mi.base.font, UP_SHAPE);
141                         FracChanger dummy(mi.base);
142                         cell(0).metrics(mi, dim0);
143                         cell(1).metrics(mi, dim1);
144                         dim.wid = dim0.width() + dim1.wid + dim2.wid + 10;
145                         dim.asc = max(dim2.asc, dim0.height() + 5);
146                         dim.des = max(dim2.des, dim1.height() - 5);
147                 }
148         } else {
149                 FracChanger dummy(mi.base);
150                 cell(0).metrics(mi, dim0);
151                 cell(1).metrics(mi, dim1);
152                 if (nargs() == 3)
153                         cell(2).metrics(mi, dim2);
154
155                 if (kind_ == NICEFRAC) {
156                         dim.wid = dim0.width() + dim1.wid + 5;
157                         dim.asc = dim0.height() + 5;
158                         dim.des = dim1.height() - 5;
159                 } else if (kind_ == UNITFRAC) {
160                         ShapeChanger dummy2(mi.base.font, UP_SHAPE);
161                         dim.wid = dim0.width() + dim1.wid + 5;
162                         dim.asc = dim0.height() + 5;
163                         dim.des = dim1.height() - 5;
164                 } else {
165                         dim.wid = max(dim0.width(), dim1.wid) + 2;
166                         dim.asc = dim0.height() + 2 + 5;
167                         dim.des = dim1.height() + 2 - 5;
168                 }
169         }
170         metricsMarkers(dim);
171 }
172
173
174 void InsetMathFrac::draw(PainterInfo & pi, int x, int y) const
175 {
176         setPosCache(pi, x, y);
177         Dimension const dim = dimension(*pi.base.bv);
178         Dimension const dim0 = cell(0).dimension(*pi.base.bv);
179         int m = x + dim.wid / 2;
180         if (kind_ == UNIT || (kind_ == UNITFRAC && nargs() == 3)) {
181                 if (nargs() == 1) {
182                         ShapeChanger dummy2(pi.base.font, UP_SHAPE);
183                         cell(0).draw(pi, x + 1, y);
184                 } else if (nargs() == 2) {
185                         cell(0).draw(pi, x + 1, y);
186                         ShapeChanger dummy2(pi.base.font, UP_SHAPE);
187                         cell(1).draw(pi, x + dim0.width() + 5, y);
188                 } else {
189                         cell(2).draw(pi, x + 1, y);
190                         ShapeChanger dummy2(pi.base.font, UP_SHAPE);
191                         FracChanger dummy(pi.base);
192                         Dimension const dim1 = cell(1).dimension(*pi.base.bv);
193                         Dimension const dim2 = cell(2).dimension(*pi.base.bv);
194                         int xx = x + dim2.wid + 5;
195                         cell(0).draw(pi, xx + 2, 
196                                          y - dim0.des - 5);
197                         cell(1).draw(pi, xx  + dim0.width() + 5, 
198                                          y + dim1.asc / 2);
199                 }
200         } else {
201                 FracChanger dummy(pi.base);
202                 Dimension const dim1 = cell(1).dimension(*pi.base.bv);
203                 if (kind_ == NICEFRAC) {
204                         cell(0).draw(pi, x + 2,
205                                         y - dim0.des - 5);
206                         cell(1).draw(pi, x + dim0.width() + 5,
207                                         y + dim1.asc / 2);
208                 } else if (kind_ == UNITFRAC) {
209                         ShapeChanger dummy2(pi.base.font, UP_SHAPE);
210                         cell(0).draw(pi, x + 2,
211                                         y - dim0.des - 5);
212                         cell(1).draw(pi, x + dim0.width() + 5,
213                                         y + dim1.asc / 2);
214                 } else {
215                         // Classical fraction
216                         cell(0).draw(pi, m - dim0.width() / 2,
217                                         y - dim0.des - 2 - 5);
218                         cell(1).draw(pi, m - dim1.wid / 2,
219                                         y + dim1.asc  + 2 - 5);
220                 }
221         }
222         if (kind_ == NICEFRAC || kind_ == UNITFRAC) {
223                 // Diag line:
224                 int xx = x;
225                 if (nargs() == 3)
226                         xx += cell(2).dimension(*pi.base.bv).wid + 5;
227
228                 pi.pain.line(xx + dim0.wid,
229                                 y + dim.des - 2,
230                                 xx + dim0.wid + 5,
231                                 y - dim.asc + 2, Color_math);
232         }
233         if (kind_ == FRAC || kind_ == OVER)
234                 pi.pain.line(x + 1, y - 5,
235                                 x + dim.wid - 2, y - 5, Color_math);
236         drawMarkers(pi, x, y);
237 }
238
239
240 void InsetMathFrac::metricsT(TextMetricsInfo const & mi, Dimension & dim) const
241 {
242         Dimension dim0, dim1;
243         cell(0).metricsT(mi, dim0);
244         cell(1).metricsT(mi, dim1);
245         dim.wid = max(dim0.width(), dim1.wid);
246         dim.asc = dim0.height() + 1;
247         dim.des = dim1.height();
248 }
249
250
251 void InsetMathFrac::drawT(TextPainter & /*pain*/, int /*x*/, int /*y*/) const
252 {
253         // FIXME: BROKEN!
254         /*
255         Dimension dim;
256         int m = x + dim.width() / 2;
257         cell(0).drawT(pain, m - dim0.width() / 2, y - dim0.des - 1);
258         cell(1).drawT(pain, m - dim1.wid / 2, y + dim1.asc);
259         // ASCII art: ignore niceties
260         if (kind_ == FRAC || kind_ == OVER || kind_ == NICEFRAC || kind_ == UNITFRAC)
261                 pain.horizontalLine(x, y, dim.width());
262         */
263 }
264
265
266 void InsetMathFrac::write(WriteStream & os) const
267 {
268         bool brace = os.pendingBrace();
269         os.pendingBrace(false);
270         if (os.latex() && os.textMode()) {
271                 os << "\\ensuremath{";
272                 os.textMode(false);
273                 brace = true;
274         }
275
276         switch (kind_) {
277         case ATOP:
278                 os << '{' << cell(0) << "\\atop " << cell(1) << '}';
279                 break;
280         case OVER:
281                 // \\over is only for compatibility, normalize this to \\frac
282                 os << "\\frac{" << cell(0) << "}{" << cell(1) << '}';
283                 break;
284         case FRAC:
285         case NICEFRAC:
286         case UNITFRAC:
287                 if (nargs() == 2)
288                         InsetMathNest::write(os);
289                 else
290                         os << "\\unitfrac[" << cell(2) << "]{" << cell(0) << "}{" << cell(1) << '}';
291                 break;
292         case UNIT:
293                 if (nargs() == 2)
294                         os << "\\unit[" << cell(0) << "]{" << cell(1) << '}';
295                 else
296                         os << "\\unit{" << cell(0) << '}';
297                 break;
298         }
299
300         os.pendingBrace(brace);
301 }
302
303
304 docstring InsetMathFrac::name() const
305 {
306         switch (kind_) {
307         case FRAC:
308                 return from_ascii("frac");
309         case OVER:
310                 return from_ascii("over");
311         case NICEFRAC:
312                 return from_ascii("nicefrac");
313         case UNITFRAC:
314                 return from_ascii("unitfrac");
315         case UNIT:
316                 return from_ascii("unit");
317         case ATOP:
318                 return from_ascii("atop");
319         }
320         // shut up stupid compiler
321         return docstring();
322 }
323
324
325 bool InsetMathFrac::extraBraces() const
326 {
327         return kind_ == ATOP || kind_ == OVER;
328 }
329
330
331 void InsetMathFrac::maple(MapleStream & os) const
332 {
333         os << '(' << cell(0) << ")/(" << cell(1) << ')';
334 }
335
336
337 void InsetMathFrac::mathematica(MathematicaStream & os) const
338 {
339         os << '(' << cell(0) << ")/(" << cell(1) << ')';
340 }
341
342
343 void InsetMathFrac::octave(OctaveStream & os) const
344 {
345         os << '(' << cell(0) << ")/(" << cell(1) << ')';
346 }
347
348
349 void InsetMathFrac::mathmlize(MathStream & os) const
350 {
351         os << MTag("mfrac") << cell(0) << cell(1) << ETag("mfrac");
352 }
353
354
355 void InsetMathFrac::validate(LaTeXFeatures & features) const
356 {
357         if (kind_ == NICEFRAC || kind_ == UNITFRAC || kind_ == UNIT)
358                 features.require("units");
359         InsetMathNest::validate(features);
360 }
361
362
363 /////////////////////////////////////////////////////////////////////
364 //
365 // InsetMathDFrac
366 //
367 /////////////////////////////////////////////////////////////////////
368
369
370 Inset * InsetMathDFrac::clone() const
371 {
372         return new InsetMathDFrac(*this);
373 }
374
375
376 void InsetMathDFrac::metrics(MetricsInfo & mi, Dimension & dim) const
377 {
378         Dimension dim0, dim1;
379         cell(0).metrics(mi, dim0);
380         cell(1).metrics(mi, dim1);
381         dim.wid = max(dim0.wid, dim1.wid) + 2;
382         dim.asc = dim0.height() + 2 + 5;
383         dim.des = dim1.height() + 2 - 5;
384 }
385
386
387 void InsetMathDFrac::draw(PainterInfo & pi, int x, int y) const
388 {
389         Dimension const dim = dimension(*pi.base.bv);
390         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
391         Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
392         int m = x + dim.wid / 2;
393         cell(0).draw(pi, m - dim0.wid / 2, y - dim0.des - 2 - 5);
394         cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc  + 2 - 5);
395         pi.pain.line(x + 1, y - 5, x + dim.wid - 2, y - 5, Color_math);
396         setPosCache(pi, x, y);
397 }
398
399
400 docstring InsetMathDFrac::name() const
401 {
402         return from_ascii("dfrac");
403 }
404
405
406 void InsetMathDFrac::mathmlize(MathStream & os) const
407 {
408         os << MTag("mdfrac") << cell(0) << cell(1) << ETag("mdfrac");
409 }
410
411
412 void InsetMathDFrac::validate(LaTeXFeatures & features) const
413 {
414         features.require("amsmath");
415         InsetMathNest::validate(features);
416 }
417
418
419 /////////////////////////////////////////////////////////////////////
420 //
421 // InsetMathTFrac
422 //
423 /////////////////////////////////////////////////////////////////////
424
425
426 Inset * InsetMathTFrac::clone() const
427 {
428         return new InsetMathTFrac(*this);
429 }
430
431
432 void InsetMathTFrac::metrics(MetricsInfo & mi, Dimension & dim) const
433 {
434         StyleChanger dummy(mi.base, LM_ST_SCRIPT);
435         Dimension dim0;
436         cell(0).metrics(mi, dim0);
437         Dimension dim1;
438         cell(1).metrics(mi, dim1);
439         dim.wid = max(dim0.width(), dim1.width()) + 2;
440         dim.asc = dim0.height() + 2 + 5;
441         dim.des = dim1.height() + 2 - 5;
442 }
443
444
445 void InsetMathTFrac::draw(PainterInfo & pi, int x, int y) const
446 {
447         StyleChanger dummy(pi.base, LM_ST_SCRIPT);
448         Dimension const dim = dimension(*pi.base.bv);
449         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
450         Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
451         int m = x + dim.wid / 2;
452         cell(0).draw(pi, m - dim0.width() / 2, y - dim0.descent() - 2 - 5);
453         cell(1).draw(pi, m - dim1.width() / 2, y + dim1.ascent()  + 2 - 5);
454         pi.pain.line(x + 1, y - 5, x + dim.wid - 2, y - 5, Color_math);
455         setPosCache(pi, x, y);
456 }
457
458
459 docstring InsetMathTFrac::name() const
460 {
461         return from_ascii("tfrac");
462 }
463
464
465 void InsetMathTFrac::mathmlize(MathStream & os) const
466 {
467         os << MTag("mtfrac") << cell(0) << cell(1) << ETag("mtfrac");
468 }
469
470
471 void InsetMathTFrac::validate(LaTeXFeatures & features) const
472 {
473         features.require("amsmath");
474         InsetMathNest::validate(features);
475 }
476
477
478 /////////////////////////////////////////////////////////////////////
479 //
480 // InsetMathBinom
481 //
482 /////////////////////////////////////////////////////////////////////
483
484
485 InsetMathBinom::InsetMathBinom(Kind kind)
486         : kind_(kind)
487 {}
488
489
490 Inset * InsetMathBinom::clone() const
491 {
492         return new InsetMathBinom(*this);
493 }
494
495
496 int InsetMathBinom::dw(int height) const
497 {
498         int w = height / 5;
499         if (w > 15)
500                 w = 15;
501         if (w < 6)
502                 w = 6;
503         return w;
504 }
505
506
507 void InsetMathBinom::metrics(MetricsInfo & mi, Dimension & dim) const
508 {
509         FracChanger dummy(mi.base);
510         Dimension dim0, dim1;
511         cell(0).metrics(mi, dim0);
512         cell(1).metrics(mi, dim1);
513         dim.asc = dim0.height() + 4 + 5;
514         dim.des = dim1.height() + 4 - 5;
515         dim.wid = max(dim0.width(), dim1.wid) + 2 * dw(dim.height()) + 4;
516         metricsMarkers2(dim);
517 }
518
519
520 void InsetMathBinom::draw(PainterInfo & pi, int x, int y) const
521 {
522         Dimension const dim = dimension(*pi.base.bv);
523         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
524         Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
525         docstring const bra = kind_ == BRACE ? from_ascii("{") :
526                               kind_ == BRACK ? from_ascii("[") : from_ascii("(");
527         docstring const ket = kind_ == BRACE ? from_ascii("}") :
528                               kind_ == BRACK ? from_ascii("]") : from_ascii(")");
529         int m = x + dim.width() / 2;
530         FracChanger dummy(pi.base);
531         cell(0).draw(pi, m - dim0.width() / 2, y - dim0.des - 3 - 5);
532         cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc  + 3 - 5);
533         mathed_draw_deco(pi, x, y - dim.ascent(), dw(dim.height()), dim.height(), bra);
534         mathed_draw_deco(pi, x + dim.width() - dw(dim.height()), y - dim.ascent(),
535                 dw(dim.height()), dim.height(), ket);
536         drawMarkers2(pi, x, y);
537 }
538
539
540 bool InsetMathBinom::extraBraces() const
541 {
542         return kind_ == CHOOSE || kind_ == BRACE || kind_ == BRACK;
543 }
544
545
546 void InsetMathBinom::write(WriteStream & os) const
547 {
548         bool brace = os.pendingBrace();
549         os.pendingBrace(false);
550         if (os.latex() && os.textMode()) {
551                 os << "\\ensuremath{";
552                 os.textMode(false);
553                 brace = true;
554         }
555
556         switch (kind_) {
557         case BINOM:
558                 os << "\\binom{" << cell(0) << "}{" << cell(1) << '}';
559                 break;
560         case CHOOSE:
561                 os << '{' << cell(0) << " \\choose " << cell(1) << '}';
562                 break;
563         case BRACE:
564                 os << '{' << cell(0) << " \\brace " << cell(1) << '}';
565                 break;
566         case BRACK:
567                 os << '{' << cell(0) << " \\brack " << cell(1) << '}';
568                 break;
569         }
570
571         os.pendingBrace(brace);
572 }
573
574
575 void InsetMathBinom::normalize(NormalStream & os) const
576 {
577         os << "[binom " << cell(0) << ' ' << cell(1) << ']';
578 }
579
580
581 void InsetMathBinom::validate(LaTeXFeatures & features) const
582 {
583         if (kind_ == BINOM)
584                 features.require("binom");
585         InsetMathNest::validate(features);
586 }
587
588
589 /////////////////////////////////////////////////////////////////////
590 //
591 // InsetMathDBinom
592 //
593 /////////////////////////////////////////////////////////////////////
594
595 Inset * InsetMathDBinom::clone() const
596 {
597         return new InsetMathDBinom(*this);
598 }
599
600
601 int InsetMathDBinom::dw(int height) const
602 {
603         int w = height / 5;
604         if (w > 15)
605                 w = 15;
606         if (w < 6)
607                 w = 6;
608         return w;
609 }
610
611
612 void InsetMathDBinom::metrics(MetricsInfo & mi, Dimension & dim) const
613 {
614         Dimension dim0, dim1;
615         cell(0).metrics(mi, dim0);
616         cell(1).metrics(mi, dim1);
617         dim.asc = dim0.height() + 4 + 5;
618         dim.des = dim1.height() + 4 - 5;
619         dim.wid = max(dim0.width(), dim1.wid) + 2 * dw(dim.height()) + 4;
620         metricsMarkers2(dim);
621 }
622
623
624 void InsetMathDBinom::draw(PainterInfo & pi, int x, int y) const
625 {
626         Dimension const dim = dimension(*pi.base.bv);
627         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
628         Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
629         int m = x + dim.width() / 2;
630         cell(0).draw(pi, m - dim0.width() / 2, y - dim0.des - 3 - 5);
631         cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc  + 3 - 5);
632         mathed_draw_deco(pi, x, y - dim.ascent(), dw(dim.height()), dim.height(), from_ascii("("));
633         mathed_draw_deco(pi, x + dim.width() - dw(dim.height()), y - dim.ascent(),
634                 dw(dim.height()), dim.height(), from_ascii(")"));
635         drawMarkers2(pi, x, y);
636 }
637
638
639 docstring InsetMathDBinom::name() const
640 {
641         return from_ascii("dbinom");
642 }
643
644 void InsetMathDBinom::mathmlize(MathStream & os) const
645 {
646         os << MTag("mdbinom") << cell(0) << cell(1) << ETag("mdbinom");
647 }
648
649 void InsetMathDBinom::validate(LaTeXFeatures & features) const
650 {
651         features.require("amsmath");
652         InsetMathNest::validate(features);
653 }
654
655
656 /////////////////////////////////////////////////////////////////////
657 //
658 // InsetMathTBinom
659 //
660 /////////////////////////////////////////////////////////////////////
661
662 Inset * InsetMathTBinom::clone() const
663 {
664         return new InsetMathTBinom(*this);
665 }
666
667
668 int InsetMathTBinom::dw(int height) const
669 {
670         int w = height / 5;
671         if (w > 15)
672                 w = 15;
673         if (w < 6)
674                 w = 6;
675         return w;
676 }
677
678
679 void InsetMathTBinom::metrics(MetricsInfo & mi, Dimension & dim) const
680 {
681         StyleChanger dummy(mi.base, LM_ST_SCRIPT);
682         Dimension dim0, dim1;
683         cell(0).metrics(mi, dim0);
684         cell(1).metrics(mi, dim1);
685         dim.asc = dim0.height() + 4 + 5;
686         dim.des = dim1.height() + 4 - 5;
687         dim.wid = max(dim0.width(), dim1.wid) + 2 * dw(dim.height()) + 4;
688         metricsMarkers2(dim);
689 }
690
691
692 void InsetMathTBinom::draw(PainterInfo & pi, int x, int y) const
693 {
694         StyleChanger dummy(pi.base, LM_ST_SCRIPT);
695         Dimension const dim = dimension(*pi.base.bv);
696         Dimension const & dim0 = cell(0).dimension(*pi.base.bv);
697         Dimension const & dim1 = cell(1).dimension(*pi.base.bv);
698         int m = x + dim.width() / 2;
699         cell(0).draw(pi, m - dim0.width() / 2, y - dim0.des - 3 - 5);
700         cell(1).draw(pi, m - dim1.wid / 2, y + dim1.asc  + 3 - 5);
701         mathed_draw_deco(pi, x, y - dim.ascent(), dw(dim.height()), dim.height(), from_ascii("("));
702         mathed_draw_deco(pi, x + dim.width() - dw(dim.height()), y - dim.ascent(),
703                 dw(dim.height()), dim.height(), from_ascii(")"));
704         drawMarkers2(pi, x, y);
705 }
706
707
708 docstring InsetMathTBinom::name() const
709 {
710         return from_ascii("tbinom");
711 }
712
713 void InsetMathTBinom::mathmlize(MathStream & os) const
714 {
715         os << MTag("mtbinom") << cell(0) << cell(1) << ETag("mtbinom");
716 }
717
718 void InsetMathTBinom::validate(LaTeXFeatures & features) const
719 {
720         features.require("amsmath");
721         InsetMathNest::validate(features);
722 }
723
724 } // namespace lyx