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