]> git.lyx.org Git - lyx.git/blob - src/Row.h
prepare Qt 5.6 builds
[lyx.git] / src / Row.h
1 // -*- C++ -*-
2 /**
3  * \file Row.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Matthias Ettrich
8  * \author Lars Gullik Bjønnes
9  *
10  * Full author contact details are available in file CREDITS.
11  *
12  * Metrics for an on-screen text row.
13  */
14
15 #ifndef ROW_H
16 #define ROW_H
17
18 #include "Changes.h"
19 #include "Dimension.h"
20 #include "Font.h"
21
22 #include "support/docstring.h"
23 #include "support/types.h"
24
25 #include <vector>
26
27 namespace lyx {
28
29 class DocIterator;
30 class Inset;
31
32 /**
33  * An on-screen row of text. A paragraph is broken into a RowList for
34  * display. Each Row contains a tokenized description of the contents
35  * of the line.
36  */
37 class Row {
38 public:
39         // Possible types of row elements
40         enum Type {
41                 // a string of character
42                 STRING,
43                 /**
44                  * Something (completion, end-of-par marker)
45                  * that occupies space one screen but does not
46                  * correspond to any paragraph contents
47                  */
48                 VIRTUAL,
49                 // An inset
50                 INSET,
51                 // Some spacing described by its width, not a string
52                 SPACE
53         };
54
55 /**
56  * One element of a Row. It has a set of attributes that can be used
57  * by other methods that need to parse the Row contents.
58  */
59         struct Element {
60                 Element(Type const t, pos_type p, Font const & f, Change const & ch)
61                         : type(t), pos(p), endpos(p + 1), inset(0),
62                           extra(0), font(f), change(ch), final(false) {}
63
64                 // Return total width of element, including separator overhead
65                 double full_width() const { return dim.wid + extra * countSeparators(); }
66                 // Return the number of separator in the element (only STRING type)
67                 int countSeparators() const;
68
69                 /** Return position in pixels (from the left) of position
70                  * \param i in the row element.
71                  */
72                 double pos2x(pos_type const i) const;
73                 /** Return character position that is the closest to
74                  *  pixel position \param x. The value \param x is
75                  *  adjusted to the actual pixel position.
76                 */
77                 pos_type x2pos(int &x) const;
78                 /** Break the element if possible, so that its width is less
79                  * than \param w. Returns true on success. When \param force
80                  * is true, the string is cut at any place, other wise it
81                  * respects the row breaking rules of characters.
82                  */
83                 bool breakAt(int w, bool force);
84
85                 // Returns the position on left side of the element.
86                 pos_type left_pos() const;
87                 // Returns the position on right side of the element.
88                 pos_type right_pos() const;
89
90                 //
91                 bool isRTL() const { return font.isVisibleRightToLeft(); }
92                 // This is true for virtual elements.
93                 // Note that we do not use the type here. The two definitions
94                 // should be equivalent
95                 bool isVirtual() const { return pos == endpos; }
96
97                 // The kind of row element
98                 Type type;
99                 // position of the element in the paragraph
100                 pos_type pos;
101                 // first position after the element in the paragraph
102                 pos_type endpos;
103                 // The dimension of the chunk (does not contains the
104                 // separator correction)
105                 Dimension dim;
106
107                 // Non-zero only if element is an inset
108                 Inset const * inset;
109
110                 // Only non-null for justified rows
111                 double extra;
112
113                 // Non-empty if element is a string or is virtual
114                 docstring str;
115                 //
116                 Font font;
117                 //
118                 Change change;
119                 // is it possible to add contents to this element?
120                 bool final;
121
122                 friend std::ostream & operator<<(std::ostream & os, Element const & row);
123         };
124
125
126         ///
127         Row();
128         ///
129         bool changed() const { return changed_; }
130         ///
131         void setChanged(bool c) { changed_ = c; }
132         ///
133         void setCrc(size_type crc) const;
134         /// Set the selection begin and end.
135         /**
136           * This is const because we update the selection status only at draw()
137           * time.
138           */
139         void setSelection(pos_type sel_beg, pos_type sel_end) const;
140         ///
141         bool selection() const;
142         /// Set the selection begin and end and whether the left and/or right
143         /// margins are selected.
144         void setSelectionAndMargins(DocIterator const & beg,
145                 DocIterator const & end) const;
146
147         ///
148         void pos(pos_type p) { pos_ = p; }
149         ///
150         pos_type pos() const { return pos_; }
151         ///
152         void endpos(pos_type p) { end_ = p; }
153         ///
154         pos_type endpos() const { return end_; }
155         ///
156         void right_boundary(bool b) { right_boundary_ = b; }
157         ///
158         bool right_boundary() const { return right_boundary_; }
159
160         ///
161         Dimension const & dimension() const { return dim_; }
162         ///
163         Dimension & dimension() { return dim_; }
164         ///
165         int height() const { return dim_.height(); }
166         /// The width of the row, including the left margin, but not the right one.
167         int width() const { return dim_.wid; }
168         ///
169         int ascent() const { return dim_.asc; }
170         ///
171         int descent() const { return dim_.des; }
172
173         /// The offset of the left-most cursor position on the row
174         int left_x() const;
175         /// The offset of the right-most cursor position on the row
176         int right_x() const;
177
178         // Return the number of separators in the row
179         int countSeparators() const;
180         // Set the extra spacing for every separator in STRING elements
181         void setSeparatorExtraWidth(double w);
182
183         ///
184         void add(pos_type pos, Inset const * ins, Dimension const & dim,
185                  Font const & f, Change const & ch);
186         ///
187         void add(pos_type pos, char_type const c,
188                  Font const & f, Change const & ch);
189         ///
190         void addVirtual(pos_type pos, docstring const & s,
191                         Font const & f, Change const & ch);
192         ///
193         void addSpace(pos_type pos, int width, Font const & f, Change const & ch);
194
195         ///
196         typedef std::vector<Element> Elements;
197         ///
198         typedef Elements::iterator iterator;
199         ///
200         typedef Elements::const_iterator const_iterator;
201         ///
202         iterator begin() { return elements_.begin(); }
203         ///
204         iterator end() { return elements_.end(); }
205         ///
206         const_iterator begin() const { return elements_.begin(); }
207         ///
208         const_iterator end() const { return elements_.end(); }
209
210         ///
211         bool empty() const { return elements_.empty(); }
212         ///
213         Element & front() { return elements_.front(); }
214         ///
215         Element const & front() const { return elements_.front(); }
216         ///
217         Element & back() { return elements_.back(); }
218         ///
219         Element const & back() const { return elements_.back(); }
220         /// remove last element
221         void pop_back();
222         /// remove all row elements
223         void clear() { elements_.clear(); }
224         /**
225          * if row width is too large, remove all elements after last
226          * separator and update endpos if necessary. If all that
227          * remains is a large word, cut it to \param width.
228          * \param body_pos minimum amount of text to keep.
229          * \param width maximum width of the row
230          */
231         void shortenIfNeeded(pos_type const body_pos, int const width);
232
233         /**
234          * If last element of the row is a string, compute its width
235          * and mark it final.
236          */
237         void finalizeLast();
238
239         /**
240          * Find sequences of right-to-left elements and reverse them.
241          * This should be called once the row is completely built.
242          */
243         void reverseRTL(bool rtl_par);
244
245         friend std::ostream & operator<<(std::ostream & os, Row const & row);
246
247         /// additional width for separators in justified rows (i.e. space)
248         double separator;
249         /// width of hfills in the label
250         double label_hfill;
251         /// the left margin position of the row
252         int left_margin;
253         /// the right margin of the row
254         int right_margin;
255         ///
256         mutable pos_type sel_beg;
257         ///
258         mutable pos_type sel_end;
259         ///
260         mutable bool begin_margin_sel;
261         ///
262         mutable bool end_margin_sel;
263
264 private:
265         /// Decides whether the margin is selected.
266         /**
267           * \param margin_begin
268           * \param beg
269           * \param end
270           */
271         bool isMarginSelected(bool left_margin, DocIterator const & beg,
272                 DocIterator const & end) const;
273
274         /**
275          * Returns true if a char or string with font \c f and change
276          * type \c ch can be added to the current last element of the
277          * row.
278          */
279         bool sameString(Font const & f, Change const & ch) const;
280
281         ///
282         Elements elements_;
283
284         /// has the Row appearance changed since last drawing?
285         mutable bool changed_;
286         /// CRC of row contents.
287         mutable size_type crc_;
288         /// first pos covered by this row
289         pos_type pos_;
290         /// one behind last pos covered by this row
291         pos_type end_;
292         // Is there is a boundary at the end of the row (display inset...)
293         bool right_boundary_;
294         /// Row dimension.
295         Dimension dim_;
296 };
297
298
299 } // namespace lyx
300
301 #endif