2007-10-19 14:35:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* \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<EFBFBD>nnes
|
|
|
|
|
* \author Jean-Marc Lasgouttes
|
|
|
|
|
* \author Angus Leeming
|
|
|
|
|
* \author John Levon
|
|
|
|
|
* \author Andr<EFBFBD> P<EFBFBD>nitz
|
|
|
|
|
* \author Dekel Tsur
|
|
|
|
|
* \author J<EFBFBD>rgen Vigna
|
|
|
|
|
* \author Abdelrazak Younes
|
|
|
|
|
*
|
|
|
|
|
* Full author contact details are available in file CREDITS.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
|
|
#include "FontList.h"
|
|
|
|
|
|
|
|
|
|
#include <boost/next_prior.hpp>
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
using std::distance;
|
|
|
|
|
using std::endl;
|
|
|
|
|
using std::string;
|
|
|
|
|
using std::ostream;
|
|
|
|
|
|
|
|
|
|
namespace lyx {
|
|
|
|
|
|
2007-10-19 14:47:32 +00:00
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
class matchFT
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
/// used by lower_bound and upper_bound
|
|
|
|
|
int operator()(FontTable const & a, FontTable const & b) const {
|
|
|
|
|
return a.pos() < b.pos();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // anon namespace
|
2007-10-19 14:35:05 +00:00
|
|
|
|
|
|
|
|
|
FontList::iterator FontList::fontIterator(pos_type pos)
|
|
|
|
|
{
|
|
|
|
|
static Font dummy;
|
|
|
|
|
FontTable search_elem(pos, dummy);
|
|
|
|
|
return lower_bound(list_.begin(), list_.end(), search_elem,
|
|
|
|
|
matchFT());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FontList::const_iterator FontList::fontIterator(pos_type pos) const
|
|
|
|
|
{
|
|
|
|
|
static Font dummy;
|
|
|
|
|
FontTable search_elem(pos, dummy);
|
|
|
|
|
return lower_bound(list_.begin(), list_.end(), search_elem,
|
|
|
|
|
matchFT());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Font & FontList::get(pos_type pos)
|
|
|
|
|
{
|
|
|
|
|
iterator end = list_.end();
|
|
|
|
|
iterator it = fontIterator(pos);
|
2007-10-19 15:23:11 +00:00
|
|
|
|
if (it != end && it->pos() == pos)
|
2007-10-19 14:35:05 +00:00
|
|
|
|
return it->font_;
|
|
|
|
|
static Font 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
|
2007-10-20 21:27:22 +00:00
|
|
|
|
|| (it != list_.begin() && boost::prior(it)->pos() == pos - 1))) {
|
2007-10-19 14:35:05 +00:00
|
|
|
|
|
|
|
|
|
// If it is a multi-character font
|
|
|
|
|
// entry, we just make it smaller
|
|
|
|
|
// (see update below), otherwise we
|
|
|
|
|
// should delete it.
|
2007-10-20 21:27:22 +00:00
|
|
|
|
unsigned int const i = it - list_.begin();
|
|
|
|
|
list_.erase(it);
|
|
|
|
|
if (i >= list_.size())
|
|
|
|
|
return;
|
|
|
|
|
it = list_.begin() + i;
|
2007-10-19 14:35:05 +00:00
|
|
|
|
if (i > 0 && i < list_.size() &&
|
|
|
|
|
list_[i - 1].font() == list_[i].font()) {
|
|
|
|
|
list_.erase(beg + i - 1);
|
2007-10-20 21:27:22 +00:00
|
|
|
|
it = list_.begin() + i - 1;
|
2007-10-19 14:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
|
iterator beg = list_.begin();
|
|
|
|
|
iterator it = beg;
|
|
|
|
|
iterator endit = list_.end();
|
|
|
|
|
for (; it != endit; ++it) {
|
|
|
|
|
if (it->pos() >= pos)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
size_t const i = distance(beg, it);
|
|
|
|
|
bool notfound = (it == endit);
|
|
|
|
|
|
|
|
|
|
if (!notfound && list_[i].font() == font)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool begin = pos == 0 || notfound ||
|
|
|
|
|
(i > 0 && list_[i - 1].pos() == pos - 1);
|
|
|
|
|
// Is position pos is a beginning of a font block?
|
|
|
|
|
bool end = !notfound && list_[i].pos() == pos;
|
|
|
|
|
// Is position pos is the end of a font block?
|
|
|
|
|
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));
|
|
|
|
|
} else { // The general case. The block is splitted into 3 blocks
|
|
|
|
|
list_.insert(list_.begin() + i,
|
|
|
|
|
FontTable(pos - 1, list_[i].font()));
|
|
|
|
|
list_.insert(list_.begin() + i + 1,
|
|
|
|
|
FontTable(pos, font));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-19 14:55:44 +00:00
|
|
|
|
|
|
|
|
|
Font_size FontList::highestInRange
|
|
|
|
|
(pos_type startpos, pos_type endpos, Font_size def_size) const
|
|
|
|
|
{
|
|
|
|
|
if (list_.empty())
|
|
|
|
|
return def_size;
|
|
|
|
|
|
|
|
|
|
const_iterator end_it = list_.begin();
|
|
|
|
|
const_iterator const end = list_.end();
|
|
|
|
|
for (; end_it != end; ++end_it) {
|
|
|
|
|
if (end_it->pos() >= endpos)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (end_it != end)
|
|
|
|
|
++end_it;
|
|
|
|
|
|
|
|
|
|
FontList::const_iterator cit = list_.begin();
|
|
|
|
|
for (; cit != end; ++cit) {
|
|
|
|
|
if (cit->pos() >= startpos)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Font::FONT_SIZE maxsize = Font::SIZE_TINY;
|
|
|
|
|
for (; cit != end_it; ++cit) {
|
|
|
|
|
Font::FONT_SIZE size = cit->font().size();
|
|
|
|
|
if (size == Font::INHERIT_SIZE)
|
|
|
|
|
size = def_size;
|
|
|
|
|
if (size > maxsize && size <= Font::SIZE_HUGER)
|
|
|
|
|
maxsize = size;
|
|
|
|
|
}
|
|
|
|
|
return maxsize;
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-19 15:30:54 +00:00
|
|
|
|
|
|
|
|
|
bool FontList::hasChangeInRange(pos_type pos, int len) const
|
|
|
|
|
{
|
|
|
|
|
// FIXME: can't we use fontIterator(pos) instead?
|
|
|
|
|
const_iterator cit = list_.begin();
|
|
|
|
|
const_iterator end = list_.end();
|
|
|
|
|
for (; cit != end; ++cit) {
|
|
|
|
|
if (cit->pos() >= pos)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (cit != end && pos + len - 1 > cit->pos())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-19 16:01:32 +00:00
|
|
|
|
|
|
|
|
|
void FontList::validate(LaTeXFeatures & features) const
|
|
|
|
|
{
|
|
|
|
|
const_iterator fcit = list_.begin();
|
|
|
|
|
const_iterator fend = list_.end();
|
2007-10-19 16:22:36 +00:00
|
|
|
|
for (; fcit != fend; ++fcit)
|
|
|
|
|
fcit->font().validate(features);
|
2007-10-19 16:01:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-19 14:35:05 +00:00
|
|
|
|
} // namespace lyx
|