]> git.lyx.org Git - lyx.git/blob - src/FontList.cpp
add short git hash to name of devel disk images to get different names for devel...
[lyx.git] / src / FontList.cpp
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.
5  *
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
15  *
16  * Full author contact details are available in file CREDITS.
17  */
18
19 #include <config.h>
20
21 #include "FontList.h"
22
23 #include <boost/next_prior.hpp>
24
25 #include <algorithm>
26
27 using namespace std;
28
29 namespace lyx {
30
31
32 FontList::iterator FontList::fontIterator(pos_type pos)
33 {
34         FontList::iterator it = list_.begin();
35         FontList::iterator end = list_.end();
36         for (; it != end; ++it) {
37                 if (it->pos() >= pos)
38                         break;
39         }
40         return it;
41 }
42
43
44 FontList::const_iterator FontList::fontIterator(pos_type pos) const
45 {
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;
51         }
52         return it;
53 }
54
55
56 Font const & FontList::get(pos_type pos)
57 {
58         iterator end = list_.end();
59         iterator it = fontIterator(pos);
60         if (it != end && it->pos() == pos)
61                 return it->font_;
62
63         static Font const dummy;
64         return dummy;
65 }
66
67
68 void FontList::erase(pos_type pos)
69 {
70         // Erase entries in the tables.
71         iterator it = fontIterator(pos);
72         iterator beg = list_.begin();
73         if (it != list_.end() && it->pos() == pos
74                 && (pos == 0 
75                         || (it != list_.begin() && boost::prior(it)->pos() == pos - 1))) {
76
77                 // If it is a multi-character font
78                 // entry, we just make it smaller
79                 // (see update below), otherwise we
80                 // should delete it.
81                 unsigned int const i = it - list_.begin();
82                 list_.erase(it);
83                 if (i >= list_.size())
84                         return;
85                 it = list_.begin() + i;
86                 if (i > 0 && i < list_.size() &&
87                     list_[i - 1].font() == list_[i].font()) {
88                         list_.erase(beg + i - 1);
89                         it = list_.begin() + i - 1;
90                 }
91         }
92
93         // Update all other entries
94         iterator end = list_.end();
95         for (; it != end; ++it)
96                 it->pos(it->pos() - 1);
97 }
98
99 void FontList::increasePosAfterPos(pos_type pos)
100 {
101         List::iterator end = list_.end();
102         List::iterator it = fontIterator(pos);
103         for (; it != end; ++it)
104                 ++it->pos_;
105 }
106
107
108 void FontList::decreasePosAfterPos(pos_type pos)
109 {
110         List::iterator end = list_.end();
111         List::iterator it = fontIterator(pos);
112         for (; it != end; ++it)
113                 --it->pos_;
114 }
115
116
117 void FontList::setRange(pos_type startpos, pos_type endpos, Font const & font)
118 {
119         // FIXME: Optimize!!!
120         for (pos_type pos = startpos; pos != endpos; ++pos)
121                 set(pos, font);
122 }
123
124
125 void FontList::set(pos_type pos, Font const & font)
126 {
127         // No need to simplify this because it will disappear
128         // in a new kernel. (Asger)
129         // Next search font table
130
131         List::iterator it = fontIterator(pos);
132         bool const found = it != list_.end();
133         if (found && it->font() == font)
134                 // Font is already set.
135                 return;
136
137         size_t const i = distance(list_.begin(), it);
138
139         // Is position pos a beginning of a font block?
140         bool const begin = pos == 0 || !found 
141                 || (i > 0 && list_[i - 1].pos() == pos - 1);
142
143         // Is position pos at the end of a font block?
144         bool const end = found && list_[i].pos() == pos;
145
146         if (!begin && !end) {
147                 // The general case: The block is split into 3 blocks
148                 list_.insert(list_.begin() + i,
149                                 FontTable(pos - 1, list_[i].font()));
150                 list_.insert(list_.begin() + i + 1,
151                                 FontTable(pos, font));
152                 return;
153         }
154
155         if (begin && end) {
156                 // A single char block
157                 if (i + 1 < list_.size() &&
158                     list_[i + 1].font() == font) {
159                         // Merge the singleton block with the next block
160                         list_.erase(list_.begin() + i);
161                         if (i > 0 && list_[i - 1].font() == font)
162                                 list_.erase(list_.begin() + i - 1);
163                 } else if (i > 0 && list_[i - 1].font() == font) {
164                         // Merge the singleton block with the previous block
165                         list_[i - 1].pos(pos);
166                         list_.erase(list_.begin() + i);
167                 } else
168                         list_[i].font(font);
169         } else if (begin) {
170                 if (i > 0 && list_[i - 1].font() == font)
171                         list_[i - 1].pos(pos);
172                 else
173                         list_.insert(list_.begin() + i,
174                                         FontTable(pos, font));
175         } else if (end) {
176                 list_[i].pos(pos - 1);
177                 if (!(i + 1 < list_.size() &&
178                       list_[i + 1].font() == font))
179                         list_.insert(list_.begin() + i + 1,
180                                         FontTable(pos, font));
181         }
182 }
183
184
185 FontSize FontList::highestInRange(pos_type startpos, pos_type endpos,
186         FontSize def_size) const
187 {
188         if (list_.empty())
189                 return def_size;
190
191         List::const_iterator end_it = fontIterator(endpos);
192         const_iterator const end = list_.end();
193         if (end_it != end)
194                 ++end_it;
195
196         List::const_iterator cit = fontIterator(startpos);
197
198         FontSize maxsize = FONT_SIZE_TINY;
199         for (; cit != end_it; ++cit) {
200                 FontSize size = cit->font().fontInfo().size();
201                 if (size == FONT_SIZE_INHERIT)
202                         size = def_size;
203                 if (size > maxsize && size <= FONT_SIZE_HUGER)
204                         maxsize = size;
205         }
206         return maxsize;
207 }
208
209
210 bool FontList::hasChangeInRange(pos_type pos, int len) const
211 {
212         List::const_iterator cit = fontIterator(pos);
213         return cit == list_.end() || pos + len - 1 <= cit->pos();
214 }
215
216
217 void FontList::validate(LaTeXFeatures & features) const
218 {
219         const_iterator fcit = list_.begin();
220         const_iterator fend = list_.end();
221         for (; fcit != fend; ++fcit)
222                 fcit->font().validate(features);
223 }
224
225 } // namespace lyx