mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-10 20:04:46 +00:00
Transfer getColumnNearX from LyXText to TextMetrics.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16454 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
e58397400c
commit
f1d90e17d8
@ -30,6 +30,7 @@
|
||||
#include "FontIterator.h"
|
||||
#include "LColor.h"
|
||||
#include "lyxlength.h"
|
||||
#include "lyxrc.h"
|
||||
#include "lyxtext.h"
|
||||
#include "metricsinfo.h"
|
||||
#include "ParagraphParameters.h"
|
||||
@ -775,6 +776,149 @@ void TextMetrics::setHeightOfRow(pit_type const pit,
|
||||
}
|
||||
|
||||
|
||||
// x is an absolute screen coord
|
||||
// returns the column near the specified x-coordinate of the row
|
||||
// x is set to the real beginning of this column
|
||||
pos_type TextMetrics::getColumnNearX(pit_type const pit,
|
||||
Row const & row, int & x, bool & boundary) const
|
||||
{
|
||||
Buffer const & buffer = *bv_->buffer();
|
||||
|
||||
/// For the main LyXText, it is possible that this pit is not
|
||||
/// yet in the CoordCache when moving cursor up.
|
||||
/// x Paragraph coordinate is always 0 for main text anyway.
|
||||
int const xo = main_text_? 0 : bv_->coordCache().get(text_, pit).x_;
|
||||
x -= xo;
|
||||
RowMetrics const r = computeRowMetrics(pit, row);
|
||||
Paragraph const & par = text_->getPar(pit);
|
||||
|
||||
pos_type vc = row.pos();
|
||||
pos_type end = row.endpos();
|
||||
pos_type c = 0;
|
||||
LyXLayout_ptr const & layout = par.layout();
|
||||
|
||||
bool left_side = false;
|
||||
|
||||
pos_type body_pos = par.beginOfBody();
|
||||
|
||||
double tmpx = r.x;
|
||||
double last_tmpx = tmpx;
|
||||
|
||||
if (body_pos > 0 &&
|
||||
(body_pos > end || !par.isLineSeparator(body_pos - 1)))
|
||||
body_pos = 0;
|
||||
|
||||
// check for empty row
|
||||
if (vc == end) {
|
||||
x = int(tmpx) + xo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
frontend::FontMetrics const & fm
|
||||
= theFontMetrics(text_->getLabelFont(buffer, par));
|
||||
|
||||
while (vc < end && tmpx <= x) {
|
||||
c = text_->bidi.vis2log(vc);
|
||||
last_tmpx = tmpx;
|
||||
if (body_pos > 0 && c == body_pos - 1) {
|
||||
// FIXME UNICODE
|
||||
docstring const lsep = from_utf8(layout->labelsep);
|
||||
tmpx += r.label_hfill + fm.width(lsep);
|
||||
if (par.isLineSeparator(body_pos - 1))
|
||||
tmpx -= text_->singleWidth(buffer, par, body_pos - 1);
|
||||
}
|
||||
|
||||
if (par.hfillExpansion(row, c)) {
|
||||
tmpx += text_->singleWidth(buffer, par, c);
|
||||
if (c >= body_pos)
|
||||
tmpx += r.hfill;
|
||||
else
|
||||
tmpx += r.label_hfill;
|
||||
} else if (par.isSeparator(c)) {
|
||||
tmpx += text_->singleWidth(buffer, par, c);
|
||||
if (c >= body_pos)
|
||||
tmpx += r.separator;
|
||||
} else {
|
||||
tmpx += text_->singleWidth(buffer, par, c);
|
||||
}
|
||||
++vc;
|
||||
}
|
||||
|
||||
if ((tmpx + last_tmpx) / 2 > x) {
|
||||
tmpx = last_tmpx;
|
||||
left_side = true;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(vc <= end); // This shouldn't happen.
|
||||
|
||||
boundary = false;
|
||||
// This (rtl_support test) is not needed, but gives
|
||||
// some speedup if rtl_support == false
|
||||
bool const lastrow = lyxrc.rtl_support && row.endpos() == par.size();
|
||||
|
||||
// If lastrow is false, we don't need to compute
|
||||
// the value of rtl.
|
||||
bool const rtl = lastrow ? text_->isRTL(buffer, par) : false;
|
||||
if (lastrow &&
|
||||
((rtl && left_side && vc == row.pos() && x < tmpx - 5) ||
|
||||
(!rtl && !left_side && vc == end && x > tmpx + 5)))
|
||||
c = end;
|
||||
else if (vc == row.pos()) {
|
||||
c = text_->bidi.vis2log(vc);
|
||||
if (text_->bidi.level(c) % 2 == 1)
|
||||
++c;
|
||||
} else {
|
||||
c = text_->bidi.vis2log(vc - 1);
|
||||
bool const rtl = (text_->bidi.level(c) % 2 == 1);
|
||||
if (left_side == rtl) {
|
||||
++c;
|
||||
boundary = text_->bidi.isBoundary(buffer, par, c);
|
||||
}
|
||||
}
|
||||
|
||||
// I believe this code is not needed anymore (Jug 20050717)
|
||||
#if 0
|
||||
// The following code is necessary because the cursor position past
|
||||
// the last char in a row is logically equivalent to that before
|
||||
// the first char in the next row. That's why insets causing row
|
||||
// divisions -- Newline and display-style insets -- must be treated
|
||||
// specially, so cursor up/down doesn't get stuck in an air gap -- MV
|
||||
// Newline inset, air gap below:
|
||||
if (row.pos() < end && c >= end && par.isNewline(end - 1)) {
|
||||
if (text_->bidi.level(end -1) % 2 == 0)
|
||||
tmpx -= text_->singleWidth(buffer, par, end - 1);
|
||||
else
|
||||
tmpx += text_->singleWidth(buffer, par, end - 1);
|
||||
c = end - 1;
|
||||
}
|
||||
|
||||
// Air gap above display inset:
|
||||
if (row.pos() < end && c >= end && end < par.size()
|
||||
&& par.isInset(end) && par.getInset(end)->display()) {
|
||||
c = end - 1;
|
||||
}
|
||||
// Air gap below display inset:
|
||||
if (row.pos() < end && c >= end && par.isInset(end - 1)
|
||||
&& par.getInset(end - 1)->display()) {
|
||||
c = end - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
x = int(tmpx) + xo;
|
||||
pos_type const col = c - row.pos();
|
||||
|
||||
if (!c || end == par.size())
|
||||
return col;
|
||||
|
||||
if (c==end && !par.isLineSeparator(c-1) && !par.isNewline(c-1)) {
|
||||
boundary = true;
|
||||
return col;
|
||||
}
|
||||
|
||||
return min(col, end - 1 - row.pos());
|
||||
}
|
||||
|
||||
|
||||
int defaultRowHeight()
|
||||
{
|
||||
return int(theFontMetrics(LyXFont(LyXFont::ALL_SANE)).maxHeight() * 1.2);
|
||||
|
@ -90,6 +90,12 @@ private:
|
||||
/// Calculate and set the height of the row
|
||||
void setHeightOfRow(pit_type, Row & row);
|
||||
|
||||
/// 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;
|
||||
|
||||
/// The BufferView owner.
|
||||
BufferView * bv_;
|
||||
|
||||
|
@ -149,13 +149,6 @@ public:
|
||||
/// FIXME: move to TextMetrics.
|
||||
pit_type getPitNearY(BufferView & bv, int y);
|
||||
|
||||
/** returns the column near the specified x-coordinate of the row
|
||||
x is set to the real beginning of this column
|
||||
*/
|
||||
/// FIXME: move to TextMetrics.
|
||||
pos_type getColumnNearX(BufferView const & bv, int right_margin,
|
||||
pit_type pit, Row const & row, int & x, bool & boundary) const;
|
||||
|
||||
/** Find the word under \c from in the relative location
|
||||
* defined by \c word_location.
|
||||
* @param from return here the start of the word
|
||||
|
@ -1687,7 +1687,7 @@ pos_type LyXText::x2pos(BufferView const & bv, pit_type pit, int row,
|
||||
BOOST_ASSERT(row < int(pm.rows().size()));
|
||||
bool bound = false;
|
||||
Row const & r = pm.rows()[row];
|
||||
return r.pos() + getColumnNearX(bv, tm.rightMargin(pm), pit, r, x, bound);
|
||||
return r.pos() + tm.getColumnNearX(pit, r, x, bound);
|
||||
}
|
||||
|
||||
|
||||
@ -1736,8 +1736,8 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int const x, int const y)
|
||||
bool bound = false;
|
||||
int xx = x;
|
||||
int right_margin = tm.rightMargin(pm);
|
||||
pos_type const pos = row.pos() + getColumnNearX(cur.bv(), right_margin,
|
||||
pit, row, xx, bound);
|
||||
pos_type const pos = row.pos()
|
||||
+ tm.getColumnNearX(pit, row, xx, bound);
|
||||
|
||||
lyxerr[Debug::DEBUG]
|
||||
<< BOOST_CURRENT_FUNCTION
|
||||
|
148
src/text2.C
148
src/text2.C
@ -748,152 +748,6 @@ void LyXText::setCurrentFont(LCursor & cur)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// x is an absolute screen coord
|
||||
// returns the column near the specified x-coordinate of the row
|
||||
// x is set to the real beginning of this column
|
||||
pos_type LyXText::getColumnNearX(BufferView const & bv, int right_margin,
|
||||
pit_type const pit, Row const & row, int & x, bool & boundary) const
|
||||
{
|
||||
Buffer const & buffer = *bv.buffer();
|
||||
TextMetrics const & tm = bv.textMetrics(this);
|
||||
|
||||
/// For the main LyXText, it is possible that this pit is not
|
||||
/// yet in the CoordCache when moving cursor up.
|
||||
/// x Paragraph coordinate is always 0 for main text anyway.
|
||||
int const xo = isMainText(*bv.buffer())?
|
||||
0 : bv.coordCache().get(this, pit).x_;
|
||||
x -= xo;
|
||||
RowMetrics const r = tm.computeRowMetrics(pit, row);
|
||||
Paragraph const & par = pars_[pit];
|
||||
|
||||
pos_type vc = row.pos();
|
||||
pos_type end = row.endpos();
|
||||
pos_type c = 0;
|
||||
LyXLayout_ptr const & layout = par.layout();
|
||||
|
||||
bool left_side = false;
|
||||
|
||||
pos_type body_pos = par.beginOfBody();
|
||||
|
||||
double tmpx = r.x;
|
||||
double last_tmpx = tmpx;
|
||||
|
||||
if (body_pos > 0 &&
|
||||
(body_pos > end || !par.isLineSeparator(body_pos - 1)))
|
||||
body_pos = 0;
|
||||
|
||||
// check for empty row
|
||||
if (vc == end) {
|
||||
x = int(tmpx) + xo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
frontend::FontMetrics const & fm
|
||||
= theFontMetrics(getLabelFont(buffer, par));
|
||||
|
||||
while (vc < end && tmpx <= x) {
|
||||
c = bidi.vis2log(vc);
|
||||
last_tmpx = tmpx;
|
||||
if (body_pos > 0 && c == body_pos - 1) {
|
||||
// FIXME UNICODE
|
||||
docstring const lsep = from_utf8(layout->labelsep);
|
||||
tmpx += r.label_hfill + fm.width(lsep);
|
||||
if (par.isLineSeparator(body_pos - 1))
|
||||
tmpx -= singleWidth(buffer, par, body_pos - 1);
|
||||
}
|
||||
|
||||
if (par.hfillExpansion(row, c)) {
|
||||
tmpx += singleWidth(buffer, par, c);
|
||||
if (c >= body_pos)
|
||||
tmpx += r.hfill;
|
||||
else
|
||||
tmpx += r.label_hfill;
|
||||
} else if (par.isSeparator(c)) {
|
||||
tmpx += singleWidth(buffer, par, c);
|
||||
if (c >= body_pos)
|
||||
tmpx += r.separator;
|
||||
} else {
|
||||
tmpx += singleWidth(buffer, par, c);
|
||||
}
|
||||
++vc;
|
||||
}
|
||||
|
||||
if ((tmpx + last_tmpx) / 2 > x) {
|
||||
tmpx = last_tmpx;
|
||||
left_side = true;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(vc <= end); // This shouldn't happen.
|
||||
|
||||
boundary = false;
|
||||
// This (rtl_support test) is not needed, but gives
|
||||
// some speedup if rtl_support == false
|
||||
bool const lastrow = lyxrc.rtl_support && row.endpos() == par.size();
|
||||
|
||||
// If lastrow is false, we don't need to compute
|
||||
// the value of rtl.
|
||||
bool const rtl = lastrow ? isRTL(buffer, par) : false;
|
||||
if (lastrow &&
|
||||
((rtl && left_side && vc == row.pos() && x < tmpx - 5) ||
|
||||
(!rtl && !left_side && vc == end && x > tmpx + 5)))
|
||||
c = end;
|
||||
else if (vc == row.pos()) {
|
||||
c = bidi.vis2log(vc);
|
||||
if (bidi.level(c) % 2 == 1)
|
||||
++c;
|
||||
} else {
|
||||
c = bidi.vis2log(vc - 1);
|
||||
bool const rtl = (bidi.level(c) % 2 == 1);
|
||||
if (left_side == rtl) {
|
||||
++c;
|
||||
boundary = bidi.isBoundary(buffer, par, c);
|
||||
}
|
||||
}
|
||||
|
||||
// I believe this code is not needed anymore (Jug 20050717)
|
||||
#if 0
|
||||
// The following code is necessary because the cursor position past
|
||||
// the last char in a row is logically equivalent to that before
|
||||
// the first char in the next row. That's why insets causing row
|
||||
// divisions -- Newline and display-style insets -- must be treated
|
||||
// specially, so cursor up/down doesn't get stuck in an air gap -- MV
|
||||
// Newline inset, air gap below:
|
||||
if (row.pos() < end && c >= end && par.isNewline(end - 1)) {
|
||||
if (bidi.level(end -1) % 2 == 0)
|
||||
tmpx -= singleWidth(buffer, par, end - 1);
|
||||
else
|
||||
tmpx += singleWidth(buffer, par, end - 1);
|
||||
c = end - 1;
|
||||
}
|
||||
|
||||
// Air gap above display inset:
|
||||
if (row.pos() < end && c >= end && end < par.size()
|
||||
&& par.isInset(end) && par.getInset(end)->display()) {
|
||||
c = end - 1;
|
||||
}
|
||||
// Air gap below display inset:
|
||||
if (row.pos() < end && c >= end && par.isInset(end - 1)
|
||||
&& par.getInset(end - 1)->display()) {
|
||||
c = end - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
x = int(tmpx) + xo;
|
||||
pos_type const col = c - row.pos();
|
||||
|
||||
if (!c || end == par.size())
|
||||
return col;
|
||||
|
||||
if (c==end && !par.isLineSeparator(c-1) && !par.isNewline(c-1)) {
|
||||
boundary = true;
|
||||
return col;
|
||||
}
|
||||
|
||||
return min(col, end - 1 - row.pos());
|
||||
}
|
||||
|
||||
|
||||
// y is screen coordinate
|
||||
pit_type LyXText::getPitNearY(BufferView & bv, int y)
|
||||
{
|
||||
@ -1007,7 +861,7 @@ InsetBase * LyXText::editXY(LCursor & cur, int x, int y)
|
||||
int right_margin = tm.rightMargin(pm);
|
||||
int xx = x; // is modified by getColumnNearX
|
||||
pos_type const pos = row.pos()
|
||||
+ getColumnNearX(cur.bv(), right_margin, pit, row, xx, bound);
|
||||
+ tm.getColumnNearX(pit, row, xx, bound);
|
||||
cur.pit() = pit;
|
||||
cur.pos() = pos;
|
||||
cur.boundary(bound);
|
||||
|
Loading…
Reference in New Issue
Block a user