tufte layout files:
[lyx.git] / src / FontList.cpp
blob923986f11af7c3899b0fde29966dcdfc751f7517
1 /**
2 * \file FontList.cpp
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
10 * \author John Levon
11 * \author André Pönitz
12 * \author Dekel Tsur
13 * \author Jürgen Vigna
14 * \author Abdelrazak Younes
16 * Full author contact details are available in file CREDITS.
19 #include <config.h>
21 #include "FontList.h"
23 #include <boost/next_prior.hpp>
25 #include <algorithm>
27 using namespace std;
29 namespace lyx {
32 FontList::iterator FontList::fontIterator(pos_type pos)
34 FontList::iterator it = list_.begin();
35 FontList::iterator end = list_.end();
36 for (; it != end; ++it) {
37 if (it->pos() >= pos)
38 break;
40 return it;
44 FontList::const_iterator FontList::fontIterator(pos_type pos) const
46 FontList::const_iterator it = list_.begin();
47 FontList::const_iterator end = list_.end();
48 for (; it != end; ++it) {
49 if (it->pos() >= pos)
50 break;
52 return it;
56 Font & FontList::get(pos_type pos)
58 iterator end = list_.end();
59 iterator it = fontIterator(pos);
60 if (it != end && it->pos() == pos)
61 return it->font_;
62 static Font dummy;
63 return dummy;
67 void FontList::erase(pos_type pos)
69 // Erase entries in the tables.
70 iterator it = fontIterator(pos);
71 iterator beg = list_.begin();
72 if (it != list_.end() && it->pos() == pos
73 && (pos == 0
74 || (it != list_.begin() && boost::prior(it)->pos() == pos - 1))) {
76 // If it is a multi-character font
77 // entry, we just make it smaller
78 // (see update below), otherwise we
79 // should delete it.
80 unsigned int const i = it - list_.begin();
81 list_.erase(it);
82 if (i >= list_.size())
83 return;
84 it = list_.begin() + i;
85 if (i > 0 && i < list_.size() &&
86 list_[i - 1].font() == list_[i].font()) {
87 list_.erase(beg + i - 1);
88 it = list_.begin() + i - 1;
92 // Update all other entries
93 iterator end = list_.end();
94 for (; it != end; ++it)
95 it->pos(it->pos() - 1);
98 void FontList::increasePosAfterPos(pos_type pos)
100 List::iterator end = list_.end();
101 List::iterator it = fontIterator(pos);
102 for (; it != end; ++it)
103 ++it->pos_;
107 void FontList::decreasePosAfterPos(pos_type pos)
109 List::iterator end = list_.end();
110 List::iterator it = fontIterator(pos);
111 for (; it != end; ++it)
112 --it->pos_;
116 void FontList::setRange(pos_type startpos, pos_type endpos, Font const & font)
118 // FIXME: Optimize!!!
119 for (pos_type pos = startpos; pos != endpos; ++pos)
120 set(pos, font);
124 void FontList::set(pos_type pos, Font const & font)
126 // No need to simplify this because it will disappear
127 // in a new kernel. (Asger)
128 // Next search font table
130 List::iterator it = fontIterator(pos);
131 bool const found = it != list_.end();
132 if (found && it->font() == font)
133 // Font is already set.
134 return;
136 size_t const i = distance(list_.begin(), it);
138 // Is position pos a beginning of a font block?
139 bool const begin = pos == 0 || !found
140 || (i > 0 && list_[i - 1].pos() == pos - 1);
142 // Is position pos at the end of a font block?
143 bool const end = found && list_[i].pos() == pos;
145 if (!begin && !end) {
146 // The general case: The block is splitted into 3 blocks
147 list_.insert(list_.begin() + i,
148 FontTable(pos - 1, list_[i].font()));
149 list_.insert(list_.begin() + i + 1,
150 FontTable(pos, font));
151 return;
154 if (begin && end) {
155 // A single char block
156 if (i + 1 < list_.size() &&
157 list_[i + 1].font() == font) {
158 // Merge the singleton block with the next block
159 list_.erase(list_.begin() + i);
160 if (i > 0 && list_[i - 1].font() == font)
161 list_.erase(list_.begin() + i - 1);
162 } else if (i > 0 && list_[i - 1].font() == font) {
163 // Merge the singleton block with the previous block
164 list_[i - 1].pos(pos);
165 list_.erase(list_.begin() + i);
166 } else
167 list_[i].font(font);
168 } else if (begin) {
169 if (i > 0 && list_[i - 1].font() == font)
170 list_[i - 1].pos(pos);
171 else
172 list_.insert(list_.begin() + i,
173 FontTable(pos, font));
174 } else if (end) {
175 list_[i].pos(pos - 1);
176 if (!(i + 1 < list_.size() &&
177 list_[i + 1].font() == font))
178 list_.insert(list_.begin() + i + 1,
179 FontTable(pos, font));
184 void FontList::setMisspelled(pos_type startpos, pos_type endpos,
185 bool misspelled)
187 List::iterator start = fontIterator(startpos);
188 if (misspelled && start->font().isMisspelled())
189 return;
190 if (!misspelled && !start->font().isMisspelled())
191 return;
193 Font f = start->font();
194 f.setMisspelled(misspelled);
195 setRange(startpos, endpos, f);
199 FontSize FontList::highestInRange(pos_type startpos, pos_type endpos,
200 FontSize def_size) const
202 if (list_.empty())
203 return def_size;
205 List::const_iterator end_it = fontIterator(endpos);
206 const_iterator const end = list_.end();
207 if (end_it != end)
208 ++end_it;
210 List::const_iterator cit = fontIterator(startpos);
212 FontSize maxsize = FONT_SIZE_TINY;
213 for (; cit != end_it; ++cit) {
214 FontSize size = cit->font().fontInfo().size();
215 if (size == FONT_SIZE_INHERIT)
216 size = def_size;
217 if (size > maxsize && size <= FONT_SIZE_HUGER)
218 maxsize = size;
220 return maxsize;
224 bool FontList::hasChangeInRange(pos_type pos, int len) const
226 List::const_iterator cit = fontIterator(pos);
227 return cit == list_.end() || pos + len - 1 <= cit->pos();
231 void FontList::validate(LaTeXFeatures & features) const
233 const_iterator fcit = list_.begin();
234 const_iterator fend = list_.end();
235 for (; fcit != fend; ++fcit)
236 fcit->font().validate(features);
239 } // namespace lyx