mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-09-01 07:42:40 -06:00
RichText: Header/Footer now can be defined for NEXT page, without breaking the page
git-svn-id: svn://ultimatepp.org/upp/trunk@10854 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
7f73bb3714
commit
beab1177bd
11 changed files with 493 additions and 417 deletions
|
|
@ -29,10 +29,15 @@ RichText& GetHeaderFooterText(RichText *text, int page, int pagecount)
|
|||
return *text;
|
||||
}
|
||||
|
||||
void RichContext::NewHeaderFooter(RichText *header_, RichText *footer_)
|
||||
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_)
|
||||
{
|
||||
page.top -= header_cy;
|
||||
page.bottom += footer_cy;
|
||||
header = header_;
|
||||
footer = footer_;
|
||||
int cx = page.GetWidth();
|
||||
|
|
@ -43,8 +48,36 @@ void RichContext::NewHeaderFooter(RichText *header_, RichText *footer_)
|
|||
maxcy = maxcy * 4 / 5;
|
||||
if(header_cy + footer_cy > maxcy)
|
||||
header_cy = footer_cy = 0;
|
||||
page.top += header_cy;
|
||||
page.bottom -= footer_cy;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -52,7 +85,8 @@ RichContext RichText::Context(const Rect& page, PageY py, RichText *header, Rich
|
|||
RichContext rc(style, this);
|
||||
rc.page = page;
|
||||
rc.py = py;
|
||||
rc.NewHeaderFooter(header, footer);
|
||||
rc.HeaderFooter(header, footer);
|
||||
rc.AdjustPage();
|
||||
if(rc.py.y < rc.page.top)
|
||||
rc.py.y = rc.page.top;
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -265,11 +265,11 @@ struct RichPara {
|
|||
void GetRichPos(RichPos& rp, int pos) const;
|
||||
|
||||
Lines FormatLines(int cx) const;
|
||||
void Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo& pi, const Number& n, const Bits& spellerror, bool baselevel) const;
|
||||
RichCaret GetCaret(int pos, const Rect& page, PageY py) const;
|
||||
int GetPos(int x, PageY y, const Rect& page, PageY py) const;
|
||||
void GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const;
|
||||
void GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const;
|
||||
void Paint(PageDraw& pw, RichContext rc, const PaintInfo& pi, const Number& n, const Bits& spellerror, bool baselevel) const;
|
||||
RichCaret GetCaret(int pos, RichContext rc) const;
|
||||
int GetPos(int x, PageY y, RichContext rc) const;
|
||||
void GatherLabels(Vector<RichValPos>& info, RichContext rc, int pos) const;
|
||||
void GatherIndexes(Vector<RichValPos>& info, RichContext rc, int pos) const;
|
||||
int GetVertMove(int pos, int gx, const Rect& page, int dir) const;
|
||||
|
||||
WString GetText() const;
|
||||
|
|
@ -296,8 +296,8 @@ struct RichPara {
|
|||
private:
|
||||
Tab GetNextTab(int pos, int cx) const;
|
||||
void Smh(Lines& lines, HeightInfo *th, int cx) const;
|
||||
Lines Begin(const Rect& page, PageY& py) const;
|
||||
bool BreaksPage(PageY py, const Lines& pl, int i, const Rect& page) const;
|
||||
Lines Begin(RichContext& rc) const;
|
||||
bool BreaksPage(const RichContext& rc, const Lines& pl, int i) const;
|
||||
void PackParts(Stream& out, const CharFormat& chrstyle,
|
||||
const Array<Part>& part, CharFormat& cf,
|
||||
Array<RichObject>& obj) const;
|
||||
|
|
|
|||
|
|
@ -4,28 +4,12 @@ namespace Upp {
|
|||
|
||||
#define IMAGECLASS RichTextImg
|
||||
#define IMAGEFILE <RichText/RichText.iml>
|
||||
#include <Draw/iml.h>
|
||||
#include <Draw/iml_source.h>
|
||||
|
||||
RichPara::Lines RichPara::Begin(const Rect& page, PageY& py) const
|
||||
RichPara::Lines RichPara::Begin(RichContext& rc) const
|
||||
{
|
||||
Lines pl = FormatLines(page.Width());
|
||||
#if 0 // pagination logic moved to RichTxt
|
||||
int cy = format.ruler + format.before;
|
||||
if(format.keep || format.keepnext)
|
||||
cy += pl.BodyHeight();
|
||||
else
|
||||
cy += pl[0].Sum();
|
||||
int after = format.after;
|
||||
if(!format.keepnext)
|
||||
nbefore = nline = after = 0;
|
||||
if(page.Height() < 32000 &&
|
||||
(format.newpage || py.y + cy + after + nbefore + nline > page.bottom && cy < page.Height() ||
|
||||
format.header_qtf.GetCount() + format.footer_qtf.GetCount()/* && rc.level == 0*/)) {
|
||||
py.page++;
|
||||
py.y = page.top;
|
||||
}
|
||||
#endif
|
||||
py.y += format.before + format.ruler;
|
||||
Lines pl = FormatLines(rc.page.Width());
|
||||
rc.py.y += format.before + format.ruler;
|
||||
pl.Justify(format);
|
||||
return pl;
|
||||
}
|
||||
|
|
@ -122,14 +106,14 @@ void RichPara::Flush(Draw& draw, const PaintInfo& pi, wchar *text,
|
|||
}
|
||||
}
|
||||
|
||||
bool RichPara::BreaksPage(PageY py, const Lines& pl, int i, const Rect& page) const
|
||||
bool RichPara::BreaksPage(const RichContext& rc, const Lines& pl, int i) const
|
||||
{
|
||||
int linecy = pl[i].Sum();
|
||||
if(linecy >= page.Height()) return false;
|
||||
if(linecy + py.y > page.bottom)
|
||||
if(linecy >= rc.page.Height()) return false;
|
||||
if(linecy + rc.py.y > rc.page.bottom)
|
||||
return true;
|
||||
if(format.orphan || pl.GetCount() < 2) return false;
|
||||
if((i == 0 || i == pl.GetCount() - 2) && py.y + linecy + pl[i + 1].Sum() > page.bottom)
|
||||
if((i == 0 || i == pl.GetCount() - 2) && rc.py.y + linecy + pl[i + 1].Sum() > rc.page.bottom)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -157,11 +141,6 @@ String RichObjectImageMaker::Key() const
|
|||
Image RichObjectImageMaker::Make() const
|
||||
{
|
||||
return object.ToImage(sz, context);
|
||||
/* ImageDraw iw(sz);
|
||||
iw.DrawRect(sz, SColorPaper());
|
||||
object.Paint(iw, sz, context);
|
||||
return iw;
|
||||
*/
|
||||
}
|
||||
|
||||
void RichPara::DrawRuler(Draw& w, int x, int y, int cx, int cy, Color ink, int style)
|
||||
|
|
@ -183,67 +162,69 @@ void RichPara::DrawRuler(Draw& w, int x, int y, int cx, int cy, Color ink, int s
|
|||
}
|
||||
}
|
||||
|
||||
void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo& pi,
|
||||
void RichPara::Paint(PageDraw& pw, RichContext rc, const PaintInfo& pi,
|
||||
const Number& n, const Bits& spellerror, bool baselevel) const
|
||||
{
|
||||
Zoom z = pi.zoom;
|
||||
PageY opy = py;
|
||||
Lines pl = Begin(page, py);
|
||||
PageY opy = rc.py;
|
||||
Lines pl = Begin(rc);
|
||||
if(pw.tracer) {
|
||||
PageY h = py;
|
||||
PageY h = rc.py;
|
||||
h.y -= format.before + format.ruler;
|
||||
pw.tracer->Paragraph(page, h, *this);
|
||||
pw.tracer->Paragraph(rc.page, h, *this);
|
||||
}
|
||||
|
||||
bool highlight = pi.highlightpara >= 0 && pi.highlightpara < pl.len;
|
||||
int hy = py.y - format.before - format.ruler;
|
||||
int phy = py.page;
|
||||
if(format.ruler && hy >= 0 && hy + format.ruler < page.bottom)
|
||||
DrawRuler(pw.Page(phy), z * page.left + z * format.lm, z * hy,
|
||||
z * page.right - z * page.left - z * format.rm - z * format.lm,
|
||||
int hy = rc.py.y - format.before - format.ruler;
|
||||
int phy = rc.py.page;
|
||||
if(format.ruler && hy >= 0 && hy + format.ruler < rc.page.bottom)
|
||||
DrawRuler(pw.Page(phy), z * rc.page.left + z * format.lm, z * hy,
|
||||
z * rc.page.right - z * rc.page.left - z * format.rm - z * format.lm,
|
||||
max(1, z * format.ruler), format.rulerink, format.rulerstyle);
|
||||
if(pi.sell < 0 && pi.selh > 0)
|
||||
for(int p = opy.page; p <= py.page; p++) {
|
||||
int top = z * (p == opy.page ? opy.y : page.top);
|
||||
int bottom = z * (p == py.page ? py.y : page.bottom);
|
||||
pw.Page(p).DrawRect(z * page.left, top, z * page.right - z * page.left,
|
||||
for(int p = opy.page; p <= rc.py.page; p++) {
|
||||
int top = z * (p == opy.page ? opy.y : rc.page.top);
|
||||
int bottom = z * (p == rc.py.page ? rc.py.y : rc.page.bottom);
|
||||
pw.Page(p).DrawRect(z * rc.page.left, top, z * rc.page.right - z * rc.page.left,
|
||||
bottom - top, InvertColor);
|
||||
}
|
||||
opy = py;
|
||||
opy = rc.py;
|
||||
int oi = 0;
|
||||
int x = 0;
|
||||
int y0 = 0;
|
||||
int lineascent = 0;
|
||||
PageY mpy;
|
||||
int mla = Null;
|
||||
for(int lni = 0; lni < pl.GetCount(); lni++) {
|
||||
const Line& li = pl[lni];
|
||||
int linecy = li.Sum();
|
||||
lineascent = li.ascent;
|
||||
if(BreaksPage(py, pl, lni, page)) {
|
||||
if(BreaksPage(rc, pl, lni)) {
|
||||
if(li.ppos > pi.sell && li.ppos < pi.selh) {
|
||||
int y = z * py.y;
|
||||
pw.Page(py.page).DrawRect(z * page.left, y, z * page.right - z * page.left,
|
||||
z * page.bottom - y, InvertColor);
|
||||
int y = z * rc.py.y;
|
||||
pw.Page(rc.py.page).DrawRect(z * rc.page.left, y, z * rc.page.right - z * rc.page.left,
|
||||
z * rc.page.bottom - y, InvertColor);
|
||||
}
|
||||
py.y = page.top;
|
||||
py.page++;
|
||||
rc.Page();
|
||||
}
|
||||
if(py > pi.bottom)
|
||||
if(rc.py > pi.bottom)
|
||||
break;
|
||||
|
||||
if(lni == 0 && format.label.GetCount() && !IsNull(pi.showcodes) && pi.showlabels)
|
||||
pw.Page(py.page).DrawImage(z * page.left - 12, z * (py.y + (lineascent - 7) / 2),
|
||||
RichTextImg::Label(), pi.showcodes);
|
||||
if(lni == 0) {
|
||||
mpy = rc.py;
|
||||
mla = lineascent;
|
||||
}
|
||||
const CharFormat **cf = pl.format + li.pos;
|
||||
const CharFormat **i = cf;
|
||||
const CharFormat **ilim = i + li.len;
|
||||
const HeightInfo *hg = pl.height + li.pos;
|
||||
if(py + linecy >= pi.top) {
|
||||
Draw& draw = pw.Page(py.page);
|
||||
if(rc.py + linecy >= pi.top) {
|
||||
Draw& draw = pw.Page(rc.py.page);
|
||||
#ifdef _DEBUG
|
||||
int cloff = draw.GetCloffLevel();
|
||||
#endif
|
||||
Buffer<int> wd(li.len);
|
||||
int x0 = li.xpos + page.left;
|
||||
int x0 = li.xpos + rc.page.left;
|
||||
x = x0;
|
||||
int *w = pl.width + li.pos;
|
||||
int *wl = w + li.len;
|
||||
|
|
@ -255,17 +236,17 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
}
|
||||
|
||||
if(highlight)
|
||||
draw.DrawRect(z * page.left, z * py.y, z * page.Width(),
|
||||
z * (py.y + linecy) - z * py.y,
|
||||
draw.DrawRect(z * rc.page.left, z * rc.py.y, z * rc.page.Width(),
|
||||
z * (rc.py.y + linecy) - z * rc.py.y,
|
||||
pi.highlight);
|
||||
|
||||
const CharFormat **i0 = i;
|
||||
wchar *text = pl.text + li.pos;
|
||||
x = x0;
|
||||
w = pl.width + li.pos;
|
||||
y0 = py.y + li.ascent;
|
||||
y0 = rc.py.y + li.ascent;
|
||||
int pp = li.pos;
|
||||
int l = page.right;
|
||||
int l = rc.page.right;
|
||||
int h = -1;
|
||||
|
||||
while(i < ilim) {
|
||||
|
|
@ -275,7 +256,7 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
h = x;
|
||||
pp++;
|
||||
if(*i0 != *i || hg->object) {
|
||||
Flush(draw, pi, text, i0, wd, (int)(i0 - cf),(int)( i - i0), x0, x, y0, py.y, linecy,
|
||||
Flush(draw, pi, text, i0, wd, (int)(i0 - cf), (int)(i - i0), x0, x, y0, rc.py.y, linecy,
|
||||
lineascent, z, highlight);
|
||||
i0 = i;
|
||||
x0 = x;
|
||||
|
|
@ -285,9 +266,9 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
if(o) {
|
||||
Size sz = z * o.GetSize();
|
||||
int ix = z * x;
|
||||
if(pi.shrink_oversized_objects && sz.cx + ix > page.right)
|
||||
sz.cx = page.right - ix;
|
||||
draw.DrawRect(ix, z * py.y, sz.cx, z * linecy, (*i)->paper);
|
||||
if(pi.shrink_oversized_objects && sz.cx + ix > rc.page.right)
|
||||
sz.cx = rc.page.right - ix;
|
||||
draw.DrawRect(ix, z * rc.py.y, sz.cx, z * linecy, (*i)->paper);
|
||||
draw.Clipoff(ix, z * (y0 - hg->ascent), sz.cx, sz.cy);
|
||||
if(pi.sizetracking)
|
||||
draw.DrawRect(sz, SColorFace);
|
||||
|
|
@ -316,13 +297,13 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
}
|
||||
}
|
||||
if(i > i0)
|
||||
Flush(draw, pi, text, i0, wd, (int)(i0 - cf), (int)(i - i0), x0, x, y0, py.y, linecy,
|
||||
Flush(draw, pi, text, i0, wd, (int)(i0 - cf), (int)(i - i0), x0, x, y0, rc.py.y, linecy,
|
||||
lineascent, z, highlight);
|
||||
if(lni == 0) {
|
||||
Rect r;
|
||||
r.left = page.left + format.lm;
|
||||
r.left = rc.page.left + format.lm;
|
||||
int q = li.ascent / 2;
|
||||
r.top = py.y + 4 * (li.ascent - q) / 5;
|
||||
r.top = rc.py.y + 4 * (li.ascent - q) / 5;
|
||||
r.right = r.left + q;
|
||||
r.bottom = r.top + q;
|
||||
q = z * (r.Width() / 4);
|
||||
|
|
@ -360,11 +341,11 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
}
|
||||
int zlcy = z * linecy;
|
||||
if(pi.spellingchecker && zlcy > 3) {
|
||||
int x = z * (li.xpos + page.left);
|
||||
int x = z * (li.xpos + rc.page.left);
|
||||
w = wd;
|
||||
wl = w + li.len;
|
||||
int i = li.pos;
|
||||
int q = z * (py.y + linecy);
|
||||
int q = z * (rc.py.y + linecy);
|
||||
while(w < wl) {
|
||||
if(spellerror[pl.pos[i++]]) {
|
||||
if(zlcy > 16)
|
||||
|
|
@ -380,12 +361,12 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
if(pi.sell == li.ppos + li.plen)
|
||||
l = x;
|
||||
if(pi.sell < li.ppos)
|
||||
l = page.left;
|
||||
l = rc.page.left;
|
||||
if(pi.selh > li.ppos + li.plen)
|
||||
h = page.right;
|
||||
h = rc.page.right;
|
||||
if(pi.sell < pi.selh && pi.selh > li.ppos)
|
||||
draw.DrawRect(z * l, z * py.y, z * h - z * l,
|
||||
z * (py.y + linecy) - z * py.y, InvertColor);
|
||||
draw.DrawRect(z * l, z * rc.py.y, z * h - z * l,
|
||||
z * (rc.py.y + linecy) - z * rc.py.y, InvertColor);
|
||||
ASSERT(draw.GetCloffLevel() == cloff);
|
||||
}
|
||||
else
|
||||
|
|
@ -395,28 +376,42 @@ void RichPara::Paint(PageDraw& pw, const Rect& page, PageY py, const PaintInfo&
|
|||
i++;
|
||||
hg++;
|
||||
}
|
||||
py.y += linecy;
|
||||
rc.py.y += linecy;
|
||||
}
|
||||
Size sz = RichTextImg::EndParaChar().GetSize();
|
||||
if(sz.cy < z * lineascent && !IsNull(pi.showcodes))
|
||||
pw.Page(py.page).DrawImage(z * x, z * y0 - sz.cy,
|
||||
RichTextImg::EndParaChar(),
|
||||
format.indexentry.GetCount() ? pi.indexentry : pi.showcodes);
|
||||
if((format.newpage || format.newhdrftr && baselevel) && !IsNull(pi.showcodes)) {
|
||||
pw.Page(rc.py.page).DrawImage(z * x, z * y0 - sz.cy,
|
||||
RichTextImg::EndParaChar(),
|
||||
format.indexentry.GetCount() ? pi.indexentry : pi.showcodes);
|
||||
if(format.newpage && !IsNull(pi.showcodes)) {
|
||||
Draw& w = pw.Page(opy.page);
|
||||
int wd = z * page.right - z * page.left;
|
||||
int wd = z * rc.page.right - z * rc.page.left;
|
||||
int step = w.Pixels() ? 8 : 50;
|
||||
int y = z * opy.y;
|
||||
for(int x = 0; x < wd; x += step)
|
||||
w.DrawRect(z * page.left + x, y, step >> 1, step >> 3, pi.showcodes);
|
||||
w.DrawRect(z * rc.page.left + x, y, step >> 1, step >> 3, pi.showcodes);
|
||||
}
|
||||
if(pl.len >= pi.sell && pl.len < pi.selh && py < pi.bottom) {
|
||||
int top = z * py.y;
|
||||
pw.Page(py.page).DrawRect(z * page.left, top, z * page.right - z * page.left,
|
||||
z * min(py.y + format.after, page.bottom) - top, InvertColor);
|
||||
if(pl.len >= pi.sell && pl.len < pi.selh && rc.py < pi.bottom) {
|
||||
int top = z * rc.py.y;
|
||||
pw.Page(rc.py.page).DrawRect(z * rc.page.left, top, z * rc.page.right - z * rc.page.left,
|
||||
z * min(rc.py.y + format.after, rc.page.bottom) - top, InvertColor);
|
||||
}
|
||||
if(!IsNull(mla) && !IsNull(pi.showcodes) && pi.showlabels) {
|
||||
bool b = format.label.GetCount();
|
||||
Image img = RichTextImg::Label();
|
||||
for(int pass = 0;;pass++) {
|
||||
Size isz = img.GetSize();
|
||||
if(b)
|
||||
pw.Page(mpy.page).DrawImage(-7 - isz.cx, z * mpy.y + (z * mla - isz.cy) / 2,
|
||||
img, pi.showcodes);
|
||||
if(pass)
|
||||
break;
|
||||
b = format.newhdrftr && baselevel;
|
||||
img = RichTextImg::HdrFtr();
|
||||
}
|
||||
}
|
||||
if(pw.tracer)
|
||||
pw.tracer->EndParagraph(py);
|
||||
pw.tracer->EndParagraph(rc.py);
|
||||
}
|
||||
|
||||
void RichPara::GetRichPos(RichPos& rp, int pos) const
|
||||
|
|
@ -445,9 +440,9 @@ void RichPara::GetRichPos(RichPos& rp, int pos) const
|
|||
rp.chr = '\n';
|
||||
}
|
||||
|
||||
RichCaret RichPara::GetCaret(int pos, const Rect& page, PageY py) const
|
||||
RichCaret RichPara::GetCaret(int pos, RichContext rc) const
|
||||
{
|
||||
Lines pl = Begin(page, py);
|
||||
Lines pl = Begin(rc);
|
||||
RichCaret pr;
|
||||
FontInfo fi = format.Info();
|
||||
pr.caretascent = fi.GetAscent();
|
||||
|
|
@ -455,13 +450,11 @@ RichCaret RichPara::GetCaret(int pos, const Rect& page, PageY py) const
|
|||
for(int lni = 0; lni < pl.GetCount(); lni++) {
|
||||
Line& li = pl[lni];
|
||||
int linecy = li.Sum();
|
||||
if(BreaksPage(py, pl, lni, page)) {
|
||||
py.y = page.top;
|
||||
py.page++;
|
||||
}
|
||||
pr.page = py.page;
|
||||
pr.top = py.y;
|
||||
pr.bottom = py.y + linecy;
|
||||
if(BreaksPage(rc, pl, lni))
|
||||
rc.Page();
|
||||
pr.page = rc.py.page;
|
||||
pr.top = rc.py.y;
|
||||
pr.bottom = rc.py.y + linecy;
|
||||
pr.lineascent = li.ascent;
|
||||
pr.line = lni;
|
||||
if(pos < li.ppos + li.plen) {
|
||||
|
|
@ -469,7 +462,7 @@ RichCaret RichPara::GetCaret(int pos, const Rect& page, PageY py) const
|
|||
int *p = pl.pos + li.pos;
|
||||
const CharFormat **i = pl.format + li.pos;
|
||||
const HeightInfo *h = pl.height + li.pos;
|
||||
int x = li.xpos + page.left;
|
||||
int x = li.xpos + rc.page.left;
|
||||
if(li.len && *i) {
|
||||
pr.caretascent = h->ascent;
|
||||
pr.caretdescent = h->descent;
|
||||
|
|
@ -491,11 +484,11 @@ RichCaret RichPara::GetCaret(int pos, const Rect& page, PageY py) const
|
|||
pr.caretdescent = min(pr.caretdescent, pr.Height() - pr.lineascent);
|
||||
return pr;
|
||||
}
|
||||
py.y += linecy;
|
||||
rc.py.y += linecy;
|
||||
}
|
||||
const Line& li = pl.line.Top();
|
||||
pr.left = li.cx + li.xpos + page.left;
|
||||
pr.right = page.right;
|
||||
pr.left = li.cx + li.xpos + rc.page.left;
|
||||
pr.right = rc.page.right;
|
||||
pr.caretdescent = min(pr.caretdescent, pr.Height() - pr.lineascent);
|
||||
return pr;
|
||||
}
|
||||
|
|
@ -514,20 +507,18 @@ int RichPara::PosInLine(int x, const Rect& page, const Lines& pl, int lni) const
|
|||
return pos < pl.clen ? pl.pos[pos] : pl.len;
|
||||
}
|
||||
|
||||
int RichPara::GetPos(int x, PageY y, const Rect& page, PageY py) const
|
||||
int RichPara::GetPos(int x, PageY y, RichContext rc) const
|
||||
{
|
||||
Lines pl = Begin(page, py);
|
||||
Lines pl = Begin(rc);
|
||||
if(pl.len)
|
||||
for(int lni = 0; lni < pl.GetCount(); lni++) {
|
||||
const Line& li = pl[lni];
|
||||
int linecy = li.Sum();
|
||||
if(BreaksPage(py, pl, lni, page)) {
|
||||
py.y = page.top;
|
||||
py.page++;
|
||||
}
|
||||
py.y += linecy;
|
||||
if(y < py || lni == pl.GetCount() - 1)
|
||||
return PosInLine(x, page, pl, lni);
|
||||
if(BreaksPage(rc, pl, lni))
|
||||
rc.Page();
|
||||
rc.py.y += linecy;
|
||||
if(y < rc.py || lni == pl.GetCount() - 1)
|
||||
return PosInLine(x, rc.page, pl, lni);
|
||||
}
|
||||
return pl.len;
|
||||
}
|
||||
|
|
@ -551,35 +542,31 @@ int RichPara::GetVertMove(int pos, int gx, const Rect& page, int dir) const
|
|||
return PosInLine(gx, page, pl, lni);
|
||||
}
|
||||
|
||||
void RichPara::GatherLabels(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const
|
||||
void RichPara::GatherLabels(Vector<RichValPos>& info, RichContext rc, int pos) const
|
||||
{
|
||||
Lines pl = Begin(page, py);
|
||||
Lines pl = Begin(rc);
|
||||
WString ie;
|
||||
if(!pl.GetCount())
|
||||
return;
|
||||
if(BreaksPage(py, pl, 0, page)) {
|
||||
py.y = page.top;
|
||||
py.page++;
|
||||
}
|
||||
if(BreaksPage(rc, pl, 0))
|
||||
rc.Page();
|
||||
if(format.label.IsEmpty())
|
||||
return;
|
||||
RichValPos& f = info.Add();
|
||||
f.py = py;
|
||||
f.py = rc.py;
|
||||
f.pos = pos;
|
||||
f.data = format.label.ToWString();
|
||||
}
|
||||
|
||||
void RichPara::GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY py, int pos) const
|
||||
void RichPara::GatherIndexes(Vector<RichValPos>& info, RichContext rc, int pos) const
|
||||
{
|
||||
Lines pl = Begin(page, py);
|
||||
Lines pl = Begin(rc);
|
||||
WString ie;
|
||||
for(int lni = 0; lni < pl.GetCount(); lni++) {
|
||||
Line& li = pl[lni];
|
||||
int linecy = li.Sum();
|
||||
if(BreaksPage(py, pl, lni, page)) {
|
||||
py.y = page.top;
|
||||
py.page++;
|
||||
}
|
||||
if(BreaksPage(rc, pl, lni))
|
||||
rc.Page();
|
||||
const CharFormat **i0 = pl.format + li.pos;
|
||||
const CharFormat **i = i0;
|
||||
const CharFormat **ilim = i + li.len;
|
||||
|
|
@ -588,14 +575,14 @@ void RichPara::GatherIndexes(Vector<RichValPos>& info, const Rect& page, PageY
|
|||
ie = (*i)->indexentry;
|
||||
if(!ie.IsEmpty()) {
|
||||
RichValPos& f = info.Add();
|
||||
f.py = py;
|
||||
f.py = rc.py;
|
||||
f.pos = (int)(i - i0) + pos;
|
||||
f.data = ie;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
py.y += linecy;
|
||||
rc.py.y += linecy;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
#define IMAGECLASS RichTextImg
|
||||
#define IMAGEFILE <RichText/RichText.iml>
|
||||
#include <Draw/iml_header.h>
|
||||
|
||||
INITIALIZE(RichImage)
|
||||
|
||||
class PasteClip;
|
||||
|
|
@ -288,6 +292,28 @@ struct PaintInfo {
|
|||
int LineZoom(Zoom z, int a);
|
||||
|
||||
class RichTable;
|
||||
class RichText;
|
||||
struct RichStyle;
|
||||
|
||||
typedef ArrayMap<Uuid, RichStyle> RichStyles;
|
||||
|
||||
struct RichContext {
|
||||
const RichText *text;
|
||||
const RichStyles *styles;
|
||||
RichText *header, *footer;
|
||||
int header_cy, footer_cy; // next page header/footer size
|
||||
int current_header_cy, current_footer_cy; // current header/footer size
|
||||
Rect page;
|
||||
PageY py;
|
||||
|
||||
void HeaderFooter(RichText *header, RichText *footer_qtf);
|
||||
void AdjustPage();
|
||||
void Page();
|
||||
void Set(PageY p0, const Rect& first_page, const Rect& next_page, PageY p);
|
||||
|
||||
RichContext(const RichStyles& styles, const RichText *text);
|
||||
RichContext() {}
|
||||
};
|
||||
|
||||
#include "Para.h"
|
||||
|
||||
|
|
@ -357,28 +383,11 @@ struct RichStyle {
|
|||
RichStyle() { next = GetDefaultId(); }
|
||||
};
|
||||
|
||||
typedef ArrayMap<Uuid, RichStyle> RichStyles;
|
||||
|
||||
const RichStyle& GetStyle(const RichStyles& s, const Uuid& id);
|
||||
int FindStyleWithName(const RichStyles& style, const String& name);
|
||||
|
||||
class RichText;
|
||||
|
||||
struct RichContext {
|
||||
const RichText *text;
|
||||
const RichStyles *styles;
|
||||
RichText *header, *footer;
|
||||
int header_cy, footer_cy;
|
||||
Rect page;
|
||||
PageY py;
|
||||
|
||||
void NewHeaderFooter(RichText *header, RichText *footer_qtf);
|
||||
void Page() { py.page++; py.y = page.top; }
|
||||
|
||||
RichContext(const RichStyles& styles, const RichText *text) : text(text), styles(&styles) { header_cy = footer_cy = 0; }
|
||||
RichContext() {}
|
||||
};
|
||||
|
||||
struct RichCellPos;
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
PREMULTIPLIED
|
||||
IMAGE_ID(Label)
|
||||
IMAGE_ID(HdrFtr)
|
||||
IMAGE_ID(EndParaChar)
|
||||
IMAGE_ID(TabChar)
|
||||
IMAGE_ID(SpaceChar)
|
||||
IMAGE_ID(HardSpaceChar)
|
||||
|
||||
IMAGE_BEGIN_DATA
|
||||
IMAGE_DATA(120,156,149,80,81,10,192,80,8,146,177,183,237,86,221,255,84,173,159,199,42,172,152,208,71,34,42,98,225,134,131,218)
|
||||
IMAGE_DATA(9,34,148,240,74,120,77,55,233,178,95,204,93,120,208,64,127,114,146,74,237,159,21,205,165,189,110,67,2,119,89,221)
|
||||
IMAGE_DATA(166,104,94,212,7,250,0,182,32,211,115,255,195,106,52,65,204,244,195,57,207,93,25,85,255,28,90,224,5,200,43,63)
|
||||
IMAGE_DATA(111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
|
||||
IMAGE_END_DATA(128, 5)
|
||||
IMAGE_DATA(120,156,189,82,91,10,192,48,8,11,99,237,118,43,239,127,42,231,79,153,74,172,251,90,32,148,6,73,210,7,6,46)
|
||||
IMAGE_DATA(56,168,81,16,161,68,87,162,107,98,55,151,253,98,238,196,205,74,48,130,172,127,128,101,115,142,120,152,202,232,171,38)
|
||||
IMAGE_DATA(41,116,237,187,34,121,110,65,130,54,173,238,166,104,254,30,62,208,7,176,87,98,243,220,255,176,26,155,32,102,250,226)
|
||||
IMAGE_DATA(236,175,187,50,170,246,125,104,129,7,42,71,81,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
|
||||
IMAGE_END_DATA(128, 6)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ private:
|
|||
PageY GetTop(RichContext rc) const;
|
||||
PageY GetHeight(RichContext rc) const;
|
||||
void Paint(PageDraw& pw, RichContext rc, PageY npy,
|
||||
const Rect& xpg, int y, int ny, const PaintInfo& pi,
|
||||
const Rect& xpg, const Rect& nxpg,
|
||||
int y, int ny, const PaintInfo& pi,
|
||||
bool select) const;
|
||||
RichCaret GetCaret(int pos, RichContext rc, PageY pyy) const;
|
||||
int GetPos(int x, PageY y, RichContext rc, PageY pyy) const;
|
||||
|
|
@ -78,28 +79,30 @@ private:
|
|||
mutable One<RichText> header, footer;
|
||||
|
||||
struct PaintCell : Moveable<PaintCell> {
|
||||
int left;
|
||||
int right;
|
||||
Rect page;
|
||||
PageY hy;
|
||||
bool top;
|
||||
bool bottom;
|
||||
int left; // left pos with grid
|
||||
int right; // right pos with grid
|
||||
int page_left; // left pos without grid (if any)
|
||||
int page_right; // right pos without grid (if any)
|
||||
PageY hy; // end of cell
|
||||
bool top; // this is top cell of vspan (or single cell without vspan)
|
||||
bool bottom; // this is bottom cell of vspan (or single cell without vspan)
|
||||
|
||||
RichContext MakeRichContext(RichContext rc) const;
|
||||
|
||||
PaintCell() { top = true; }
|
||||
};
|
||||
|
||||
struct PaintRow : Moveable<PaintRow> {
|
||||
PageY gpy;
|
||||
PageY py, pyy;
|
||||
PageY gpy; // position of grid line (if not first)
|
||||
PageY py, pyy; //start, end of line
|
||||
Buffer<PaintCell> cell;
|
||||
bool first;
|
||||
bool first; // first row on the page
|
||||
|
||||
PaintCell& operator[](int i) { return cell[i]; }
|
||||
const PaintCell& operator[](int i) const { return cell[i]; }
|
||||
};
|
||||
|
||||
struct Layout {
|
||||
Buffer<Rect> col;
|
||||
Buffer<PaintRow> row;
|
||||
int frame;
|
||||
int grid;
|
||||
|
|
@ -112,32 +115,36 @@ private:
|
|||
struct TabLayout : Layout {
|
||||
bool hasheader;
|
||||
Layout header;
|
||||
Rect page;
|
||||
int page0;
|
||||
Size sz;
|
||||
PageY py;
|
||||
Rect first_page0;
|
||||
Rect next_page0;
|
||||
Rect first_page;
|
||||
Rect next_page;
|
||||
Rect header_page;
|
||||
|
||||
rval_default(TabLayout);
|
||||
TabLayout() {}
|
||||
};
|
||||
|
||||
mutable TabLayout clayout; // TODO: MT?
|
||||
mutable Rect cpage;
|
||||
mutable PageY cpy;
|
||||
mutable TabLayout clayout;
|
||||
|
||||
Buffer< Buffer<CellInfo> > ci;
|
||||
int r_row, r_column; // r_ - refresh info
|
||||
Rect r_page;
|
||||
Rect r_first_page, r_next_page, r_header_page;
|
||||
PageY r_py, r_pyy;
|
||||
|
||||
void Invalidate();
|
||||
void InvalidateRefresh(int i, int j);
|
||||
void InvalidateRefresh(Point p) { InvalidateRefresh(p.y, p.x); }
|
||||
|
||||
bool Reduce(RichContext& rc) const;
|
||||
Layout Realize(RichContext rc, int ny) const;
|
||||
bool RowPaint(PageDraw& pw, const RichStyles& st, const Layout& tab,
|
||||
int i, int ny, const Rect& pg, VectorMap<int, Rect>& frr,
|
||||
PaintInfo& pi, int pd, bool sel) const;
|
||||
bool Reduce(Rect& r) const;
|
||||
Rect GetPageRect(PageY py) const;
|
||||
void NextPage(PageY& py, bool header = false) const;
|
||||
RichContext MakeRichContext(RichContext rc, PageY py, bool header = false) const;
|
||||
Layout Realize(PageY py, RichContext arc, int ny, bool header) const;
|
||||
bool RowPaint(PageDraw& pw, RichContext rc, const Layout& tab, bool header,
|
||||
int i, int ny, Rect pg, Rect npg, VectorMap<int, Rect>& frr,
|
||||
PaintInfo& pi, int pd, bool sel) const;
|
||||
|
||||
const TabLayout& Realize(RichContext rc) const;
|
||||
|
||||
|
|
@ -185,7 +192,7 @@ private:
|
|||
|
||||
PageY GetHeight(RichContext rc) const;
|
||||
PageY GetTop(RichContext rc) const;
|
||||
void Paint(PageDraw& pw, RichContext rc, const PaintInfo& pi) const;
|
||||
void Paint(PageDraw& pw, RichContext rc, const PaintInfo& pi, bool baselevel) const;
|
||||
RichCaret GetCaret(int pos, RichContext rc) const;
|
||||
int GetPos(int x, PageY y, RichContext rc) const;
|
||||
int GetVertMove(int pos, int gx, RichContext rc, int dir) const;
|
||||
|
|
|
|||
|
|
@ -48,9 +48,11 @@ bool RichCell::Reduce(RichContext& rc) const
|
|||
rc.page.bottom -= format.margin.bottom + format.border.bottom;
|
||||
rc.page.left += format.margin.left + format.border.left;
|
||||
rc.page.right -= format.margin.right + format.border.right;
|
||||
if(rc.page.IsEmpty())
|
||||
if(rc.page.IsEmpty()) {
|
||||
rc.page = br;
|
||||
return !rc.page.IsEmpty();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PageY RichCell::GetTop(RichContext rc) const
|
||||
|
|
@ -168,7 +170,8 @@ PageY RichCell::Align(const RichContext& rc, PageY npy) const
|
|||
}
|
||||
|
||||
void RichCell::Paint(PageDraw& pw, RichContext rc, PageY npy,
|
||||
const Rect& xpg, int y, int ny, const PaintInfo& pi, bool select) const
|
||||
const Rect& xpg, const Rect& nxpg,
|
||||
int y, int ny, const PaintInfo& pi, bool select) const
|
||||
{
|
||||
if(!Reduce(rc))
|
||||
return;
|
||||
|
|
@ -181,8 +184,8 @@ void RichCell::Paint(PageDraw& pw, RichContext rc, PageY npy,
|
|||
else {
|
||||
DrawCell(pw.Page(rc.py.page), xpg.left, xpg.right, y, xpg.bottom, border, margin);
|
||||
for(int i = rc.py.page + 1; i < npy.page; i++)
|
||||
DrawCell(pw.Page(i), xpg.left, xpg.right, xpg.top, xpg.bottom, border, margin);
|
||||
DrawCell(pw.Page(npy.page), xpg.left, xpg.right, xpg.top, ny, border, margin);
|
||||
DrawCell(pw.Page(i), nxpg.left, nxpg.right, nxpg.top, nxpg.bottom, border, margin);
|
||||
DrawCell(pw.Page(npy.page), nxpg.left, nxpg.right, nxpg.top, ny, border, margin);
|
||||
}
|
||||
|
||||
rc.py = Align(rc, npy);
|
||||
|
|
@ -195,8 +198,8 @@ void RichCell::Paint(PageDraw& pw, RichContext rc, PageY npy,
|
|||
else {
|
||||
pw.Page(rc.py.page).DrawRect(xpg.left, y, cx, xpg.bottom - y, InvertColor);
|
||||
for(int i = rc.py.page + 1; i < npy.page; i++)
|
||||
pw.Page(i).DrawRect(xpg.left, xpg.top, cx, xpg.Height(), InvertColor);
|
||||
pw.Page(npy.page).DrawRect(xpg.left, xpg.top, cx, ny - xpg.top, InvertColor);
|
||||
pw.Page(i).DrawRect(nxpg.left, nxpg.top, cx, nxpg.Height(), InvertColor);
|
||||
pw.Page(npy.page).DrawRect(nxpg.left, nxpg.top, cx, ny - nxpg.top, InvertColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -209,7 +212,7 @@ RichCaret RichCell::GetCaret(int pos, RichContext rc, PageY pyy) const
|
|||
return text.GetCaret(pos, rc);
|
||||
}
|
||||
|
||||
int RichCell::GetPos(int x, PageY y, RichContext rc, PageY pyy) const
|
||||
int RichCell::GetPos(int x, PageY y, RichContext rc, PageY pyy) const
|
||||
{
|
||||
if(!Reduce(rc))
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace Upp {
|
|||
|
||||
void RichTable::Invalidate()
|
||||
{
|
||||
cpy.page = -1;
|
||||
clayout.py.page = -1;
|
||||
length = tabcount = -1;
|
||||
}
|
||||
|
||||
|
|
@ -17,9 +17,10 @@ void RichTable::InvalidateRefresh(int i, int j)
|
|||
if(r_row == -2 && clayout.sz == GetSize()) {
|
||||
r_row = i;
|
||||
r_column = j;
|
||||
r_py = cpy;
|
||||
r_py = clayout.py;
|
||||
r_pyy = clayout[min(GetRows() - 1, i + cell[i][j].vspan)].pyy;
|
||||
r_page = cpage;
|
||||
r_first_page = clayout.first_page0;
|
||||
r_next_page = clayout.next_page0;
|
||||
}
|
||||
else
|
||||
r_row = -1;
|
||||
|
|
@ -27,6 +28,24 @@ void RichTable::InvalidateRefresh(int i, int j)
|
|||
Invalidate();
|
||||
}
|
||||
|
||||
int RichTable::GetInvalid(PageY& top, PageY& bottom, RichContext rc) const
|
||||
{
|
||||
if(r_row == -2)
|
||||
return -1;
|
||||
const TabLayout& tab = Realize(rc);
|
||||
RichContext rc2 = rc;
|
||||
rc2.Page();
|
||||
if(r_row >= 0 && r_first_page == rc.page && r_next_page == rc2.page
|
||||
&& r_py == rc.py && tab[min(GetRows() - 1, r_row + cell[r_row][r_column].vspan)].pyy == r_pyy) {
|
||||
const PaintRow& pr = tab[r_row];
|
||||
const RichCell& cl = cell[r_row][r_column];
|
||||
top = pr.py;
|
||||
bottom = tab[min(cell.GetCount() - 1, r_row + cl.vspan)].pyy;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void RichTable::Normalize0()
|
||||
{
|
||||
int nx = format.column.GetCount();
|
||||
|
|
@ -245,22 +264,6 @@ void RichTable::Validate()
|
|||
r_row = -2;
|
||||
}
|
||||
|
||||
int RichTable::GetInvalid(PageY& top, PageY& bottom, RichContext rc) const
|
||||
{
|
||||
if(r_row == -2)
|
||||
return -1;
|
||||
const TabLayout& tab = Realize(rc);
|
||||
if(r_row >= 0 && r_page == rc.page
|
||||
&& r_py == rc.py && tab[min(GetRows() - 1, r_row + cell[r_row][r_column].vspan)].pyy == r_pyy) {
|
||||
const PaintRow& pr = tab[r_row];
|
||||
const RichCell& cl = cell[r_row][r_column];
|
||||
top = pr.py;
|
||||
bottom = tab[min(cell.GetCount() - 1, r_row + cl.vspan)].pyy;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void RichTable::AddColumn(int cx)
|
||||
{
|
||||
format.column.Add(cx);
|
||||
|
|
@ -583,7 +586,7 @@ RichTable::RichTable(const RichTable& src, int)
|
|||
|
||||
RichTable::RichTable()
|
||||
{
|
||||
cpy.page = -1;
|
||||
clayout.py.page = -1;
|
||||
r_row = -1;
|
||||
Invalidate();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,105 +2,135 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
bool RichTable::Reduce(RichContext& rc) const
|
||||
bool RichTable::Reduce(Rect& r) const
|
||||
{
|
||||
Rect br = rc.page;
|
||||
rc.page.left += format.lm;
|
||||
rc.page.right -= format.rm;
|
||||
rc.page.Deflate(format.frame);
|
||||
if(rc.page.IsEmpty())
|
||||
rc.page = br;
|
||||
return !rc.page.IsEmpty();
|
||||
Rect br = r;
|
||||
r.left += format.lm;
|
||||
r.right -= format.rm;
|
||||
r.Deflate(format.frame);
|
||||
if(r.IsEmpty()) {
|
||||
r = br;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect RichTable::GetPageRect(PageY py) const
|
||||
{
|
||||
return py.page == clayout.py.page ? clayout.first_page : clayout.next_page;
|
||||
}
|
||||
|
||||
void RichTable::NextPage(PageY& py, bool header) const
|
||||
{
|
||||
py.y = header ? clayout.header_page.top : clayout.next_page.top;
|
||||
py.page++;
|
||||
}
|
||||
|
||||
RichContext RichTable::MakeRichContext(RichContext rc, PageY py, bool header) const
|
||||
{
|
||||
if(header)
|
||||
rc.Set(py, clayout.header_page, clayout.header_page, py);
|
||||
else
|
||||
rc.Set(clayout.py, clayout.first_page, clayout.next_page, py);
|
||||
return rc;
|
||||
}
|
||||
|
||||
const RichTable::TabLayout& RichTable::Realize(RichContext rc) const
|
||||
{ // Create page layout with header
|
||||
if(rc.py != cpy || rc.page != cpage) {
|
||||
rc.py.y += format.before;
|
||||
if(rc.py.y > rc.page.bottom) {
|
||||
// TODO: header/footer adjustment here
|
||||
rc.py.y = rc.page.top;
|
||||
rc.py.page++;
|
||||
}
|
||||
cpage = rc.page;
|
||||
cpy = rc.py;
|
||||
Reduce(rc);
|
||||
clayout.page = rc.page;
|
||||
clayout.hasheader = false;
|
||||
RichContext rc2 = rc;
|
||||
rc2.Page();
|
||||
if(rc.py != clayout.py || rc.page != clayout.first_page0 || rc2.page != clayout.next_page0) {
|
||||
clayout.sz = GetSize();
|
||||
clayout.py = rc.py;
|
||||
clayout.first_page = clayout.first_page0 = rc.page;
|
||||
clayout.next_page = clayout.next_page0 = rc2.page;
|
||||
Reduce(clayout.first_page);
|
||||
Reduce(clayout.next_page);
|
||||
clayout.header_page = clayout.next_page;
|
||||
PageY py = rc.py;
|
||||
py.y += format.before;
|
||||
if(py.y > clayout.first_page.bottom)
|
||||
NextPage(py, false);
|
||||
clayout.hasheader = false;
|
||||
if(format.header && cell.GetCount()) {
|
||||
RichContext nextpage_rc = rc;
|
||||
PageY hpy(0, clayout.next_page.top); // RowPaint will need page zero here to add real page
|
||||
nextpage_rc.Set(hpy, clayout.next_page, clayout.next_page, hpy);
|
||||
int hy = min(format.header, cell.GetCount());
|
||||
RichContext nrc = rc;
|
||||
nrc.py.page = 0;
|
||||
nrc.py.y = clayout.page.top;
|
||||
clayout.header = Realize(nrc, hy); // realize header as if first on page
|
||||
clayout.header = Realize(hpy, nextpage_rc, hy, true); // realize header as if first on next page
|
||||
if(clayout.header[0].py.page == clayout.header[hy - 1].pyy.page) { // header fits single page
|
||||
Layout x = Realize(rc, cell.GetCount());
|
||||
if(cell.GetCount() > hy && rc.py.page != x[hy].py.page) { // first header would break the end of page
|
||||
// TODO: header/footer adjustment here
|
||||
rc.py.page++;
|
||||
rc.py.y = rc.page.top;
|
||||
}
|
||||
Layout x = Realize(py, MakeRichContext(rc, py, false), cell.GetCount(), false); // TODO: check this
|
||||
if(cell.GetCount() > hy && py.page != x[hy].py.page) // first header would break the end of page
|
||||
NextPage(py, false);
|
||||
clayout.hasheader = true; // if it fits, we repeat header on each new page
|
||||
rc.page.top = clayout.page.top = clayout.header[hy - 1].pyy.y + format.grid; // so have to reduce the page size for nonheader rows
|
||||
clayout.header_page.bottom = clayout.header[hy - 1].pyy.y;
|
||||
clayout.next_page.top = clayout.header_page.bottom + format.grid ;// so have to reduce the page size for nonheader rows
|
||||
}
|
||||
}
|
||||
clayout.page0 = rc.py.page;
|
||||
(Layout&)clayout = Realize(rc, cell.GetCount());
|
||||
(Layout&)clayout = Realize(py, MakeRichContext(rc, py, false), cell.GetCount(), false);
|
||||
if(format.keep && cell.GetCount()) {
|
||||
if(clayout[0].py.page != clayout[cell.GetCount() - 1].pyy.page) {
|
||||
rc.py.page++;
|
||||
rc.py.y = rc.page.top;
|
||||
}
|
||||
clayout.page0 = rc.py.page;
|
||||
(Layout&)clayout = Realize(rc, cell.GetCount());
|
||||
if(clayout[0].py.page != clayout[cell.GetCount() - 1].pyy.page)
|
||||
NextPage(py, false);
|
||||
(Layout&)clayout = Realize(py, MakeRichContext(rc, py, false), cell.GetCount(), false);
|
||||
}
|
||||
}
|
||||
return clayout;
|
||||
}
|
||||
|
||||
RichTable::Layout RichTable::Realize(RichContext rc, int ny) const
|
||||
RichContext RichTable::PaintCell::MakeRichContext(RichContext rc) const
|
||||
{
|
||||
rc.page.left = page_left;
|
||||
rc.page.right = page_right;
|
||||
return rc;
|
||||
}
|
||||
|
||||
RichTable::Layout RichTable::Realize(PageY py, RichContext arc, int ny, bool header) const
|
||||
{ // create layout for first ny rows
|
||||
Layout tab;
|
||||
|
||||
|
||||
int nx = format.column.GetCount();
|
||||
tab.row.Alloc(ny);
|
||||
for(int i = 0; i < ny; i++)
|
||||
tab[i].cell.Alloc(nx);
|
||||
tab.col.Alloc(nx);
|
||||
|
||||
|
||||
int sum = 0;
|
||||
for(int i = 0; i < nx; i++)
|
||||
sum += format.column[i];
|
||||
|
||||
Buffer<int> column_left, column_right;
|
||||
column_left.Alloc(nx);
|
||||
column_right.Alloc(nx);
|
||||
|
||||
int x = 0;
|
||||
int xx = rc.page.left;
|
||||
int dcx = rc.page.Width();
|
||||
int xx = arc.page.left;
|
||||
int dcx = arc.page.Width();
|
||||
for(int i = 0; i < nx; i++) {
|
||||
Rect& cp = tab.col[i];
|
||||
cp = rc.page;
|
||||
cp.left = xx;
|
||||
column_left[i] = xx;
|
||||
x += format.column[i];
|
||||
xx = cp.right = x * dcx / sum + rc.page.left;
|
||||
xx = column_right[i] = x * dcx / sum + arc.page.left;
|
||||
}
|
||||
|
||||
int f2 = format.grid / 2;
|
||||
int ff2 = format.grid - f2;
|
||||
|
||||
rc.py.y += format.frame;
|
||||
py.y += format.frame;
|
||||
for(int i = 0; i < ny; i++) {
|
||||
const Array<RichCell>& row = cell[i];
|
||||
PaintRow& pr = tab[i];
|
||||
pr.first = i == 0;
|
||||
pr.gpy = rc.py;
|
||||
pr.gpy = py;
|
||||
if(i)
|
||||
rc.py.y += format.grid;
|
||||
py.y += format.grid;
|
||||
for(int j = 0; j < nx;) {
|
||||
PaintCell& pc = pr[j];
|
||||
const RichCell& cell = row[j];
|
||||
if(pc.top) {
|
||||
pc.page = tab.col[j];
|
||||
pc.page.right = tab.col[min(nx - 1, j + cell.hspan)].right;
|
||||
pc.page_left = pc.left = column_left[j];
|
||||
pc.page_right = pc.right = column_right[min(nx - 1, j + cell.hspan)];
|
||||
if(j)
|
||||
pc.page_left += f2;
|
||||
if(j + cell.hspan < nx - 1)
|
||||
pc.page_right -= ff2;
|
||||
pc.bottom = false;
|
||||
int ms = min(ny - 1, i + cell.vspan);
|
||||
for(int k = i + 1; k <= ms; k++) {
|
||||
|
|
@ -108,12 +138,6 @@ RichTable::Layout RichTable::Realize(RichContext rc, int ny) const
|
|||
pc.top = pc.bottom = false;
|
||||
}
|
||||
tab[ms][j].bottom = true;
|
||||
pc.left = pc.page.left;
|
||||
pc.right = pc.page.right;
|
||||
if(j)
|
||||
pc.page.left += f2;
|
||||
if(j + cell.hspan < nx - 1)
|
||||
pc.page.right -= ff2;
|
||||
}
|
||||
j += cell.hspan + 1;
|
||||
}
|
||||
|
|
@ -135,41 +159,40 @@ RichTable::Layout RichTable::Realize(RichContext rc, int ny) const
|
|||
}
|
||||
j += cell.hspan + 1;
|
||||
}
|
||||
if(!span)
|
||||
if(!span) // check whether we should break page before this row
|
||||
for(int j = 0; j < nx;) {
|
||||
const RichCell& cell = row[j];
|
||||
PaintCell& pc = pr[j];
|
||||
if(pc.top) {
|
||||
rc.page = pc.page;
|
||||
PageY ty = cell.GetTop(rc);
|
||||
PageY ky = rc.py;
|
||||
RichContext trc = pc.MakeRichContext(MakeRichContext(arc, py, header));
|
||||
PageY ty = cell.GetTop(trc);
|
||||
PageY ky = py;
|
||||
if(keep)
|
||||
ky = cell.GetHeight(rc);
|
||||
if(ty.page != rc.py.page || ky.page != rc.py.page) {
|
||||
rc.Page();
|
||||
pr.gpy = rc.py;
|
||||
ky = cell.GetHeight(trc);
|
||||
if(ty.page != py.page || ky.page != py.page) {
|
||||
NextPage(py, header);
|
||||
pr.gpy = py;
|
||||
pr.first = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
j += cell.hspan + 1;
|
||||
}
|
||||
pr.py = rc.py;
|
||||
pr.py = py;
|
||||
for(int j = 0; j < nx;) {
|
||||
const RichCell& cell = row[j];
|
||||
PaintCell& pc = pr[j];
|
||||
rc.page = pc.page;
|
||||
if(pc.top)
|
||||
tab[min(ny - 1, i + cell.vspan)][j].hy = cell.GetHeight(rc);
|
||||
tab[min(ny - 1, i + cell.vspan)][j].hy = cell.GetHeight(pc.MakeRichContext(MakeRichContext(arc, py, header)));
|
||||
j += cell.hspan + 1;
|
||||
}
|
||||
for(int j = 0; j < nx;) {
|
||||
const RichCell& cell = row[j];
|
||||
if(pr[j].bottom)
|
||||
rc.py = max(pr[j].hy, rc.py);
|
||||
py = max(pr[j].hy, py);
|
||||
j += cell.hspan + 1;
|
||||
}
|
||||
tab.pyy = pr.pyy = rc.py;
|
||||
tab.pyy = pr.pyy = py;
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,17 +24,15 @@ void RichTable::ExpandFrr(VectorMap<int, Rect>& frr, int pi, int l, int r, int t
|
|||
fr.bottom = max(fr.bottom, b);
|
||||
}
|
||||
|
||||
bool RichTable::RowPaint(PageDraw& pw, const RichStyles& st, const Layout& tab,
|
||||
int i, int ny, const Rect& pg, VectorMap<int, Rect>& frr,
|
||||
bool RichTable::RowPaint(PageDraw& pw, RichContext rc, const Layout& tab, bool header,
|
||||
int i, int ny, Rect pg, Rect npg,
|
||||
VectorMap<int, Rect>& frr,
|
||||
PaintInfo& pi, int pd, bool sel) const
|
||||
{
|
||||
RichContext rc(st, NULL);
|
||||
const Array<RichCell>& row = cell[i];
|
||||
const PaintRow& pr = tab[i];
|
||||
rc.py = pr.py;
|
||||
rc.py.page += pd;
|
||||
if(pw.tracer)
|
||||
pw.tracer->TableRow(pg, rc.py, i, *this);
|
||||
pw.tracer->TableRow(GetPageRect(pr.py), rc.py, i, *this);
|
||||
int gridln = LineZoom(pi.zoom, format.grid);
|
||||
int ff2ln = gridln - gridln / 2;
|
||||
Color gc = format.gridcolor;
|
||||
|
|
@ -42,53 +40,59 @@ bool RichTable::RowPaint(PageDraw& pw, const RichStyles& st, const Layout& tab,
|
|||
gridln = 1;
|
||||
gc = pi.showcodes;
|
||||
}
|
||||
PageY py = pr.py;
|
||||
py.page += pd;
|
||||
if(py.page != clayout.py.page) // We are on the next page already
|
||||
pg = npg;
|
||||
for(int j = 0; j < format.column.GetCount();) {
|
||||
const RichCell& cell = row[j];
|
||||
const PaintCell& pc = pr[j];
|
||||
if(pc.top) {
|
||||
PageY pyy = tab[min(ny - 1, i + cell.vspan)].pyy;
|
||||
pyy.page += pd;
|
||||
pyy.page += pd; // move header line
|
||||
bool paint = pyy > pi.top;
|
||||
rc.page = pr[j].page;
|
||||
Rect xpg = pg;
|
||||
Rect xpg = pg; // on first page
|
||||
Rect nxpg = npg; // on next page
|
||||
int y;
|
||||
int ny = pi.zoom * pyy.y;
|
||||
y = pi.zoom * pr.gpy.y;
|
||||
if(j) {
|
||||
xpg.left = pi.zoom * pc.left - ff2ln;
|
||||
if(pyy.page == rc.py.page)
|
||||
pw.Page(rc.py.page).DrawRect(xpg.left, y, gridln, ny - y, gc);
|
||||
nxpg.left = xpg.left = pi.zoom * pc.left;
|
||||
xpg.right = pi.zoom * pc.right;
|
||||
if(j) { // need to draw vertical grid line on the left
|
||||
nxpg.left = xpg.left = xpg.left - ff2ln; // move half of vertical grid width left
|
||||
if(py.page == pyy.page)
|
||||
pw.Page(py.page).DrawRect(xpg.left, y, gridln, ny - y, gc);
|
||||
else {
|
||||
pw.Page(rc.py.page).DrawRect(xpg.left, y, gridln, pg.bottom - y, gc);
|
||||
for(int i = rc.py.page + 1; i < pyy.page; i++)
|
||||
pw.Page(i).DrawRect(xpg.left, pg.top, gridln, pg.bottom - pg.top, gc);
|
||||
pw.Page(pyy.page).DrawRect(xpg.left, pg.top, gridln, ny - pg.top, gc);
|
||||
pw.Page(py.page).DrawRect(xpg.left, y, gridln, pg.bottom - y, gc);
|
||||
for(int i = py.page + 1; i < pyy.page; i++)
|
||||
pw.Page(i).DrawRect(nxpg.left, npg.top, gridln, npg.bottom - npg.top, gc);
|
||||
pw.Page(pyy.page).DrawRect(nxpg.left, npg.top, gridln, ny - npg.top, gc);
|
||||
}
|
||||
xpg.left += gridln;
|
||||
nxpg.left = xpg.left = xpg.left + gridln;
|
||||
}
|
||||
if(j + cell.hspan < format.column.GetCount() - 1)
|
||||
xpg.right = pi.zoom * pc.right - ff2ln;
|
||||
if(!pr.first) {
|
||||
y += gridln;
|
||||
xpg.right = pi.zoom * pc.right - ff2ln; // make place for the next grid line
|
||||
if(!pr.first) { // Draw horizontal grid line
|
||||
if(paint)
|
||||
pw.Page(rc.py.page).DrawRect(xpg.left, y - gridln, xpg.Width(), gridln, gc);
|
||||
pw.Page(py.page).DrawRect(xpg.left, y, xpg.Width(), gridln, gc);
|
||||
y += gridln;
|
||||
}
|
||||
if(paint) {
|
||||
if(pw.tracer)
|
||||
pw.tracer->TableCell(rc.page, rc.py, i, j, *this, pyy);
|
||||
row[j].Paint(pw, rc, pyy, xpg, y, ny, pi,
|
||||
row[j].Paint(pw, pc.MakeRichContext(MakeRichContext(rc, py, header)), pyy, xpg, nxpg, y, ny, pi,
|
||||
sel && j >= pi.cells.left && i >= pi.cells.top &&
|
||||
j + cell.hspan <= pi.cells.right && i + cell.vspan <= pi.cells.bottom);
|
||||
if(pw.tracer)
|
||||
pw.tracer->EndTableCell(pyy);
|
||||
}
|
||||
if(pyy.page == rc.py.page)
|
||||
ExpandFrr(frr, pyy.page, xpg.left, xpg.right, y, ny);
|
||||
if(pyy.page == py.page)
|
||||
ExpandFrr(frr, py.page, xpg.left, xpg.right, y, ny);
|
||||
else {
|
||||
ExpandFrr(frr, rc.py.page, xpg.left, xpg.right, y, xpg.bottom);
|
||||
for(int i = rc.py.page + 1; i < pyy.page; i++)
|
||||
ExpandFrr(frr, i, xpg.left, xpg.right, xpg.top, xpg.bottom);
|
||||
ExpandFrr(frr, pyy.page, xpg.left, xpg.right, xpg.top, ny);
|
||||
ExpandFrr(frr, py.page, xpg.left, xpg.right, y, xpg.bottom);
|
||||
for(int i = py.page + 1; i < pyy.page; i++)
|
||||
ExpandFrr(frr, i, nxpg.left, nxpg.right, nxpg.top, nxpg.bottom);
|
||||
ExpandFrr(frr, pyy.page, nxpg.left, nxpg.right, nxpg.top, ny);
|
||||
}
|
||||
int l = cell.text.GetLength() + 1;
|
||||
pi.sell -= l;
|
||||
|
|
@ -102,70 +106,86 @@ bool RichTable::RowPaint(PageDraw& pw, const RichStyles& st, const Layout& tab,
|
|||
return rc.py >= pi.bottom;
|
||||
}
|
||||
|
||||
void RichTable::Paint(PageDraw& pw, RichContext rc, const PaintInfo& _pi) const
|
||||
void RichTable::Paint(PageDraw& pw, RichContext rc, const PaintInfo& _pi, bool baselevel) const
|
||||
{
|
||||
if(pw.tracer)
|
||||
pw.tracer->Table(rc.page, rc.py, *this);
|
||||
const TabLayout& tab = Realize(rc);
|
||||
if(!tab.page.IsEmpty()) {
|
||||
PaintInfo pi = _pi;
|
||||
int frameln = LineZoom(pi.zoom, format.frame);
|
||||
int gridln = LineZoom(pi.zoom, format.grid);
|
||||
Rect pg = rc.page;
|
||||
pg.left += format.lm;
|
||||
pg.right -= format.rm;
|
||||
pg.left = pi.zoom * pg.left;
|
||||
pg.right = pi.zoom * pg.right;
|
||||
pg.top = pi.zoom * pg.top;
|
||||
pg.bottom = pi.zoom * pg.bottom;
|
||||
pg.Deflate(frameln);
|
||||
int hy = min(format.header, cell.GetCount());
|
||||
Rect hpg = pg;
|
||||
PaintInfo pi = _pi;
|
||||
int frameln = LineZoom(pi.zoom, format.frame);
|
||||
int gridln = LineZoom(pi.zoom, format.grid);
|
||||
Rect pg[2];
|
||||
Rect hpg;
|
||||
RichContext hrc = rc;
|
||||
int hy = min(format.header, cell.GetCount());
|
||||
for(int pass = 0;; pass++) {
|
||||
Rect& pgr = pg[pass];
|
||||
pgr = pass ? tab.next_page : tab.first_page;
|
||||
pgr.left += format.lm;
|
||||
pgr.right -= format.rm;
|
||||
pgr.left = pi.zoom * pgr.left;
|
||||
pgr.right = pi.zoom * pgr.right;
|
||||
pgr.top = pi.zoom * pgr.top;
|
||||
pgr.bottom = pi.zoom * pgr.bottom;
|
||||
pgr.Deflate(LineZoom(pi.zoom, format.frame));
|
||||
if(pass)
|
||||
break;
|
||||
hpg = pgr;
|
||||
if(tab.hasheader) {
|
||||
hpg.bottom = pi.zoom * tab.header[hy - 1].pyy.y;
|
||||
pg.top = hpg.bottom + gridln;
|
||||
pgr.top = hpg.bottom + LineZoom(pi.zoom, format.grid);
|
||||
}
|
||||
bool allsel = false;
|
||||
if(pi.sell < 0 && pi.selh >= 0) {
|
||||
pi.sell = pi.selh = 0;
|
||||
allsel = true;
|
||||
}
|
||||
bool sel = pi.tablesel == 0;
|
||||
int ny = cell.GetCount();
|
||||
VectorMap<int, Rect> frr;
|
||||
for(int i = 0; i < ny; i++)
|
||||
if(RowPaint(pw, *rc.styles, tab, i, ny, pg, frr, pi, 0, sel))
|
||||
break;
|
||||
hrc.Page();
|
||||
}
|
||||
|
||||
Color gc = format.gridcolor;
|
||||
Color fc = format.framecolor;
|
||||
int fl = frameln;
|
||||
if(!IsNull(pi.showcodes)) {
|
||||
if(fl == 0 && !IsNull(pi.showcodes)) {
|
||||
fl = 1;
|
||||
fc = pi.showcodes;
|
||||
}
|
||||
if(gridln == 0) {
|
||||
gridln = 1;
|
||||
gc = pi.showcodes;
|
||||
}
|
||||
bool allsel = false;
|
||||
if(pi.sell < 0 && pi.selh >= 0) {
|
||||
pi.sell = pi.selh = 0;
|
||||
allsel = true;
|
||||
}
|
||||
bool sel = pi.tablesel == 0;
|
||||
int ny = cell.GetCount();
|
||||
|
||||
if(format.newhdrftr && ny && baselevel) {
|
||||
Image img = RichTextImg::HdrFtr();
|
||||
Size isz = img.GetSize();
|
||||
pw.Page(tab[0].py.page).DrawImage(-7 - isz.cx, pi.zoom * tab[0].py.y, img, pi.showcodes);
|
||||
}
|
||||
|
||||
VectorMap<int, Rect> frr; // page -> table rectangle
|
||||
for(int i = 0; i < ny; i++)
|
||||
if(RowPaint(pw, rc, tab, false, i, ny, pg[0], pg[1], frr, pi, 0, sel))
|
||||
break;
|
||||
|
||||
Color gc = format.gridcolor;
|
||||
Color fc = format.framecolor;
|
||||
int fl = frameln;
|
||||
if(!IsNull(pi.showcodes)) {
|
||||
if(fl == 0 && !IsNull(pi.showcodes)) {
|
||||
fl = 1;
|
||||
fc = pi.showcodes;
|
||||
}
|
||||
for(int i = 0; i < frr.GetCount(); i++) {
|
||||
pi.tablesel = 0;
|
||||
pi.sell = pi.selh = -1;
|
||||
int pgi = frr.GetKey(i);
|
||||
Draw& w = pw.Page(pgi);
|
||||
if(pgi > tab.page0 && tab.hasheader)
|
||||
for(int i = 0; i < hy; i++) {
|
||||
RowPaint(pw, *rc.styles, tab.header, i, hy, hpg, frr, pi, pgi, false);
|
||||
w.DrawRect(pg.left, hpg.bottom, pg.Width(), gridln, format.gridcolor);
|
||||
}
|
||||
Rect r = frr[i].Inflated(frameln);
|
||||
if(!r.IsEmpty()) {
|
||||
DrawFatFrame(w, r, fc, fl);
|
||||
if(allsel)
|
||||
w.DrawRect(r, InvertColor);
|
||||
if(gridln == 0) {
|
||||
gridln = 1;
|
||||
gc = pi.showcodes;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < frr.GetCount(); i++) { // add headers on subsequent pages and outer border
|
||||
pi.tablesel = 0;
|
||||
pi.sell = pi.selh = -1;
|
||||
int pgi = frr.GetKey(i);
|
||||
Rect r = frr[i];
|
||||
if(pgi > tab.py.page && tab.hasheader) // need to paint header here...
|
||||
for(int i = 0; i < hy; i++) {
|
||||
RowPaint(pw, rc, tab.header, true, i, hy, hpg, hpg, frr, pi, pgi, false);
|
||||
pw.Page(pgi).DrawRect(r.left, hpg.bottom, r.Width(), gridln, format.gridcolor);
|
||||
}
|
||||
r = frr[i].Inflated(frameln);
|
||||
Draw& w = pw.Page(pgi);
|
||||
if(!r.IsEmpty()) {
|
||||
DrawFatFrame(w, r, fc, fl);
|
||||
if(allsel)
|
||||
w.DrawRect(r, InvertColor);
|
||||
}
|
||||
}
|
||||
if(pw.tracer)
|
||||
|
|
@ -200,10 +220,8 @@ PageY RichTable::GetHeight(RichContext rc) const
|
|||
PageY pyy = Realize(rc).pyy;
|
||||
pyy.y += format.frame;
|
||||
pyy.y += format.after;
|
||||
if(pyy.y > rc.page.bottom) {
|
||||
pyy.y = rc.page.top;
|
||||
pyy.page++;
|
||||
}
|
||||
if(pyy.y > GetPageRect(pyy).bottom)
|
||||
NextPage(pyy);
|
||||
return pyy;
|
||||
}
|
||||
|
||||
|
|
@ -211,9 +229,9 @@ PageY RichTable::GetTop(RichContext rc) const
|
|||
{
|
||||
if(cell.GetCount() == 0)
|
||||
return rc.py;
|
||||
rc.py = Realize(rc)[0].py;
|
||||
rc.py.y -= format.frame;
|
||||
return rc.py;
|
||||
PageY py = Realize(rc)[0].py;
|
||||
py.y -= format.frame;
|
||||
return py;
|
||||
}
|
||||
|
||||
RichCaret RichTable::GetCaret(int pos, RichContext rc) const
|
||||
|
|
@ -225,17 +243,14 @@ RichCaret RichTable::GetCaret(int pos, RichContext rc) const
|
|||
const TabLayout& tab = Realize(rc);
|
||||
for(int i = 0; i < ny; i++) {
|
||||
const PaintRow& pr = tab[i];
|
||||
rc.py = pr.py;
|
||||
PageY pyy;
|
||||
for(int j = 0; j < nx; j++) {
|
||||
if(ci[i][j].valid) {
|
||||
const RichCell& cl = cell[i][j];
|
||||
pyy = tab[min(ny - 1, i + cl.vspan)].pyy;
|
||||
int l = cl.text.GetLength() + 1;
|
||||
if(pos < l) {
|
||||
rc.page = pr[j].page;
|
||||
return cl.GetCaret(pos, rc, pyy);
|
||||
}
|
||||
if(pos < l)
|
||||
return cl.GetCaret(pos, pr[j].MakeRichContext(MakeRichContext(rc, pr.py)), pyy);
|
||||
ti += cl.text.GetTableCount();
|
||||
pos -= l;
|
||||
}
|
||||
|
|
@ -260,11 +275,9 @@ int RichTable::GetPos(int x, PageY y, RichContext rc) const
|
|||
const PaintCell& pc = pr[j];
|
||||
PageY pyy = tab[min(ny - 1, i + cl.vspan)].pyy;
|
||||
if(y < pyy
|
||||
&& (j == 0 || x >= pc.page.left - format.grid)
|
||||
&& (j == nx - 1 || x < pc.page.right)) {
|
||||
rc.page = pc.page;
|
||||
return cl.GetPos(x, y, rc, pyy) + pos;
|
||||
}
|
||||
&& (j == 0 || x >= pc.page_left - format.grid)
|
||||
&& (j == nx - 1 || x < pc.page_right))
|
||||
return cl.GetPos(x, y, pr[j].MakeRichContext(MakeRichContext(rc, pr.py)), pyy) + pos;
|
||||
pos += cl.text.GetLength() + 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -273,45 +286,46 @@ int RichTable::GetPos(int x, PageY y, RichContext rc) const
|
|||
|
||||
RichHotPos RichTable::GetHotPos(int x, PageY y, int tolerance, RichContext rc) const
|
||||
{
|
||||
|
||||
RichHotPos hp;
|
||||
hp.textleft = rc.page.left;
|
||||
hp.textcx = rc.page.Width();
|
||||
int nx = format.column.GetCount();
|
||||
int ny = cell.GetCount();
|
||||
const TabLayout& tab = Realize(rc);
|
||||
if(abs(x - tab.page.left) <= tolerance) {
|
||||
int left = tab.first_page.left;
|
||||
int right = tab.first_page.right;
|
||||
if(abs(x - left) <= tolerance) {
|
||||
hp.table = 0;
|
||||
hp.column = RICHHOT_LM;
|
||||
hp.delta = x - tab.page.left;
|
||||
hp.delta = x - left;
|
||||
return hp;
|
||||
}
|
||||
if(abs(x - tab.page.right) <= tolerance) {
|
||||
if(abs(x - right) <= tolerance) {
|
||||
hp.table = 0;
|
||||
hp.column = RICHHOT_RM;
|
||||
hp.delta = x - tab.page.right;
|
||||
hp.delta = x - right;
|
||||
return hp;
|
||||
}
|
||||
int ti = 0;
|
||||
for(int i = 0; i < ny; i++) {
|
||||
const PaintRow& pr = tab[i];
|
||||
rc.py = pr.py;
|
||||
for(int j = 0; j < nx; j++) {
|
||||
if(ci[i][j].valid) {
|
||||
const RichCell& cl = cell[i][j];
|
||||
const PaintCell& pc = pr[j];
|
||||
PageY pyy = tab[min(ny - 1, i + cl.vspan)].pyy;
|
||||
if(y < pyy) {
|
||||
if(j < nx - 1 && abs(x - pc.page.right) <= tolerance) {
|
||||
if(j < nx - 1 && abs(x - pc.right) <= tolerance) {
|
||||
hp.table = 0;
|
||||
hp.column = j + cl.hspan;
|
||||
hp.delta = x - pc.page.right;
|
||||
hp.left = tab.page.left;
|
||||
hp.cx = tab.page.Width();
|
||||
hp.delta = x - pc.right;
|
||||
hp.left = left;
|
||||
hp.cx = right - left;
|
||||
return hp;
|
||||
}
|
||||
if((j == 0 || x >= pc.page.left - format.grid) && (j == nx - 1 || x < pc.page.right)) {
|
||||
rc.page = pc.page;
|
||||
hp = cl.GetHotPos(x, y, tolerance, rc, pyy);
|
||||
if((j == 0 || x >= pc.left - format.grid) && (j == nx - 1 || x < pc.right)) {
|
||||
hp = cl.GetHotPos(x, y, tolerance, MakeRichContext(rc, pr.py) , pyy);
|
||||
hp.table += ti;
|
||||
return hp;
|
||||
}
|
||||
|
|
@ -338,16 +352,15 @@ int RichTable::GetVertMove(int pos, int gx, RichContext rc, int dir) const
|
|||
cp.x = 0;
|
||||
const PaintRow& pr = tab[cp.y];
|
||||
for(int j = 0; j < nx; j++)
|
||||
if(ci[cp.y][cp.x].valid && gx < pr[j].page.right) {
|
||||
if(ci[cp.y][cp.x].valid && gx < pr[j].page_right) {
|
||||
cp.x = j;
|
||||
break;
|
||||
}
|
||||
pos = -1;
|
||||
}
|
||||
for(;;) {
|
||||
rc.page = tab[cp.y][cp.x].page;
|
||||
RichContext rc1 = tab[cp.y][cp.x].MakeRichContext(rc);
|
||||
const RichCell& c = cell[cp.y][cp.x];
|
||||
RichContext rc1 = rc;
|
||||
if(c.Reduce(rc1)) {
|
||||
int q = cell[cp.y][cp.x].text.GetVertMove(pos, gx, rc1, dir);
|
||||
if(q >= 0)
|
||||
|
|
@ -372,8 +385,7 @@ void RichTable::GatherValPos(Vector<RichValPos>& f, RichContext rc, int pos, int
|
|||
for(int j = 0; j < nx; j++)
|
||||
if(ci[i][j].valid) {
|
||||
const RichCell& cl = cell[i][j];
|
||||
rc.page = pr[j].page;
|
||||
cl.GatherValPos(f, rc, tab[min(ny - 1, i + cl.vspan)].pyy, pos, type);
|
||||
cl.GatherValPos(f, pr[j].MakeRichContext(rc), tab[min(ny - 1, i + cl.vspan)].pyy, pos, type);
|
||||
pos += cl.text.GetLength() + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,15 +71,15 @@ void RichTxt::Advance(int parti, RichContext& rc, RichContext& begin) const
|
|||
{
|
||||
if(part[parti].Is<RichTable>()) {
|
||||
const RichTable& tab = GetTable(parti);
|
||||
if(tab.format.newhdrftr && rc.text == this) {
|
||||
rc.NewHeaderFooter(~tab.header, ~tab.footer);
|
||||
rc.Page();
|
||||
}
|
||||
else
|
||||
if(tab.format.newhdrftr && rc.text == this)
|
||||
rc.HeaderFooter(~tab.header, ~tab.footer);
|
||||
if(tab.format.newpage)
|
||||
rc.Page();
|
||||
begin = rc;
|
||||
rc.py = GetTable(parti).GetHeight(rc);
|
||||
PageY py = GetTable(parti).GetHeight(rc);
|
||||
if(py.page > rc.py.page)
|
||||
rc.Page(); // set new header / footer and page size
|
||||
rc.py = py;
|
||||
}
|
||||
else {
|
||||
Sync(parti, rc);
|
||||
|
|
@ -98,11 +98,8 @@ void RichTxt::Advance(int parti, RichContext& rc, RichContext& begin) const
|
|||
nbefore = p.before + p.ruler;
|
||||
nline = p.linecy[0];
|
||||
}
|
||||
if(pp.newhdrftr && rc.text == this) {
|
||||
rc.NewHeaderFooter(~pp.header, ~pp.footer);
|
||||
rc.Page();
|
||||
}
|
||||
else
|
||||
if(pp.newhdrftr && rc.text == this)
|
||||
rc.HeaderFooter(~pp.header, ~pp.footer);
|
||||
if(pp.newpage || rc.py.y + cy + nbefore + nline > rc.page.bottom && cy < rc.page.Height())
|
||||
rc.Page();
|
||||
begin = rc;
|
||||
|
|
@ -171,7 +168,7 @@ void RichTxt::Paint(PageDraw& pw, RichContext& rc, const PaintInfo& _pi) const
|
|||
const RichTable& tab = GetTable(parti);
|
||||
RichContext begin;
|
||||
Advance(parti, rc, begin);
|
||||
tab.Paint(pw, begin, pi);
|
||||
tab.Paint(pw, begin, pi, rc.text == this);
|
||||
pi.tablesel -= tab.GetTableCount();
|
||||
}
|
||||
else {
|
||||
|
|
@ -195,7 +192,7 @@ void RichTxt::Paint(PageDraw& pw, RichContext& rc, const PaintInfo& _pi) const
|
|||
pp.spellerrors.Clear();
|
||||
}
|
||||
if(IsPainting(pw, pi.zoom, rc.page, begin.py, next.py))
|
||||
p.Paint(pw, rc.page, begin.py, pi, n, pp.spellerrors, rc.text == this);
|
||||
p.Paint(pw, begin, pi, n, pp.spellerrors, rc.text == this);
|
||||
}
|
||||
rc = next;
|
||||
}
|
||||
|
|
@ -221,7 +218,7 @@ RichCaret RichTxt::GetCaret(int pos, RichContext rc) const
|
|||
if(IsTable(parti))
|
||||
return GetTable(parti).GetCaret(pos, begin);
|
||||
else {
|
||||
RichCaret tp = Get(parti, *rc.styles, true).GetCaret(pos, begin.page, begin.py);
|
||||
RichCaret tp = Get(parti, *rc.styles, true).GetCaret(pos, begin);
|
||||
tp.textpage = begin.page;
|
||||
return tp;
|
||||
}
|
||||
|
|
@ -245,7 +242,7 @@ int RichTxt::GetPos(int x, PageY y, RichContext rc) const
|
|||
if(IsTable(parti))
|
||||
return GetTable(parti).GetPos(x, y, begin) + pos;
|
||||
else
|
||||
return Get(parti, *rc.styles, true).GetPos(x, y, begin.page, begin.py) + pos;
|
||||
return Get(parti, *rc.styles, true).GetPos(x, y, begin) + pos;
|
||||
}
|
||||
pos += GetPartLength(parti) + 1;
|
||||
parti++;
|
||||
|
|
@ -329,9 +326,9 @@ void RichTxt::GatherValPos(Vector<RichValPos>& f, RichContext rc, int pos, int t
|
|||
const Para& p = part[parti].Get<Para>();
|
||||
if(p.haspos) {
|
||||
if(type == LABELS)
|
||||
Get(parti, *begin.styles, true).GatherLabels(f, begin.page, begin.py, pos);
|
||||
Get(parti, *begin.styles, true).GatherLabels(f, begin, pos);
|
||||
else
|
||||
Get(parti, *begin.styles, true).GatherIndexes(f, begin.page, begin.py, pos);
|
||||
Get(parti, *begin.styles, true).GatherIndexes(f, begin, pos);
|
||||
}
|
||||
}
|
||||
pos += GetPartLength(parti) + 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue