lyx_mirror/src/FontList.cpp
2020-10-20 11:38:55 +03:00

182 lines
4.1 KiB
C++

/**
* \file FontList.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Asger Alstrup
* \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
* \author John Levon
* \author André Pönitz
* \author Dekel Tsur
* \author Jürgen Vigna
* \author Abdelrazak Younes
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "FontList.h"
using namespace std;
namespace lyx {
FontList::iterator FontList::fontIterator(pos_type pos)
{
FontList::iterator it = list_.begin();
FontList::iterator end = list_.end();
for (; it != end; ++it) {
if (it->pos() >= pos)
break;
}
return it;
}
FontList::const_iterator FontList::fontIterator(pos_type pos) const
{
FontList::const_iterator it = list_.begin();
FontList::const_iterator end = list_.end();
for (; it != end; ++it) {
if (it->pos() >= pos)
break;
}
return it;
}
Font const & FontList::get(pos_type pos)
{
iterator end = list_.end();
iterator it = fontIterator(pos);
if (it != end && it->pos() == pos)
return it->font_;
static Font const dummy;
return dummy;
}
void FontList::erase(pos_type pos)
{
// Erase entries in the tables.
iterator it = fontIterator(pos);
iterator beg = list_.begin();
if (it != list_.end() && it->pos() == pos
&& (pos == 0
|| (it != list_.begin() && prev(it, 1)->pos() == pos - 1))) {
// If it is a multi-character font
// entry, we just make it smaller
// (see update below), otherwise we
// should delete it.
unsigned int const i = it - list_.begin();
list_.erase(it);
if (i >= list_.size())
return;
it = list_.begin() + i;
if (i > 0 && i < list_.size() &&
list_[i - 1].font() == list_[i].font()) {
list_.erase(beg + i - 1);
it = list_.begin() + i - 1;
}
}
// Update all other entries
iterator end = list_.end();
for (; it != end; ++it)
it->pos(it->pos() - 1);
}
void FontList::increasePosAfterPos(pos_type pos)
{
List::iterator end = list_.end();
List::iterator it = fontIterator(pos);
for (; it != end; ++it)
++it->pos_;
}
void FontList::decreasePosAfterPos(pos_type pos)
{
List::iterator end = list_.end();
List::iterator it = fontIterator(pos);
for (; it != end; ++it)
--it->pos_;
}
void FontList::set(pos_type pos, Font const & font)
{
// No need to simplify this because it will disappear
// in a new kernel. (Asger)
// Next search font table
List::iterator it = fontIterator(pos);
bool const found = it != list_.end();
if (found && it->font() == font)
// Font is already set.
return;
size_t const i = distance(list_.begin(), it);
// Is position pos a beginning of a font block?
bool const begin = pos == 0 || !found
|| (i > 0 && list_[i - 1].pos() == pos - 1);
// Is position pos at the end of a font block?
bool const end = found && list_[i].pos() == pos;
if (!begin && !end) {
// The general case: The block is split into 3 blocks
list_.insert(list_.begin() + i,
FontTable(pos - 1, list_[i].font()));
list_.insert(list_.begin() + i + 1,
FontTable(pos, font));
return;
}
if (begin && end) {
// A single char block
if (i + 1 < list_.size() &&
list_[i + 1].font() == font) {
// Merge the singleton block with the next block
list_.erase(list_.begin() + i);
if (i > 0 && list_[i - 1].font() == font)
list_.erase(list_.begin() + i - 1);
} else if (i > 0 && list_[i - 1].font() == font) {
// Merge the singleton block with the previous block
list_[i - 1].pos(pos);
list_.erase(list_.begin() + i);
} else
list_[i].font(font);
} else if (begin) {
if (i > 0 && list_[i - 1].font() == font)
list_[i - 1].pos(pos);
else
list_.insert(list_.begin() + i,
FontTable(pos, font));
} else if (end) {
list_[i].pos(pos - 1);
if (!(i + 1 < list_.size() &&
list_[i + 1].font() == font))
list_.insert(list_.begin() + i + 1,
FontTable(pos, font));
}
}
void FontList::validate(LaTeXFeatures & features) const
{
const_iterator fcit = list_.begin();
const_iterator fend = list_.end();
for (; fcit != fend; ++fcit)
fcit->font().validate(features);
}
} // namespace lyx