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 "BufferParams.h"
26 #include "LaTeXFeatures.h"
28 #include <boost/next_prior.hpp>
44 /// used by lower_bound and upper_bound
45 int operator()(FontTable const & a, FontTable const & b) const {
46 return a.pos() < b.pos();
52 FontList::iterator FontList::fontIterator(pos_type pos)
55 FontTable search_elem(pos, dummy);
56 return lower_bound(list_.begin(), list_.end(), search_elem,
61 FontList::const_iterator FontList::fontIterator(pos_type pos) const
64 FontTable search_elem(pos, dummy);
65 return lower_bound(list_.begin(), list_.end(), search_elem,
70 Font & FontList::get(pos_type pos)
72 iterator end = list_.end();
73 iterator it = fontIterator(pos);
74 if (it != end && it->pos() == pos)
81 void FontList::erase(pos_type pos)
83 // Erase entries in the tables.
84 iterator it = fontIterator(pos);
85 iterator beg = list_.begin();
86 if (it != list_.end() && it->pos() == pos
88 || (it != beg && boost::prior(it)->pos() == pos - 1))) {
90 // If it is a multi-character font
91 // entry, we just make it smaller
92 // (see update below), otherwise we
94 unsigned int const i = it - beg;
97 if (i > 0 && i < list_.size() &&
98 list_[i - 1].font() == list_[i].font()) {
99 list_.erase(beg + i - 1);
104 // Update all other entries
105 iterator end = list_.end();
106 for (; it != end; ++it)
107 it->pos(it->pos() - 1);
110 void FontList::increasePosAfterPos(pos_type pos)
112 List::iterator end = list_.end();
113 List::iterator it = fontIterator(pos);
114 for (; it != end; ++it)
119 void FontList::decreasePosAfterPos(pos_type pos)
121 List::iterator end = list_.end();
122 List::iterator it = fontIterator(pos);
123 for (; it != end; ++it)
128 void FontList::set(pos_type pos, Font const & font)
130 // No need to simplify this because it will disappear
131 // in a new kernel. (Asger)
132 // Next search font table
134 iterator beg = list_.begin();
136 iterator endit = list_.end();
137 for (; it != endit; ++it) {
138 if (it->pos() >= pos)
141 size_t const i = distance(beg, it);
142 bool notfound = (it == endit);
144 if (!notfound && list_[i].font() == font)
147 bool begin = pos == 0 || notfound ||
148 (i > 0 && list_[i - 1].pos() == pos - 1);
149 // Is position pos is a beginning of a font block?
150 bool end = !notfound && list_[i].pos() == pos;
151 // Is position pos is the end of a font block?
152 if (begin && end) { // A single char block
153 if (i + 1 < list_.size() &&
154 list_[i + 1].font() == font) {
155 // Merge the singleton block with the next block
156 list_.erase(list_.begin() + i);
157 if (i > 0 && list_[i - 1].font() == font)
158 list_.erase(list_.begin() + i - 1);
159 } else if (i > 0 && list_[i - 1].font() == font) {
160 // Merge the singleton block with the previous block
161 list_[i - 1].pos(pos);
162 list_.erase(list_.begin() + i);
166 if (i > 0 && list_[i - 1].font() == font)
167 list_[i - 1].pos(pos);
169 list_.insert(list_.begin() + i,
170 FontTable(pos, font));
172 list_[i].pos(pos - 1);
173 if (!(i + 1 < list_.size() &&
174 list_[i + 1].font() == font))
175 list_.insert(list_.begin() + i + 1,
176 FontTable(pos, font));
177 } else { // The general case. The block is splitted into 3 blocks
178 list_.insert(list_.begin() + i,
179 FontTable(pos - 1, list_[i].font()));
180 list_.insert(list_.begin() + i + 1,
181 FontTable(pos, font));
186 Font_size FontList::highestInRange
187 (pos_type startpos, pos_type endpos, Font_size def_size) const
192 const_iterator end_it = list_.begin();
193 const_iterator const end = list_.end();
194 for (; end_it != end; ++end_it) {
195 if (end_it->pos() >= endpos)
202 FontList::const_iterator cit = list_.begin();
203 for (; cit != end; ++cit) {
204 if (cit->pos() >= startpos)
208 Font::FONT_SIZE maxsize = Font::SIZE_TINY;
209 for (; cit != end_it; ++cit) {
210 Font::FONT_SIZE size = cit->font().size();
211 if (size == Font::INHERIT_SIZE)
213 if (size > maxsize && size <= Font::SIZE_HUGER)
220 bool FontList::hasChangeInRange(pos_type pos, int len) const
222 // FIXME: can't we use fontIterator(pos) instead?
223 const_iterator cit = list_.begin();
224 const_iterator end = list_.end();
225 for (; cit != end; ++cit) {
226 if (cit->pos() >= pos)
229 if (cit != end && pos + len - 1 > cit->pos())
236 void FontList::validate(LaTeXFeatures & features) const
238 BufferParams const & bparams = features.bufferParams();
239 Language const * doc_language = bparams.language;
241 const_iterator fcit = list_.begin();
242 const_iterator fend = list_.end();
243 for (; fcit != fend; ++fcit) {
244 if (fcit->font().noun() == Font::ON) {
245 LYXERR(Debug::LATEX) << "font.noun: "
246 << fcit->font().noun()
248 features.require("noun");
249 LYXERR(Debug::LATEX) << "Noun enabled. Font: "
250 << to_utf8(fcit->font().stateText(0))
253 switch (fcit->font().color()) {
257 // probably we should put here all interface colors used for
258 // font displaying! For now I just add this ones I know of (Jug)
263 features.require("color");
264 LYXERR(Debug::LATEX) << "Color enabled. Font: "
265 << to_utf8(fcit->font().stateText(0))
269 Language const * language = fcit->font().language();
270 if (language->babel() != doc_language->babel() &&
271 language != ignore_language &&
272 language != latex_language)
274 features.useLanguage(language);
275 LYXERR(Debug::LATEX) << "Found language "
276 << language->lang() << endl;