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