4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author Lars Gullik Bjønnes
9 * \author Abdelrazak Younes
11 * Full author contact details are available in file CREDITS.
14 #ifndef TEXT_METRICS_H
15 #define TEXT_METRICS_H
18 #include "ParagraphMetrics.h"
20 #include "support/types.h"
22 #include <boost/utility.hpp>
23 #include <boost/tuple/tuple.hpp>
35 /// A map from a Text to the map of paragraphs metrics
39 /// Default constructor (only here for STL containers).
40 TextMetrics(): text_(0) {}
41 /// The only useful constructor.
42 TextMetrics(BufferView *, Text *);
44 ParagraphMetrics const & parMetrics(pit_type) const;
46 Dimension const & dimension() const;
47 Dimension const & dimension();
49 /// compute text metrics.
50 bool metrics(MetricsInfo & mi, Dimension & dim);
52 /// Gets the fully instantiated font at a given position in a paragraph
53 /// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
54 /// The difference is that this one is used for displaying, and thus we
55 /// are allowed to make cosmetic improvements. For instance make footnotes
57 Font getDisplayFont(pit_type pit,
60 /// There are currently two font mechanisms in LyX:
61 /// 1. The font attributes in a lyxtext, and
62 /// 2. The inset-specific font properties, defined in an inset's
63 /// metrics() and draw() methods and handed down the inset chain through
64 /// the pi/mi parameters, and stored locally in a lyxtext in font_.
65 /// This is where the two are integrated in the final fully realized
67 void applyOuterFont(Font &) const;
69 /// is this position in the paragraph right-to-left?
70 bool isRTL(CursorSlice const & sl, bool boundary) const;
71 /// is between pos-1 and pos an RTL<->LTR boundary?
72 bool isRTLBoundary(pit_type pit,
74 /// would be a RTL<->LTR boundary between pos and the given font?
75 bool isRTLBoundary(pit_type pit,
76 pos_type pos, Font const & font) const;
79 /// Rebreaks the given paragraph.
80 /// \retval true if a full screen redraw is needed.
81 /// \retval false if a single paragraph redraw is enough.
82 bool redoParagraph(pit_type const pit);
83 /// Clear cache of paragraph metrics
84 void clear() { par_metrics_.clear(); }
87 int ascent() const { return dim_.asc; }
89 int descent() const { return dim_.des; }
90 /// current text width.
91 int width() const { return dim_.wid; }
92 /// current text heigth.
93 int height() const { return dim_.height(); }
96 int maxWidth() const { return max_width_; }
98 int singleWidth(pit_type const pit, pos_type pos) const;
101 int rightMargin(ParagraphMetrics const & pm) const;
102 int rightMargin(pit_type const pit) const;
104 /** this calculates the specified parameters. needed when setting
105 * the cursor and when creating a visible row */
106 void computeRowMetrics(pit_type pit, Row & row) const;
109 void draw(PainterInfo & pi, int x, int y) const;
110 /// draw textselection
111 void drawSelection(PainterInfo & pi, int x, int y) const;
113 void drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) const;
117 ParagraphMetrics & parMetrics(pit_type, bool redo_paragraph);
119 /// the minimum space a manual label needs on the screen in pixels
120 int labelFill(pit_type const pit, Row const & row) const;
123 int labelEnd(pit_type const pit) const;
125 /// sets row.end to the pos value *after* which a row should break.
126 /// for example, the pos after which isNewLine(pos) == true
127 pit_type rowBreakPoint(
133 /// sets row.width to the minimum space a row needs on the screen in pixel
137 pos_type const first,
141 /// Calculate and set the height of the row
142 boost::tuple<int, int> rowHeight(
144 pos_type const first,
148 /// draw selection for a single row
149 void drawRowSelection(PainterInfo & pi, int x, Row const & row,
150 DocIterator const & beg, DocIterator const & end,
151 bool drawOnBegMargin, bool drawOnEndMargin) const;
155 /// returns the column near the specified x-coordinate of the row.
156 /// x is an absolute screen coord, it is set to the real beginning
158 pos_type getColumnNearX(pit_type pit, Row const & row, int & x,
159 bool & boundary) const;
161 /// returns pos in given par at given x coord.
162 pos_type x2pos(pit_type pit, int row, int x) const;
164 // FIXME: is there a need for this?
165 //int pos2x(pit_type pit, pos_type pos) const;
167 /** returns row near the specified
168 * y-coordinate in given paragraph (relative to the screen).
170 Row const & getRowNearY(int y,
173 /// returns the paragraph number closest to screen y-coordinate.
174 /// This method uses the BufferView CoordCache to locate the
175 /// paragraph. The y-coodinate is allowed to be off-screen and
176 /// the CoordCache will be automatically updated if needed. This is
177 /// the reason why we need a non const BufferView.
178 pit_type getPitNearY(int y);
180 /// sets cursor recursively descending into nested editable insets
182 \return the inset pointer if x,y is covering that inset
183 \param x,y are absolute screen coordinates.
184 \retval inset is non-null if the cursor is positionned inside
186 /// FIXME: cleanup to use BufferView::getCoveringInset() and
187 /// setCursorFromCoordinates() instead of checkInsetHit().
188 Inset * editXY(Cursor & cur, int x, int y);
190 /// sets cursor only within this Text.
191 /// x,y are screen coordinates
192 void setCursorFromCoordinates(Cursor & cur, int x, int y);
195 int cursorX(CursorSlice const & cursor,
196 bool boundary) const;
198 int cursorY(CursorSlice const & cursor,
199 bool boundary) const;
202 void cursorPrevious(Cursor & cur);
204 void cursorNext(Cursor & cur);
206 bool cursorHome(Cursor & cur);
208 bool cursorEnd(Cursor & cur);
210 void deleteLineForward(Cursor & cur);
212 /// is this row the last in the text?
213 bool isLastRow(pit_type pit, Row const & row) const;
214 /// is this row the first in the text?
215 bool isFirstRow(pit_type pit, Row const & row) const;
217 /// Returns an inset if inset was hit, or 0 if not.
218 /// \warning This method is not recursive! It will return the
219 /// outermost inset within this Text.
220 /// \sa BufferView::getCoveringInset() to get the innermost inset.
221 Inset * checkInsetHit(int x, int y);
224 * Returns the left beginning of the text.
225 * This information cannot be taken from the layout object, because
226 * in LaTeX the beginning of the text fits in some cases
227 * (for example sections) exactly the label-width.
229 int leftMargin(int max_width, pit_type pit, pos_type pos) const;
230 int leftMargin(int max_width, pit_type pit) const;
234 /// The BufferView owner.
237 /// The text contents (the model).
238 /// \todo FIXME: this should be const.
242 /// A map from paragraph index number to paragraph metrics
243 typedef std::map<pit_type, ParagraphMetrics> ParMetricsCache;
245 mutable ParMetricsCache par_metrics_;
249 /// FIXME: transfer this code in CoordCache here.
251 /// A map from paragraph index number to screen point
252 typedef std::map<pit_type, Point> InnerParPosCache;
253 /// A map from a Text to the map of paragraphs to screen points
254 typedef std::map<Text const *, InnerParPosCache> ParPosCache;
255 /// Paragraph grouped by owning text
261 /// our 'outermost' font.
262 /// This is handed down from the surrounding
263 /// inset through the pi/mi parameter (pi.base.font)
264 /// It is used in applyOuterFont() and setCharFont() for reasons
265 /// that are not clear... to hand hand the outermost language and
266 /// also for char style apparently.
270 /// return the default height of a row in pixels, considering font zoom
271 int defaultRowHeight();
275 #endif // TEXT_METRICS_H