]> git.lyx.org Git - lyx.git/blob - src/mathed/InsetMathBox.cpp
fa3f5653241eb6fd876fac3a456bf4ed20c6a950
[lyx.git] / src / mathed / InsetMathBox.cpp
1 /**
2  * \file InsetMathBox.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  * \author Ling Li (InsetMathMakebox)
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "InsetMathBox.h"
15
16 #include "LaTeXFeatures.h"
17 #include "MathData.h"
18 #include "MathStream.h"
19 #include "MathSupport.h"
20 #include "MetricsInfo.h"
21
22 #include "frontends/Painter.h"
23
24 #include <ostream>
25
26
27 namespace lyx {
28
29 /////////////////////////////////////////////////////////////////////
30 //
31 // InsetMathBox
32 //
33 /////////////////////////////////////////////////////////////////////
34
35 InsetMathBox::InsetMathBox(Buffer * buf, docstring const & name)
36         : InsetMathNest(buf, 1), name_(name)
37 {}
38
39
40 void InsetMathBox::write(WriteStream & os) const
41 {
42         ModeSpecifier specifier(os, TEXT_MODE);
43         os << '\\' << name_ << '{' << cell(0) << '}';
44 }
45
46
47 void InsetMathBox::normalize(NormalStream & os) const
48 {
49         os << '[' << name_ << ' ';
50         //text_->write(buffer(), os);
51         os << "] ";
52 }
53
54
55 void InsetMathBox::mathmlize(MathStream & ms) const
56 {       
57         SetMode textmode(ms, true, "class='mathbox'");
58         ms << cell(0);
59 }
60
61
62 void InsetMathBox::htmlize(HtmlStream & ms) const
63 {
64         SetHTMLMode textmode(ms, true);
65         ms << cell(0);
66 }
67
68
69 void InsetMathBox::metrics(MetricsInfo & mi, Dimension & dim) const
70 {
71         FontSetChanger dummy(mi.base, "textnormal");
72         cell(0).metrics(mi, dim);
73         metricsMarkers(dim);
74 }
75
76
77 void InsetMathBox::draw(PainterInfo & pi, int x, int y) const
78 {
79         FontSetChanger dummy(pi.base, "textnormal");
80         cell(0).draw(pi, x, y);
81         drawMarkers(pi, x, y);
82 }
83
84
85 void InsetMathBox::infoize(odocstream & os) const
86 {       
87         os << "Box: " << name_;
88 }
89
90
91 void InsetMathBox::validate(LaTeXFeatures & features) const
92 {
93         if (name_ == "tag" || name_ == "tag*")
94                 features.require("amsmath");
95
96         cell(0).validate(features);
97 }
98
99
100
101 /////////////////////////////////////////////////////////////////////
102 //
103 // InsetMathFBox
104 //
105 /////////////////////////////////////////////////////////////////////
106
107
108 InsetMathFBox::InsetMathFBox(Buffer * buf)
109         : InsetMathNest(buf, 1)
110 {}
111
112
113 void InsetMathFBox::metrics(MetricsInfo & mi, Dimension & dim) const
114 {
115         FontSetChanger dummy(mi.base, "textnormal");
116         cell(0).metrics(mi, dim);
117         metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
118 }
119
120
121 void InsetMathFBox::draw(PainterInfo & pi, int x, int y) const
122 {
123         Dimension const dim = dimension(*pi.base.bv);
124         pi.pain.rectangle(x + 1, y - dim.ascent() + 1,
125                 dim.width() - 2, dim.height() - 2, Color_foreground);
126         FontSetChanger dummy(pi.base, "textnormal");
127         cell(0).draw(pi, x + 3, y);
128         setPosCache(pi, x, y);
129 }
130
131
132 void InsetMathFBox::write(WriteStream & os) const
133 {
134         ModeSpecifier specifier(os, TEXT_MODE);
135         os << "\\fbox{" << cell(0) << '}';
136 }
137
138
139 void InsetMathFBox::normalize(NormalStream & os) const
140 {
141         os << "[fbox " << cell(0) << ']';
142 }
143
144
145 void InsetMathFBox::mathmlize(MathStream & ms) const
146 {       
147         SetMode textmode(ms, true, "class='fbox'");
148         ms << cell(0);
149 }
150
151
152 void InsetMathFBox::htmlize(HtmlStream & ms) const
153 {
154         SetHTMLMode textmode(ms, true, "class='fbox'");
155         ms << cell(0);
156 }
157
158
159 void InsetMathFBox::infoize(odocstream & os) const
160 {
161         os << "FBox: ";
162 }
163
164
165 void InsetMathFBox::validate(LaTeXFeatures & features) const
166 {
167         // FIXME XHTML
168         // It'd be better to be able to get this from an InsetLayout, but at present
169         // InsetLayouts do not seem really to work for things that aren't InsetTexts.
170         if (features.runparams().math_flavor == OutputParams::MathAsMathML)
171                 features.addPreambleSnippet("<style type=\"text/css\">\n"
172                         "mtext.fbox { border: 1px solid black; }\n"
173                         "</style>");
174         else if (features.runparams().math_flavor == OutputParams::MathAsHTML)
175                 features.addPreambleSnippet("<style type=\"text/css\">\n"
176                         "span.fbox { border: 1px solid black; }\n"
177                         "</style>");
178         InsetMathNest::validate(features);
179 }
180
181
182
183 /////////////////////////////////////////////////////////////////////
184 //
185 // InsetMathMakebox
186 //
187 /////////////////////////////////////////////////////////////////////
188
189
190 InsetMathMakebox::InsetMathMakebox(Buffer * buf, bool framebox)
191         : InsetMathNest(buf, 3), framebox_(framebox)
192 {}
193
194
195 void InsetMathMakebox::metrics(MetricsInfo & mi, Dimension & dim) const
196 {
197         FontSetChanger dummy(mi.base, "textnormal");
198         
199         Dimension wdim;
200         static docstring bracket = from_ascii("[");
201         mathed_string_dim(mi.base.font, bracket, wdim);
202         int w = wdim.wid;
203         
204         Dimension dim0;
205         Dimension dim1;
206         Dimension dim2;
207         cell(0).metrics(mi, dim0);
208         cell(1).metrics(mi, dim1);
209         cell(2).metrics(mi, dim2);
210         
211         dim.wid = w + dim0.wid + w + w + dim1.wid + w + 2 + dim2.wid;
212         dim.asc = std::max(std::max(wdim.asc, dim0.asc), std::max(dim1.asc, dim2.asc)); 
213         dim.des = std::max(std::max(wdim.des, dim0.des), std::max(dim1.des, dim2.des));
214         
215         if (framebox_) {
216                 dim.wid += 4;
217                 dim.asc += 3;
218                 dim.des += 2;
219         } else {
220                 dim.asc += 1;
221                 dim.des += 1;
222         }
223         
224         metricsMarkers(dim);
225 }
226
227
228 void InsetMathMakebox::draw(PainterInfo & pi, int x, int y) const
229 {
230         drawMarkers(pi, x, y);
231         
232         FontSetChanger dummy(pi.base, "textnormal");
233         BufferView const & bv = *pi.base.bv;
234         int w = mathed_char_width(pi.base.font, '[');
235         
236         if (framebox_) {
237                 Dimension const dim = dimension(*pi.base.bv);
238                 pi.pain.rectangle(x + 1, y - dim.ascent() + 1,
239                                   dim.width() - 2, dim.height() - 2, Color_foreground);
240                 x += 2;
241         }
242         
243         drawStrBlack(pi, x, y, from_ascii("["));
244         x += w;
245         cell(0).draw(pi, x, y);
246         x += cell(0).dimension(bv).wid;
247         drawStrBlack(pi, x, y, from_ascii("]"));
248         x += w;
249
250         drawStrBlack(pi, x, y, from_ascii("["));
251         x += w;
252         cell(1).draw(pi, x, y);
253         x += cell(1).dimension(bv).wid;
254         drawStrBlack(pi, x, y, from_ascii("]"));
255         x += w + 2;
256
257         cell(2).draw(pi, x, y);
258 }
259
260
261 void InsetMathMakebox::write(WriteStream & os) const
262 {
263         ModeSpecifier specifier(os, TEXT_MODE);
264         os << (framebox_ ? "\\framebox" : "\\makebox");
265         if (cell(0).size() || !os.latex()) {
266                 os << '[' << cell(0) << ']';
267                 if (cell(1).size() || !os.latex())
268                         os << '[' << cell(1) << ']';
269         }
270         os << '{' << cell(2) << '}';
271 }
272
273
274 void InsetMathMakebox::normalize(NormalStream & os) const
275 {
276         os << (framebox_ ? "[framebox " : "[makebox ")
277            << cell(0) << ' ' << cell(1) << ' ' << cell(2) << ']';
278 }
279
280
281 void InsetMathMakebox::infoize(odocstream & os) const
282 {
283         os << (framebox_ ? "Framebox" : "Makebox") 
284            << " (width: " << cell(0)
285            << " pos: " << cell(1) << ")";
286 }
287
288
289 void InsetMathMakebox::mathmlize(MathStream & ms) const
290 {
291         // FIXME We could do something with the other arguments.
292         std::string const cssclass = framebox_ ? "framebox" : "makebox";
293         SetMode textmode(ms, true, "class='" + cssclass + "'");
294         ms << cell(2);
295 }
296
297
298 void InsetMathMakebox::htmlize(HtmlStream & ms) const
299 {
300         // FIXME We could do something with the other arguments.
301         std::string const cssclass = framebox_ ? "framebox" : "makebox";
302         SetHTMLMode textmode(ms, true, "class='" + cssclass + "'");
303         ms << cell(2);
304 }
305
306
307 void InsetMathMakebox::validate(LaTeXFeatures & features) const
308 {
309         // FIXME XHTML
310         // It'd be better to be able to get this from an InsetLayout, but at present
311         // InsetLayouts do not seem really to work for things that aren't InsetTexts.
312         if (features.runparams().math_flavor == OutputParams::MathAsMathML)
313                 features.addPreambleSnippet("<style type=\"text/css\">\n"
314                         "span.framebox { border: 1px solid black; }\n"
315                         "</style>");
316         else if (features.runparams().math_flavor == OutputParams::MathAsHTML)
317                 features.addPreambleSnippet("<style type=\"text/css\">\n"
318                         "span.framebox { border: 1px solid black; }\n"
319                         "</style>");
320         InsetMathNest::validate(features);
321 }
322
323
324 /////////////////////////////////////////////////////////////////////
325 //
326 // InsetMathBoxed
327 //
328 /////////////////////////////////////////////////////////////////////
329
330 InsetMathBoxed::InsetMathBoxed(Buffer * buf)
331         : InsetMathNest(buf, 1)
332 {}
333
334
335 void InsetMathBoxed::metrics(MetricsInfo & mi, Dimension & dim) const
336 {
337         cell(0).metrics(mi, dim);
338         metricsMarkers2(dim, 3); // 1 pixel space, 1 frame, 1 space
339 }
340
341
342 void InsetMathBoxed::draw(PainterInfo & pi, int x, int y) const
343 {
344         Dimension const dim = dimension(*pi.base.bv);
345         pi.pain.rectangle(x + 1, y - dim.ascent() + 1,
346                 dim.width() - 2, dim.height() - 2, Color_foreground);
347         cell(0).draw(pi, x + 3, y);
348         setPosCache(pi, x, y);
349 }
350
351
352 void InsetMathBoxed::write(WriteStream & os) const
353 {
354         ModeSpecifier specifier(os, MATH_MODE);
355         os << "\\boxed{" << cell(0) << '}';
356 }
357
358
359 void InsetMathBoxed::normalize(NormalStream & os) const
360 {
361         os << "[boxed " << cell(0) << ']';
362 }
363
364
365 void InsetMathBoxed::infoize(odocstream & os) const
366 {
367         os << "Boxed: ";
368 }
369
370
371 void InsetMathBoxed::mathmlize(MathStream & ms) const
372 {
373         SetMode mathmode(ms, false, "class='boxed'");
374         ms << cell(0);
375 }
376
377
378 void InsetMathBoxed::htmlize(HtmlStream & ms) const
379 {
380         SetHTMLMode mathmode(ms, false, "class='boxed'");
381         ms << cell(0);
382 }
383
384
385 void InsetMathBoxed::validate(LaTeXFeatures & features) const
386 {
387         features.require("amsmath");
388
389         // FIXME XHTML
390         // It'd be better to be able to get this from an InsetLayout, but at present
391         // InsetLayouts do not seem really to work for things that aren't InsetTexts.
392         if (features.runparams().math_flavor == OutputParams::MathAsMathML)
393                 features.addPreambleSnippet("<style type=\"text/css\">\n"
394                         "mstyle.boxed { border: 1px solid black; }\n"
395                         "</style>");
396         else if (features.runparams().math_flavor == OutputParams::MathAsHTML)
397                 features.addPreambleSnippet("<style type=\"text/css\">\n"
398                         "span.boxed { border: 1px solid black; }\n"
399                         "</style>");
400         
401         InsetMathNest::validate(features);
402 }
403
404
405 } // namespace lyx