2006-12-29 23:54:48 +00:00
|
|
|
|
// -*- C++ -*-
|
|
|
|
|
/**
|
|
|
|
|
* \file TextMetrics.h
|
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
|
|
|
|
*
|
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
* \author John Levon
|
|
|
|
|
* \author Abdelrazak Younes
|
|
|
|
|
*
|
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef TEXT_METRICS_H
|
|
|
|
|
#define TEXT_METRICS_H
|
|
|
|
|
|
2007-09-02 21:48:49 +00:00
|
|
|
|
#include "Font.h"
|
2007-09-11 16:04:10 +00:00
|
|
|
|
// FIXME: We only need Point class definition, not the full
|
|
|
|
|
// CoordCache.
|
|
|
|
|
#include "CoordCache.h"
|
2006-12-29 23:54:48 +00:00
|
|
|
|
#include "ParagraphMetrics.h"
|
|
|
|
|
|
|
|
|
|
#include "support/types.h"
|
|
|
|
|
|
2007-08-29 21:03:41 +00:00
|
|
|
|
#include <boost/utility.hpp>
|
|
|
|
|
#include <boost/tuple/tuple.hpp>
|
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
|
|
class BufferView;
|
2007-08-31 10:05:12 +00:00
|
|
|
|
class DocIterator;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
class MetricsInfo;
|
2007-08-31 10:05:12 +00:00
|
|
|
|
class Text;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
|
/// A map from a Text to the map of paragraphs metrics
|
2006-12-29 23:54:48 +00:00
|
|
|
|
class TextMetrics
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/// Default constructor (only here for STL containers).
|
|
|
|
|
TextMetrics(): text_(0) {}
|
|
|
|
|
/// The only useful constructor.
|
2007-04-29 23:33:02 +00:00
|
|
|
|
TextMetrics(BufferView *, Text *);
|
2007-09-11 16:04:10 +00:00
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
bool has(pit_type pit) const;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
///
|
|
|
|
|
ParagraphMetrics const & parMetrics(pit_type) const;
|
2007-09-15 12:28:41 +00:00
|
|
|
|
///
|
2007-09-20 08:48:28 +00:00
|
|
|
|
std::pair<pit_type, ParagraphMetrics const *> first() const;
|
2007-09-15 12:28:41 +00:00
|
|
|
|
///
|
2007-09-20 08:48:28 +00:00
|
|
|
|
std::pair<pit_type, ParagraphMetrics const *> last() const;
|
2007-09-15 12:28:41 +00:00
|
|
|
|
|
2007-09-12 12:07:45 +00:00
|
|
|
|
///
|
|
|
|
|
int parPosition(pit_type pit) const;
|
2007-09-05 13:04:05 +00:00
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
///
|
2007-09-17 21:45:14 +00:00
|
|
|
|
Dimension const & dimension() const { return dim_; }
|
2007-09-11 16:04:10 +00:00
|
|
|
|
|
|
|
|
|
Point const & origin() const { return origin_; }
|
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-09-15 12:28:41 +00:00
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
/// compute text metrics.
|
2007-09-18 08:52:38 +00:00
|
|
|
|
bool metrics(MetricsInfo & mi, Dimension & dim, int min_width = 0);
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-09-15 12:28:41 +00:00
|
|
|
|
///
|
|
|
|
|
void newParMetricsDown();
|
|
|
|
|
///
|
|
|
|
|
void newParMetricsUp();
|
|
|
|
|
|
2007-09-02 21:48:49 +00:00
|
|
|
|
/// Gets the fully instantiated font at a given position in a paragraph
|
|
|
|
|
/// Basically the same routine as Paragraph::getFont() in Paragraph.cpp.
|
|
|
|
|
/// The difference is that this one is used for displaying, and thus we
|
|
|
|
|
/// are allowed to make cosmetic improvements. For instance make footnotes
|
|
|
|
|
/// smaller. (Asger)
|
2007-09-02 22:28:49 +00:00
|
|
|
|
Font getDisplayFont(pit_type pit,
|
2007-09-02 21:48:49 +00:00
|
|
|
|
pos_type pos) const;
|
|
|
|
|
|
|
|
|
|
/// There are currently two font mechanisms in LyX:
|
|
|
|
|
/// 1. The font attributes in a lyxtext, and
|
|
|
|
|
/// 2. The inset-specific font properties, defined in an inset's
|
|
|
|
|
/// metrics() and draw() methods and handed down the inset chain through
|
|
|
|
|
/// the pi/mi parameters, and stored locally in a lyxtext in font_.
|
|
|
|
|
/// This is where the two are integrated in the final fully realized
|
|
|
|
|
/// font.
|
|
|
|
|
void applyOuterFont(Font &) const;
|
|
|
|
|
|
|
|
|
|
/// is this position in the paragraph right-to-left?
|
|
|
|
|
bool isRTL(CursorSlice const & sl, bool boundary) const;
|
|
|
|
|
/// is between pos-1 and pos an RTL<->LTR boundary?
|
2007-09-02 22:28:49 +00:00
|
|
|
|
bool isRTLBoundary(pit_type pit,
|
2007-09-02 21:48:49 +00:00
|
|
|
|
pos_type pos) const;
|
|
|
|
|
/// would be a RTL<->LTR boundary between pos and the given font?
|
2007-09-02 22:28:49 +00:00
|
|
|
|
bool isRTLBoundary(pit_type pit,
|
2007-09-02 21:48:49 +00:00
|
|
|
|
pos_type pos, Font const & font) const;
|
|
|
|
|
|
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
/// Rebreaks the given paragraph.
|
|
|
|
|
/// \retval true if a full screen redraw is needed.
|
|
|
|
|
/// \retval false if a single paragraph redraw is enough.
|
|
|
|
|
bool redoParagraph(pit_type const pit);
|
2007-06-21 06:41:55 +00:00
|
|
|
|
/// Clear cache of paragraph metrics
|
|
|
|
|
void clear() { par_metrics_.clear(); }
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
int ascent() const { return dim_.asc; }
|
|
|
|
|
///
|
|
|
|
|
int descent() const { return dim_.des; }
|
|
|
|
|
/// current text width.
|
|
|
|
|
int width() const { return dim_.wid; }
|
|
|
|
|
/// current text heigth.
|
|
|
|
|
int height() const { return dim_.height(); }
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
int maxWidth() const { return max_width_; }
|
2007-08-18 21:17:10 +00:00
|
|
|
|
///
|
|
|
|
|
int singleWidth(pit_type const pit, pos_type pos) const;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
int rightMargin(ParagraphMetrics const & pm) const;
|
|
|
|
|
int rightMargin(pit_type const pit) const;
|
|
|
|
|
|
|
|
|
|
/** this calculates the specified parameters. needed when setting
|
|
|
|
|
* the cursor and when creating a visible row */
|
2007-09-23 15:35:06 +00:00
|
|
|
|
void computeRowMetrics(pit_type pit, Row & row, int width) const;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-08-28 08:57:13 +00:00
|
|
|
|
///
|
2007-08-27 22:36:20 +00:00
|
|
|
|
void draw(PainterInfo & pi, int x, int y) const;
|
2007-08-28 08:57:13 +00:00
|
|
|
|
|
2007-08-30 15:17:38 +00:00
|
|
|
|
void drawParagraph(PainterInfo & pi, pit_type pit, int x, int y) const;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
|
|
|
|
private:
|
2007-05-28 22:27:45 +00:00
|
|
|
|
///
|
2006-12-29 23:54:48 +00:00
|
|
|
|
ParagraphMetrics & parMetrics(pit_type, bool redo_paragraph);
|
|
|
|
|
|
2007-09-05 13:04:05 +00:00
|
|
|
|
/// draw textselection.
|
|
|
|
|
/// FIXME: simplify to just to single row painting.
|
|
|
|
|
void drawSelection(PainterInfo & pi,
|
|
|
|
|
DocIterator const & beg, ///< selection begin.
|
|
|
|
|
DocIterator const & end, ///< selection end.
|
|
|
|
|
int x) const;
|
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
/// the minimum space a manual label needs on the screen in pixels
|
2007-08-18 21:17:10 +00:00
|
|
|
|
int labelFill(pit_type const pit, Row const & row) const;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
2007-01-01 09:36:55 +00:00
|
|
|
|
/// FIXME??
|
|
|
|
|
int labelEnd(pit_type const pit) const;
|
|
|
|
|
|
|
|
|
|
/// sets row.end to the pos value *after* which a row should break.
|
|
|
|
|
/// for example, the pos after which isNewLine(pos) == true
|
2007-08-29 21:03:41 +00:00
|
|
|
|
pit_type rowBreakPoint(
|
|
|
|
|
int width,
|
|
|
|
|
pit_type const pit,
|
|
|
|
|
pit_type first
|
|
|
|
|
) const;
|
2007-01-01 09:36:55 +00:00
|
|
|
|
|
|
|
|
|
/// sets row.width to the minimum space a row needs on the screen in pixel
|
2007-08-29 21:03:41 +00:00
|
|
|
|
int rowWidth(
|
|
|
|
|
int right_margin,
|
|
|
|
|
pit_type const pit,
|
|
|
|
|
pos_type const first,
|
|
|
|
|
pos_type const end
|
|
|
|
|
) const;
|
2007-01-01 09:36:55 +00:00
|
|
|
|
|
|
|
|
|
/// Calculate and set the height of the row
|
2007-08-29 21:03:41 +00:00
|
|
|
|
boost::tuple<int, int> rowHeight(
|
|
|
|
|
pit_type const pit,
|
|
|
|
|
pos_type const first,
|
|
|
|
|
pos_type const end
|
|
|
|
|
) const;
|
2007-01-01 09:36:55 +00:00
|
|
|
|
|
2007-08-31 10:05:12 +00:00
|
|
|
|
/// draw selection for a single row
|
|
|
|
|
void drawRowSelection(PainterInfo & pi, int x, Row const & row,
|
|
|
|
|
DocIterator const & beg, DocIterator const & end,
|
|
|
|
|
bool drawOnBegMargin, bool drawOnEndMargin) const;
|
|
|
|
|
|
2007-01-01 10:44:52 +00:00
|
|
|
|
// Temporary public:
|
|
|
|
|
public:
|
2007-01-01 10:33:37 +00:00
|
|
|
|
/// returns the column near the specified x-coordinate of the row.
|
|
|
|
|
/// x is an absolute screen coord, it is set to the real beginning
|
|
|
|
|
/// of this column.
|
|
|
|
|
pos_type getColumnNearX(pit_type pit, Row const & row, int & x,
|
|
|
|
|
bool & boundary) const;
|
2007-01-01 11:36:30 +00:00
|
|
|
|
|
|
|
|
|
/// returns pos in given par at given x coord.
|
|
|
|
|
pos_type x2pos(pit_type pit, int row, int x) const;
|
2007-05-28 22:27:45 +00:00
|
|
|
|
|
2007-01-01 11:36:30 +00:00
|
|
|
|
// FIXME: is there a need for this?
|
|
|
|
|
//int pos2x(pit_type pit, pos_type pos) const;
|
|
|
|
|
|
2007-09-02 09:44:08 +00:00
|
|
|
|
/** returns row near the specified
|
|
|
|
|
* y-coordinate in given paragraph (relative to the screen).
|
|
|
|
|
*/
|
|
|
|
|
Row const & getRowNearY(int y,
|
|
|
|
|
pit_type pit) const;
|
|
|
|
|
|
|
|
|
|
/// returns the paragraph number closest to screen y-coordinate.
|
|
|
|
|
/// This method uses the BufferView CoordCache to locate the
|
|
|
|
|
/// paragraph. The y-coodinate is allowed to be off-screen and
|
|
|
|
|
/// the CoordCache will be automatically updated if needed. This is
|
|
|
|
|
/// the reason why we need a non const BufferView.
|
|
|
|
|
pit_type getPitNearY(int y);
|
|
|
|
|
|
|
|
|
|
/// sets cursor recursively descending into nested editable insets
|
|
|
|
|
/**
|
|
|
|
|
\return the inset pointer if x,y is covering that inset
|
|
|
|
|
\param x,y are absolute screen coordinates.
|
|
|
|
|
\retval inset is non-null if the cursor is positionned inside
|
|
|
|
|
*/
|
|
|
|
|
/// FIXME: cleanup to use BufferView::getCoveringInset() and
|
|
|
|
|
/// setCursorFromCoordinates() instead of checkInsetHit().
|
|
|
|
|
Inset * editXY(Cursor & cur, int x, int y);
|
|
|
|
|
|
|
|
|
|
/// sets cursor only within this Text.
|
|
|
|
|
/// x,y are screen coordinates
|
|
|
|
|
void setCursorFromCoordinates(Cursor & cur, int x, int y);
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
int cursorX(CursorSlice const & cursor,
|
|
|
|
|
bool boundary) const;
|
|
|
|
|
///
|
|
|
|
|
int cursorY(CursorSlice const & cursor,
|
|
|
|
|
bool boundary) const;
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
void cursorPrevious(Cursor & cur);
|
|
|
|
|
///
|
|
|
|
|
void cursorNext(Cursor & cur);
|
2007-09-02 11:21:33 +00:00
|
|
|
|
///
|
|
|
|
|
bool cursorHome(Cursor & cur);
|
|
|
|
|
///
|
|
|
|
|
bool cursorEnd(Cursor & cur);
|
|
|
|
|
///
|
|
|
|
|
void deleteLineForward(Cursor & cur);
|
2007-09-02 09:44:08 +00:00
|
|
|
|
|
2007-09-02 11:27:19 +00:00
|
|
|
|
/// is this row the last in the text?
|
|
|
|
|
bool isLastRow(pit_type pit, Row const & row) const;
|
|
|
|
|
/// is this row the first in the text?
|
|
|
|
|
bool isFirstRow(pit_type pit, Row const & row) const;
|
|
|
|
|
|
2007-09-02 09:44:08 +00:00
|
|
|
|
/// Returns an inset if inset was hit, or 0 if not.
|
|
|
|
|
/// \warning This method is not recursive! It will return the
|
|
|
|
|
/// outermost inset within this Text.
|
|
|
|
|
/// \sa BufferView::getCoveringInset() to get the innermost inset.
|
|
|
|
|
Inset * checkInsetHit(int x, int y);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the left beginning of the text.
|
|
|
|
|
* This information cannot be taken from the layout object, because
|
|
|
|
|
* in LaTeX the beginning of the text fits in some cases
|
|
|
|
|
* (for example sections) exactly the label-width.
|
|
|
|
|
*/
|
|
|
|
|
int leftMargin(int max_width, pit_type pit, pos_type pos) const;
|
|
|
|
|
int leftMargin(int max_width, pit_type pit) const;
|
|
|
|
|
|
2007-01-01 10:44:52 +00:00
|
|
|
|
private:
|
2007-01-01 10:33:37 +00:00
|
|
|
|
|
2006-12-29 23:54:48 +00:00
|
|
|
|
/// The BufferView owner.
|
|
|
|
|
BufferView * bv_;
|
|
|
|
|
|
|
|
|
|
/// The text contents (the model).
|
|
|
|
|
/// \todo FIXME: this should be const.
|
2007-04-29 23:33:02 +00:00
|
|
|
|
Text * text_;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
|
|
|
|
|
bool main_text_;
|
|
|
|
|
/// A map from paragraph index number to paragraph metrics
|
|
|
|
|
typedef std::map<pit_type, ParagraphMetrics> ParMetricsCache;
|
|
|
|
|
///
|
|
|
|
|
mutable ParMetricsCache par_metrics_;
|
|
|
|
|
Dimension dim_;
|
|
|
|
|
int max_width_;
|
2007-09-11 16:04:10 +00:00
|
|
|
|
mutable Point origin_;
|
2007-09-02 21:48:49 +00:00
|
|
|
|
|
|
|
|
|
// temporary public:
|
|
|
|
|
public:
|
|
|
|
|
/// our 'outermost' font.
|
|
|
|
|
/// This is handed down from the surrounding
|
|
|
|
|
/// inset through the pi/mi parameter (pi.base.font)
|
|
|
|
|
/// It is used in applyOuterFont() and setCharFont() for reasons
|
|
|
|
|
/// that are not clear... to hand hand the outermost language and
|
|
|
|
|
/// also for char style apparently.
|
|
|
|
|
Font font_;
|
2006-12-29 23:54:48 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// return the default height of a row in pixels, considering font zoom
|
|
|
|
|
int defaultRowHeight();
|
|
|
|
|
|
|
|
|
|
} // namespace lyx
|
|
|
|
|
|
|
|
|
|
#endif // TEXT_METRICS_H
|