mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
142 lines
No EOL
3.7 KiB
C++
142 lines
No EOL
3.7 KiB
C++
#include "RichText.h"
|
|
|
|
namespace Upp {
|
|
|
|
struct RichNumberField : RichPara::FieldType {
|
|
virtual Array<RichPara::Part> Evaluate(const String& param, VectorMap<String, Value>& vars,
|
|
const RichPara::CharFormat& fmt) {
|
|
String h = AsString(vars.Get(param, Null));
|
|
Array<RichPara::Part> ps;
|
|
RichPara::Part& p = ps.Add();
|
|
p.format = fmt;
|
|
if(!IsNull(vars.Get("__DISPLAY_VALUE_FIELDS", Null)))
|
|
p.format.paper = WhiteGray();
|
|
p.text = h.ToWString();
|
|
return ps;
|
|
}
|
|
};
|
|
|
|
INITBLOCK {
|
|
RichPara::Register<RichNumberField>("VALUE");
|
|
}
|
|
|
|
RichText& GetHeaderFooterText(RichText *text, int page, int pagecount)
|
|
{
|
|
VectorMap<String, Value> vars;
|
|
vars.Add("PAGENUMBER", page + 1);
|
|
vars.Add("PAGECOUNT", pagecount);
|
|
text->EvaluateFields(vars);
|
|
return *text;
|
|
}
|
|
|
|
RichContext::RichContext(const RichStyles& styles, const RichText *text)
|
|
: text(text), styles(&styles)
|
|
{
|
|
header_cy = footer_cy = 0;
|
|
current_header_cy = current_footer_cy = 0;
|
|
}
|
|
|
|
void RichContext::HeaderFooter(RichText *header_, RichText *footer_)
|
|
{
|
|
header = header_;
|
|
footer = footer_;
|
|
int cx = page.GetWidth();
|
|
header_cy = header ? GetHeaderFooterText(header, 999990, 999990).GetHeight(cx) : 0;
|
|
footer_cy = footer ? GetHeaderFooterText(footer, 999990, 999990).GetHeight(cx) : 0;
|
|
int maxcy = page.GetHeight();
|
|
if(maxcy < INT_MAX / 2)
|
|
maxcy = maxcy * 4 / 5;
|
|
if(header_cy + footer_cy > maxcy)
|
|
header_cy = footer_cy = 0;
|
|
}
|
|
|
|
void RichContext::AdjustPage()
|
|
{
|
|
page.top += header_cy - current_header_cy;
|
|
page.bottom -= footer_cy - current_footer_cy;
|
|
current_header_cy = header_cy;
|
|
current_footer_cy = footer_cy;
|
|
}
|
|
|
|
void RichContext::Set(PageY p0, const Rect& first_page, const Rect& next_page, PageY p)
|
|
{ // table layout helper, real hdr/ftr is irrelevant, need correct page.top / page.bottom
|
|
current_header_cy = current_footer_cy = 0;
|
|
if(p.page != p0.page) { // we are already on next page
|
|
page = next_page;
|
|
header_cy = footer_cy = 0;
|
|
}
|
|
else {
|
|
page = first_page;
|
|
header_cy = next_page.top - page.top;
|
|
footer_cy = page.bottom - next_page.bottom;
|
|
}
|
|
py = p;
|
|
}
|
|
|
|
void RichContext::Page()
|
|
{
|
|
py.page++;
|
|
AdjustPage();
|
|
py.y = page.top;
|
|
}
|
|
|
|
RichContext RichText::Context(const Rect& page, PageY py, RichText *header, RichText *footer) const
|
|
{
|
|
RichContext rc(style, this);
|
|
rc.page = page;
|
|
rc.py = py;
|
|
rc.HeaderFooter(header, footer);
|
|
rc.AdjustPage();
|
|
if(rc.py.y < rc.page.top)
|
|
rc.py.y = rc.page.top;
|
|
return rc;
|
|
}
|
|
|
|
void RichText::PaintHeaderFooter(PageDraw& pw, const Rect& page, PageY py, const PaintInfo& pi_,
|
|
int from_page, int to_page) const
|
|
{
|
|
PaintInfo pi = pi_;
|
|
pi.sell = pi.selh = 0;
|
|
RichContext rc = Context(page, py);
|
|
int last_page = -1;
|
|
int pagecount = GetHeight(page).page + 1;
|
|
int i = 0;
|
|
while(last_page <= to_page) {
|
|
while(last_page < rc.py.page) {
|
|
last_page++;
|
|
if(last_page >= from_page && (rc.header || rc.footer)) {
|
|
if(rc.header_cy)
|
|
GetHeaderFooterText(rc.header, last_page, pagecount).Paint(pw, PageY(last_page, page.top), page, pi);
|
|
if(rc.footer_cy)
|
|
GetHeaderFooterText(rc.footer, last_page, pagecount).Paint(pw, PageY(last_page, page.bottom - rc.footer_cy), page, pi);
|
|
}
|
|
}
|
|
if(++i >= GetPartCount())
|
|
break;
|
|
RichContext begin;
|
|
Advance(i, rc, begin);
|
|
}
|
|
}
|
|
|
|
void SetQTF(One<RichText>& txt, const String& qtf)
|
|
{
|
|
txt.Clear();
|
|
if(qtf.GetCount())
|
|
txt.Create() = ParseQTF(qtf);
|
|
}
|
|
|
|
void RichTxt::SetHeaderQtf(const char *qtf)
|
|
{
|
|
header_qtf = qtf;
|
|
SetQTF(header, header_qtf);
|
|
r_type = ALL;
|
|
}
|
|
|
|
void RichTxt::SetFooterQtf(const char *qtf)
|
|
{
|
|
footer_qtf = qtf;
|
|
SetQTF(footer, footer_qtf);
|
|
r_type = ALL;
|
|
}
|
|
|
|
} |