3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Asger Alstrup
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
9 * \author Angus Leeming
11 * \author André Pönitz
13 * \author Jürgen Vigna
14 * \author Abdelrazak Younes
16 * Full author contact details are available in file CREDITS.
23 #include <boost/next_prior.hpp>
39 /// used by lower_bound and upper_bound
40 int operator()(FontTable const & a, FontTable const & b) const {
41 return a.pos() < b.pos();
47 FontList::iterator FontList::fontIterator(pos_type pos)
50 FontTable search_elem(pos, dummy);
51 return lower_bound(list_.begin(), list_.end(), search_elem,
56 FontList::const_iterator FontList::fontIterator(pos_type pos) const
59 FontTable search_elem(pos, dummy);
60 return lower_bound(list_.begin(), list_.end(), search_elem,
65 Font & FontList::get(pos_type pos)
67 iterator end = list_.end();
68 iterator it = fontIterator(pos);
69 if (it != end && it->pos() == pos)
76 void FontList::erase(pos_type pos)
78 // Erase entries in the tables.
79 iterator it = fontIterator(pos);
80 iterator beg = list_.begin();
81 if (it != list_.end() && it->pos() == pos
83 || (it != list_.begin() && boost::prior(it)->pos() == pos - 1))) {
85 // If it is a multi-character font
86 // entry, we just make it smaller
87 // (see update below), otherwise we
89 unsigned int const i = it - list_.begin();
91 if (i >= list_.size())
93 it = list_.begin() + i;
94 if (i > 0 && i < list_.size() &&
95 list_[i - 1].font() == list_[i].font()) {
96 list_.erase(beg + i - 1);
97 it = list_.begin() + i - 1;
101 // Update all other entries
102 iterator end = list_.end();
103 for (; it != end; ++it)
104 it->pos(it->pos() - 1);
107 void FontList::increasePosAfterPos(pos_type pos)
109 List::iterator end = list_.end();
110 List::iterator it = fontIterator(pos);
111 for (; it != end; ++it)
116 void FontList::decreasePosAfterPos(pos_type pos)
118 List::iterator end = list_.end();
119 List::iterator it = fontIterator(pos);
120 for (; it != end; ++it)
125 void FontList::set(pos_type pos, Font const & font)
127 // No need to simplify this because it will disappear
128 // in a new kernel. (Asger)
129 // Next search font table
131 iterator beg = list_.begin();
133 iterator endit = list_.end();
134 for (; it != endit; ++it) {
135 if (it->pos() >= pos)
138 size_t const i = distance(beg, it);
139 bool notfound = (it == endit);
141 if (!notfound && list_[i].font() == font)
144 bool begin = pos == 0 || notfound ||
145 (i > 0 && list_[i - 1].pos() == pos - 1);
146 // Is position pos is a beginning of a font block?
147 bool end = !notfound && list_[i].pos() == pos;
148 // Is position pos is the end of a font block?
149 if (begin && end) { // A single char block
150 if (i + 1 < list_.size() &&
151 list_[i + 1].font() == font) {
152 // Merge the singleton block with the next block
153 list_.erase(list_.begin() + i);
154 if (i > 0 && list_[i - 1].font() == font)
155 list_.erase(list_.begin() + i - 1);
156 } else if (i > 0 && list_[i - 1].font() == font) {
157 // Merge the singleton block with the previous block
158 list_[i - 1].pos(pos);
159 list_.erase(list_.begin() + i);
163 if (i > 0 && list_[i - 1].font() == font)
164 list_[i - 1].pos(pos);
166 list_.insert(list_.begin() + i,
167 FontTable(pos, font));
169 list_[i].pos(pos - 1);
170 if (!(i + 1 < list_.size() &&
171 list_[i + 1].font() == font))
172 list_.insert(list_.begin() + i + 1,
173 FontTable(pos, font));
174 } else { // The general case. The block is splitted into 3 blocks
175 list_.insert(list_.begin() + i,
176 FontTable(pos - 1, list_[i].font()));
177 list_.insert(list_.begin() + i + 1,
178 FontTable(pos, font));
183 Font_size FontList::highestInRange
184 (pos_type startpos, pos_type endpos, Font_size def_size) const
189 const_iterator end_it = list_.begin();
190 const_iterator const end = list_.end();
191 for (; end_it != end; ++end_it) {
192 if (end_it->pos() >= endpos)
199 FontList::const_iterator cit = list_.begin();
200 for (; cit != end; ++cit) {
201 if (cit->pos() >= startpos)
205 Font::FONT_SIZE maxsize = Font::SIZE_TINY;
206 for (; cit != end_it; ++cit) {
207 Font::FONT_SIZE size = cit->font().size();
208 if (size == Font::INHERIT_SIZE)
210 if (size > maxsize && size <= Font::SIZE_HUGER)
217 bool FontList::hasChangeInRange(pos_type pos, int len) const
219 // FIXME: can't we use fontIterator(pos) instead?
220 const_iterator cit = list_.begin();
221 const_iterator end = list_.end();
222 for (; cit != end; ++cit) {
223 if (cit->pos() >= pos)
226 if (cit != end && pos + len - 1 > cit->pos())
233 void FontList::validate(LaTeXFeatures & features) const
235 const_iterator fcit = list_.begin();
236 const_iterator fend = list_.end();
237 for (; fcit != fend; ++fcit)
238 fcit->font().validate(features);