File: ParagraphMetrics.cpp

package info (click to toggle)
lyx 2.4.3-1~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 130,280 kB
  • sloc: cpp: 259,444; ansic: 106,595; xml: 72,791; python: 32,859; sh: 7,176; makefile: 6,144; pascal: 2,129; perl: 2,007; objc: 1,084; tcl: 163; sed: 16
file content (185 lines) | stat: -rw-r--r-- 3,985 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/**
 * \file Paragraph.cpp
 * This file is part of LyX, the document processor.
 * Licence details can be found in the file COPYING.
 *
 * \author Asger Alstrup
 * \author Lars Gullik Bjønnes
 * \author Jean-Marc Lasgouttes
 * \author Angus Leeming
 * \author John Levon
 * \author André Pönitz
 * \author Dekel Tsur
 * \author Jürgen Vigna
 *
 * Full author contact details are available in file CREDITS.
 */

#include <config.h>

#include "ParagraphMetrics.h"

#include "Buffer.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "Font.h"
#include "Layout.h"
#include "LayoutEnums.h"
#include "Paragraph.h"
#include "TextClass.h"

#include "frontends/FontMetrics.h"

#include "support/lassert.h"
#include "support/debug.h"

#include <sstream>

using namespace std;
using namespace lyx::support;

namespace lyx {

const int pm_npos = -10000;

ParagraphMetrics::ParagraphMetrics(Paragraph const & par) :
	position_(pm_npos), id_(par.id()), par_(&par)
{}


ParagraphMetrics & ParagraphMetrics::operator=(
	ParagraphMetrics const & pm)
{
	rows_ = pm.rows_;
	dim_ = pm.dim_;
	par_ = pm.par_;
	position_ = pm.position_;
	return *this;
}


void ParagraphMetrics::reset(Paragraph const & par)
{
	par_ = &par;
	dim_ = Dimension();
	//position_ = pm_npos;
}


int ParagraphMetrics::position() const
{
	LASSERT(hasPosition(), return -1);
	return position_;
}


void ParagraphMetrics::setPosition(int position)
{
	position_ = position;
}


void ParagraphMetrics::resetPosition()
{
	position_ = pm_npos;
}


bool ParagraphMetrics::hasPosition() const
{
	return position_ != pm_npos;
}


Row const & ParagraphMetrics::getRow(pos_type pos, bool boundary) const
{
	LBUFERR(!rows().empty());

	// If boundary is set we should return the row on which
	// the character before is inside.
	if (pos > 0 && boundary)
		--pos;

	RowList::const_iterator rit = rows_.end();
	RowList::const_iterator const begin = rows_.begin();

	for (--rit; rit != begin && rit->pos() > pos; --rit)
		;

	return *rit;
}


size_t ParagraphMetrics::pos2row(pos_type pos) const
{
	LBUFERR(!rows().empty());

	RowList::const_iterator rit = rows_.end();
	RowList::const_iterator const begin = rows_.begin();

	for (--rit; rit != begin && rit->pos() > pos; --rit)
		;

	return rit - begin;
}


void ParagraphMetrics::dump() const
{
	lyxerr << "Paragraph::dump: rows.size(): " << rows_.size() << endl;
	for (size_t i = 0; i != rows_.size(); ++i) {
		lyxerr << "  row " << i << ":   " << rows_[i];
	}
}

int ParagraphMetrics::rightMargin(BufferView const & bv) const
{
	BufferParams const & params = bv.buffer().params();
	DocumentClass const & tclass = params.documentClass();
	frontend::FontMetrics const & fm = theFontMetrics(params.getFont());
	int const r_margin =
		bv.rightMargin()
		+ fm.signedWidth(tclass.rightmargin())
		+ fm.signedWidth(par_->layout().rightmargin)
		* 4 / (par_->getDepth() + 4);

	return r_margin;
}


// FIXME: this code seems bogus. Audit and rewrite (see bug #9860).
bool ParagraphMetrics::hfillExpansion(Row const & row, pos_type pos) const
{
	if (!par_->isHfill(pos))
		return false;

	LASSERT(pos >= row.pos() && pos < row.endpos(), return false);

	// expand at the end of a row only if there is another hfill on the same row
	if (pos == row.endpos() - 1) {
		for (pos_type i = row.pos(); i < pos; i++) {
			if (par_->isHfill(i))
				return true;
		}
		return false;
	}

	// expand at the beginning of a row only if it is the first row of a paragraph
	if (pos == row.pos())
		return pos == 0;

	// do not expand in some labels
	if (par_->layout().margintype != MARGIN_MANUAL && pos < par_->beginOfBody())
		return false;

	// if there is anything between the first char of the row and
	// the specified position that is neither a newline nor an hfill,
	// the hfill will be expanded, otherwise it won't
	for (pos_type i = row.pos(); i < pos; i++) {
		if (!par_->isNewline(i) && !par_->isEnvSeparator(i) && !par_->isHfill(i))
			return true;
	}
	return false;
}

} // namespace lyx