]> git.lyx.org Git - lyx.git/blob - src/FontList.cpp
5c7ea5b0debab2cc67c6759de7c4fb9083e868ac
[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 std::distance;
28 using std::endl;
29 using std::string;
30 using std::ostream;
31
32 namespace lyx {
33
34
35 FontList::iterator FontList::fontIterator(pos_type pos)
36 {
37         static Font dummy;
38         FontTable search_elem(pos, dummy);
39         return lower_bound(list_.begin(), list_.end(), search_elem,
40                 matchFT());
41 }
42
43
44 FontList::const_iterator FontList::fontIterator(pos_type pos) const
45 {
46         static Font dummy;
47         FontTable search_elem(pos, dummy);
48         return lower_bound(list_.begin(), list_.end(), search_elem,
49                 matchFT());
50 }
51
52
53 Font & FontList::get(pos_type pos)
54 {
55         iterator end = list_.end();
56         iterator it = fontIterator(pos);
57         if (it != end && it->pos == pos)
58                 return it->font_;
59         static Font 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 != beg && boost::prior(it)->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 - beg;
78                 list_.erase(beg + i);
79                 it = beg + i;
80                 if (i > 0 && i < list_.size() &&
81                     list_[i - 1].font() == list_[i].font()) {
82                         list_.erase(beg + i - 1);
83                         it = beg + i - 1;
84                 }
85         }
86
87         // Update all other entries
88         iterator end = list_.end();
89         for (; it != end; ++it)
90                 it->pos(it->pos() - 1);
91 }
92
93 void FontList::increasePosAfterPos(pos_type pos)
94 {
95         List::iterator end = list_.end();
96         List::iterator it = fontIterator(pos);
97         for (; it != end; ++it)
98                 ++it->pos_;
99 }
100
101
102 void FontList::decreasePosAfterPos(pos_type pos)
103 {
104         List::iterator end = list_.end();
105         List::iterator it = fontIterator(pos);
106         for (; it != end; ++it)
107                 --it->pos_;
108 }
109
110
111 void FontList::set(pos_type pos, Font const & font)
112 {
113         // No need to simplify this because it will disappear
114         // in a new kernel. (Asger)
115         // Next search font table
116
117         iterator beg = list_.begin();
118         iterator it = beg;
119         iterator endit = list_.end();
120         for (; it != endit; ++it) {
121                 if (it->pos() >= pos)
122                         break;
123         }
124         size_t const i = distance(beg, it);
125         bool notfound = (it == endit);
126
127         if (!notfound && list_[i].font() == font)
128                 return;
129
130         bool begin = pos == 0 || notfound ||
131                 (i > 0 && list_[i - 1].pos() == pos - 1);
132         // Is position pos is a beginning of a font block?
133         bool end = !notfound && list_[i].pos() == pos;
134         // Is position pos is the end of a font block?
135         if (begin && end) { // A single char block
136                 if (i + 1 < list_.size() &&
137                     list_[i + 1].font() == font) {
138                         // Merge the singleton block with the next block
139                         list_.erase(list_.begin() + i);
140                         if (i > 0 && list_[i - 1].font() == font)
141                                 list_.erase(list_.begin() + i - 1);
142                 } else if (i > 0 && list_[i - 1].font() == font) {
143                         // Merge the singleton block with the previous block
144                         list_[i - 1].pos(pos);
145                         list_.erase(list_.begin() + i);
146                 } else
147                         list_[i].font(font);
148         } else if (begin) {
149                 if (i > 0 && list_[i - 1].font() == font)
150                         list_[i - 1].pos(pos);
151                 else
152                         list_.insert(list_.begin() + i,
153                                         FontTable(pos, font));
154         } else if (end) {
155                 list_[i].pos(pos - 1);
156                 if (!(i + 1 < list_.size() &&
157                       list_[i + 1].font() == font))
158                         list_.insert(list_.begin() + i + 1,
159                                         FontTable(pos, font));
160         } else { // The general case. The block is splitted into 3 blocks
161                 list_.insert(list_.begin() + i,
162                                 FontTable(pos - 1, list_[i].font()));
163                 list_.insert(list_.begin() + i + 1,
164                                 FontTable(pos, font));
165         }
166 }
167
168 } // namespace lyx