]> git.lyx.org Git - lyx.git/blob - src/Row.h
Get rid of ugly font metrics workarounds.
[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
34  * RowList for display. Each Row contains position pointers
35  * into the first and last character positions of that row.
36  */
37 class Row {
38 public:
39 /**
40  * One element of a Row. It has a set of attributes that can be used
41  * by other methods that need to parse the Row contents.
42  */
43         struct Element {
44                 enum Type {
45                         STRING,
46                         COMPLETION,
47                         SEPARATOR,
48                         INSET,
49                         SPACE
50                 };
51
52                 Element(Type const t, pos_type p, Font const & f, Change const & ch)
53                         : type(t), pos(p), endpos(p + 1), inset(0),
54                           extra(0), font(f), change(ch), final(false) {}
55
56                 //
57                 bool isSeparator() const { return type == SEPARATOR; }
58                 // returns total width of element, including separator overhead
59                 double width() const { return dim.wid + extra; };
60                 // returns position in pixels (from the left) of position
61                 // \param i in the row element
62                 double pos2x(pos_type const i) const;
63
64                 // The kind of row element
65                 Type type;
66                 // position of the element in the paragraph
67                 pos_type pos;
68                 // first position after the element in the paragraph
69                 pos_type endpos;
70                 // The dimension of the chunk (does not contains the
71                 // separator correction)
72                 Dimension dim;
73
74                 // Non-zero only if element is an inset
75                 Inset const * inset;
76
77                 // Only non-null for separator elements
78                 double extra;
79
80                 // Non-empty if element is a string or separator
81                 docstring str;
82                 //
83                 Font font;
84                 //
85                 Change change;
86                 // is it possible to add contents to this element?
87                 bool final;
88
89                 friend std::ostream & operator<<(std::ostream & os, Element const & row);
90         };
91
92
93         ///
94         Row();
95         ///
96         bool changed() const { return changed_; }
97         ///
98         void setChanged(bool c) { changed_ = c; }
99         ///
100         void setCrc(size_type crc) const;
101         /// Set the selection begin and end.
102         /**
103           * This is const because we update the selection status only at draw()
104           * time.
105           */
106         void setSelection(pos_type sel_beg, pos_type sel_end) const;
107         ///
108         bool selection() const;
109         /// Set the selection begin and end and whether the left and/or right
110         /// margins are selected.
111         void setSelectionAndMargins(DocIterator const & beg,
112                 DocIterator const & end) const;
113
114         ///
115         void pos(pos_type p);
116         ///
117         pos_type pos() const { return pos_; }
118         ///
119         void endpos(pos_type p);
120         ///
121         pos_type endpos() const { return end_; }
122         ///
123         Dimension const & dimension() const { return dim_; }
124         ///
125         Dimension & dimension() { return dim_; }
126         ///
127         int height() const { return dim_.height(); }
128         ///
129         int width() const { return dim_.wid; }
130         ///
131         int ascent() const { return dim_.asc; }
132         ///
133         int descent() const { return dim_.des; }
134
135         ///
136         void add(pos_type pos, Inset const * ins, Dimension const & dim,
137                  Font const & f, Change const & ch);
138         ///
139         void add(pos_type pos, char_type const c,
140                  Font const & f, Change const & ch);
141         ///
142         void addCompletion(pos_type pos, docstring const & s,
143                            Font const & f, Change const & ch);
144         ///
145         void addSeparator(pos_type pos, char_type const c,
146                           Font const & f, Change const & ch);
147         ///
148         void addSpace(pos_type pos, int width, Font const & f, Change const & ch);
149
150         ///
151         typedef std::vector<Element> Elements;
152         ///
153         typedef Elements::iterator iterator;
154         ///
155         typedef Elements::const_iterator const_iterator;
156         ///
157         iterator begin() { return elements_.begin(); }
158         ///
159         iterator end() { return elements_.end(); }
160         ///
161         const_iterator begin() const { return elements_.begin(); }
162         ///
163         const_iterator end() const { return elements_.end(); }
164
165         ///
166         bool empty() const { return elements_.empty(); }
167         ///
168         Element & back() { return elements_.back(); }
169         ///
170         Element const & back() const { return elements_.back(); }
171         /// remove last element
172         void pop_back();
173         /// remove all row elements
174         void clear() { elements_.clear(); }
175         /**
176          * remove all elements after last separator and update endpos
177          * if necessary.
178          * \param keep is the minimum amount of text to keep.
179          */
180         void separate_back(pos_type keep);
181
182         /**
183          * If last element of the row is a string, compute its width
184          * and mark it final.
185          */
186         void finalizeLast();
187
188         /**
189          * Find sequences of RtL elements and reverse them.
190          * This should be called once the row is completely built.
191          */
192         void reverseRtL();
193
194         friend std::ostream & operator<<(std::ostream & os, Row const & row);
195
196         /// width of a separator (i.e. space)
197         double separator;
198         /// width of hfills in the label
199         double label_hfill;
200         /// the x position of the row
201         double x;
202         ///
203         mutable pos_type sel_beg;
204         ///
205         mutable pos_type sel_end;
206         ///
207         mutable bool begin_margin_sel;
208         ///
209         mutable bool end_margin_sel;
210
211 private:
212         /// Decides whether the margin is selected.
213         /**
214           * \param margin_begin
215           * \param beg
216           * \param end
217           */
218         bool isMarginSelected(bool left_margin, DocIterator const & beg,
219                 DocIterator const & end) const;
220
221         /**
222          * Returns true if a char or string with font \c f and change
223          * type \c ch can be added to the current last element of the
224          * row.
225          */
226         bool sameString(Font const & f, Change const & ch) const;
227
228         ///
229         Elements elements_;
230
231         /// has the Row appearance changed since last drawing?
232         mutable bool changed_;
233         /// CRC of row contents.
234         mutable size_type crc_;
235         /// first pos covered by this row
236         pos_type pos_;
237         /// one behind last pos covered by this row
238         pos_type end_;
239         /// Row dimension.
240         Dimension dim_;
241 };
242
243
244 } // namespace lyx
245
246 #endif