#include "text.h"
#include "exc.H"
#include "container.h"
#include "frame.h"
#include "canvas.h"
#include "bloputils.h"
#include <cstdio>
namespace blop
{
string text::transform_text_(const string &s)
{
string result = before_;
if(verbatim_)
{
result += "\\texttt{";
for(unsigned int i=0; i<s.size(); ++i)
{
if(s[i] == ' ')
{
if(i==0 || s[i-1] != ' ')
{
result += "\\phantom{";
}
result += 'x';
if(i==s.size()-1 || s[i+1] != ' ')
{
result += "}";
}
}
else result += s[i];
}
result += "}";
}
else result += s;
result += after_;
return result;
}
text &text::verbatim(bool f)
{
if(f == verbatim_) return *this;
verbatim_ = f;
recalculate_size_();
return *this;
}
text &text::align(sym::position a)
{
if(a!=sym::left && a!=sym::right && a!=sym::center)
{
warning::print("Text alignment can only be left|right|center","text::align(...)");
}
else align_ = a;
return *this;
}
text &text::draw(container *parent, const var &ttt)
{
if(parent == 0) err("text::draw ==> parent == 0");
text *t = new text(ttt);
t->autodel(true);
parent->add(t);
return *t;
}
text &text::fdraw(const var &ttt)
{
return text::draw(&frame::current(),ttt);
}
text &text::pdraw(const var &ttt)
{
return text::draw(&pad::current(),ttt);
}
text &text::cdraw(const var &ttt)
{
return text::draw(&canvas::current(),ttt);
}
text::text(const var &ttt) : verbatim_(false), color_(0,0,0), gap_(0.3*EX)
{
vector<string> lines;
split(ttt,"\n",lines);
for(unsigned int i=0; i<lines.size(); ++i) add_line(lines[i]);
}
void text::recalculate_size_()
{
fix_width(false);
fix_height(false);
length height = 0.0;
vector<string> transformed_lines(lines_.size());
for(unsigned int i=0; i<lines_.size(); ++i) transformed_lines[i] = transform_text_(lines_[i]);
for(unsigned int i=0; i<transformed_lines.size(); ++i) height += blop::height(transformed_lines[i],0);
if(transformed_lines.size()>1) height += gap_*(transformed_lines.size()-1);
box::height(height);
box::width(maxwidth(transformed_lines));
fix_width(true);
fix_height(true);
}
text &text::add_line(const var &line)
{
lines_.push_back(line.str());
recalculate_size_();
return *this;
}
text &text::gap(const length &l)
{
gap_ = l;
recalculate_size_();
return *this;
}
text &text::width(const length &)
{
warning::print("The width of a text can not be set","text::width(const length &)");
return *this;
}
text &text::height(const length &)
{
warning::print("The height of a text can not be set","text::height(const length &)");
return *this;
}
text &text::left(const length &l)
{
box::left(l);
return *this;
}
text &text::right(const length &l)
{
box::right(l);
return *this;
}
text &text::xcenter(const length &l)
{
box::xcenter(l);
return *this;
}
text &text::bottom(const length &l)
{
box::bottom(l);
return *this;
}
text &text::top(const length &l)
{
box::top(l);
return *this;
}
text &text::ycenter(const length &l)
{
box::ycenter(l);
return *this;
}
void text::print(terminal *t)
{
if(print_me_<2) return;
t->set_color(color_);
for(unsigned int i=0; i<lines_.size(); ++i)
{
string tt = transform_text_(lines_[i]);
if(align_ == sym::right)
{
t->draw_text(terminal::coord(right().termspecific_id(),ypositions_[i].termspecific_id()),
tt,
sym::right,
sym::top,
0,
false);
}
else if(align_ == sym::center)
{
t->draw_text(terminal::coord(xcenter().termspecific_id(),ypositions_[i].termspecific_id()),
tt,
sym::center,
sym::top,
0,
false);
}
else
{
t->draw_text(terminal::coord(left().termspecific_id(),ypositions_[i].termspecific_id()),
tt,
sym::left,
sym::top,
0,
false);
}
}
}
void text::prepare_for_draw()
{
if(print_me_<1) return;
box::prepare_for_draw();
ypositions_.clear();
ypositions_.resize(lines_.size());
ypositions_[0] = box::top();
ypositions_[0].register_me();
for(unsigned int i=1; i<lines_.size(); ++i)
{
ypositions_[i] = ypositions_[i-1]-blop::height(lines_[i-1])-gap_;
ypositions_[i].register_me();
}
}
}