1 // -*- C++ -*-
2 /**
3  * \file MathRow.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Jean-Marc Lasgouttes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11 
12 #ifndef MATH_ROW_H
13 #define MATH_ROW_H
14 
15 #include "InsetMath.h"
16 #include "MathClass.h"
17 
18 #include "ColorCode.h"
19 
20 #include "support/docstring.h"
21 
22 #include <vector>
23 
24 namespace lyx {
25 
26 class BufferView;
27 class Dimension;
28 class MetricsInfo;
29 class PainterInfo;
30 
31 class InsetMath;
32 class MathData;
33 
34 /*
35  * While for editing purpose it is important that macros are counted
36  * as a single element, this is not the case for display. To get the
37  * spacing correct, it is necessary to dissolve all the macros that
38  * can be, along with their arguments. Then one obtains a
39  * representation of the MathData contents as a string of insets and
40  * then spacing can be done properly.
41  *
42  * This is the purpose of the MathRow class.
43  */
44 class MathRow
45 {
46 public:
47 	// What row elements can be
48 	enum Type {
49 		INSET, // this element is a plain inset
50 		BOX, // an empty box
51 		BEGIN, // an inset and/or a math array begins here
52 		END, // an inset and/or a math array ends here
53 		DUMMY // a dummy element (used before or after row)
54 	};
55 
56 	// An elements, together with its spacing
57 	struct Element
58 	{
59 		///
60 		Element(MetricsInfo const & mi, Type t, MathClass mc = MC_UNKNOWN);
61 
62 		/// Classifies the contents of the object
63 		Type type;
64 		/// the class of the element
65 		MathClass mclass;
66 		/// the spacing around the element
67 		int before, after;
68 		/// count wether the current mathdata is nested in macro(s)
69 		int macro_nesting;
70 		/// Marker type
71 		InsetMath::marker_type marker;
72 
73 		/// When type is INSET
74 		/// the math inset (also for BEGIN and END)
75 		InsetMath const * inset;
76 		// Non empty when there is a completion to draw
77 		docstring compl_text;
78 		// the number of characters forming the unique part.
79 		size_t compl_unique_to;
80 
81 		// type is BEGIN, END
82 		MathData const * ar;
83 
84 		// type is BOX
85 		ColorCode color;
86 	};
87 
88 	///
MathRow()89 	MathRow() {};
90 	///
91 	typedef std::vector<Element> Elements;
92 	///
93 	typedef Elements::iterator iterator;
94 	///
95 	typedef Elements::const_iterator const_iterator;
96 	///
begin()97 	iterator begin() { return elements_.begin(); }
98 	///
end()99 	iterator end() { return elements_.end(); }
100 	///
begin()101 	const_iterator begin() const { return elements_.begin(); }
102 	///
end()103 	const_iterator end() const { return elements_.end(); }
104 	//
push_back(Element const & e)105 	void push_back(Element const & e) { elements_.push_back(e); }
106 	//
back()107 	Element & back() { return elements_.back(); }
108 
109 	// create the math row by unwinding all macros in the MathData and
110 	// compute the spacings.
111 	MathRow(MetricsInfo & mi, MathData const * ar);
112 
113 	// this returns true if the caret is here
114 	bool metrics(MetricsInfo & mi, Dimension & dim);
115 	//
116 	void draw(PainterInfo & pi, int const x, int const y) const;
117 
118 	/// superscript kerning
119 	int kerning(BufferView const *) const;
120 
121 private:
122 	// Index of the first inset element before position i
123 	int before(int i) const;
124 	// Index of the first inset element after position i
125 	int after(int i) const;
126 
127 	///
128 	Elements elements_;
129 };
130 
131 ///
132 std::ostream & operator<<(std::ostream & os, MathRow::Element const & elt);
133 
134 ///
135 std::ostream & operator<<(std::ostream & os, MathRow const & mrow);
136 
137 
138 } // namespace lyx
139 
140 #endif
141