mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
194 lines
5.1 KiB
C++
194 lines
5.1 KiB
C++
#include "RichText.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
int LineZoom(Zoom z, int a)
|
|
{
|
|
return a ? max(1, z * a) : 0;
|
|
}
|
|
|
|
RichCell::Format::Format()
|
|
{
|
|
margin.left = margin.right = 25;
|
|
margin.top = margin.bottom = 15;
|
|
border.Clear();
|
|
align = ALIGN_CENTER;
|
|
color = White;
|
|
bordercolor = Black;
|
|
keep = false;
|
|
minheight = 0;
|
|
}
|
|
|
|
void RichCell::ClearText()
|
|
{
|
|
text.Clear();
|
|
RichPara h;
|
|
text.Cat(h, RichStyles());
|
|
}
|
|
|
|
void RichCell::ClearText(const RichPara::Format& format, const RichStyles& style)
|
|
{
|
|
text.Clear();
|
|
RichPara h;
|
|
h.format = format;
|
|
text.Cat(h, style);
|
|
}
|
|
|
|
void RichCell::Clear()
|
|
{
|
|
format = Format();
|
|
vspan = hspan = 0;
|
|
ClearText();
|
|
}
|
|
|
|
bool RichCell::Reduce(RichContext& rc) const
|
|
{
|
|
Rect br = rc.page;
|
|
rc.page.top += format.margin.top + format.border.top;
|
|
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())
|
|
rc.page = br;
|
|
return !rc.page.IsEmpty();
|
|
}
|
|
|
|
PageY RichCell::GetTop(RichContext rc) const
|
|
{
|
|
if(!Reduce(rc))
|
|
return rc.py;
|
|
rc.py.y += format.margin.top + format.border.top;
|
|
return text.GetTop(rc);
|
|
}
|
|
|
|
PageY RichCell::GetHeight(RichContext rc) const
|
|
{
|
|
if(Reduce(rc)) {
|
|
PageY py = rc.py;
|
|
rc.py.y += format.margin.top + format.border.top;
|
|
rc.py = text.GetHeight(rc);
|
|
rc.py.y += format.margin.bottom + format.border.bottom;
|
|
py.y += format.margin.top + format.border.top +
|
|
format.minheight +
|
|
format.margin.bottom + format.border.bottom;
|
|
return py.y <= rc.page.bottom && py > rc.py ? py : rc.py;
|
|
}
|
|
else {
|
|
rc.py.y += format.margin.top + format.border.top;
|
|
rc.py.y += 80;
|
|
rc.py.y += format.margin.bottom + format.border.bottom;
|
|
if(rc.py.y >= rc.page.bottom) {
|
|
rc.Page();
|
|
rc.py.y += 80;
|
|
}
|
|
}
|
|
return rc.py;
|
|
}
|
|
|
|
void RichCell::DrawCell(Draw& w, int l, int r, int y, int yy, const Rect& border) const
|
|
{
|
|
w.DrawRect(l, y, r - l, border.top, format.bordercolor);
|
|
w.DrawRect(l, y, border.left, yy - y, format.bordercolor);
|
|
w.DrawRect(r - border.right, y, border.right, yy - y, format.bordercolor);
|
|
w.DrawRect(l, yy - border.bottom, r - l, border.bottom, format.bordercolor);
|
|
w.DrawRect(l + border.left, y + border.top,
|
|
r - l - border.left - border.right, yy - y - border.top - border.bottom,
|
|
format.color);
|
|
}
|
|
|
|
PageY RichCell::Align(const RichContext& rc, PageY npy) const
|
|
{
|
|
PageY y = rc.py;
|
|
y.y += format.margin.top + format.border.top;
|
|
if(rc.py.page == npy.page) {
|
|
int dx = npy.y - text.GetHeight(rc).y
|
|
- format.margin.top - format.border.top
|
|
- format.margin.bottom - format.border.bottom;
|
|
if(format.align == ALIGN_CENTER)
|
|
y.y += dx / 2;
|
|
else
|
|
if(format.align == ALIGN_BOTTOM)
|
|
y.y += dx;
|
|
}
|
|
return y;
|
|
}
|
|
|
|
void RichCell::Paint(PageDraw& pw, RichContext rc, PageY npy,
|
|
const Rect& xpg, int y, int ny, const PaintInfo& pi, bool select) const
|
|
{
|
|
if(!Reduce(rc))
|
|
return;
|
|
Rect border(LineZoom(pi.zoom, format.border.left), LineZoom(pi.zoom, format.border.top),
|
|
LineZoom(pi.zoom, format.border.right), LineZoom(pi.zoom, format.border.bottom));
|
|
if(rc.py.page == npy.page)
|
|
DrawCell(pw.Page(rc.py.page), xpg.left, xpg.right, y, ny, border);
|
|
else {
|
|
DrawCell(pw.Page(rc.py.page), xpg.left, xpg.right, y, xpg.bottom, border);
|
|
for(int i = rc.py.page + 1; i < npy.page; i++)
|
|
DrawCell(pw.Page(i), xpg.left, xpg.right, xpg.top, xpg.bottom, border);
|
|
DrawCell(pw.Page(npy.page), xpg.left, xpg.right, xpg.top, ny, border);
|
|
}
|
|
|
|
rc.py = Align(rc, npy);
|
|
text.Paint(pw, rc, pi);
|
|
|
|
if(select) {
|
|
int cx = xpg.right - xpg.left;
|
|
if(rc.py.page == npy.page)
|
|
pw.Page(rc.py.page).DrawRect(xpg.left, y, cx, ny - y, InvertColor);
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
RichCaret RichCell::GetCaret(int pos, RichContext rc, PageY pyy) const
|
|
{
|
|
if(!Reduce(rc))
|
|
return RichCaret();
|
|
rc.py = Align(rc, pyy);
|
|
return text.GetCaret(pos, rc);
|
|
}
|
|
|
|
int RichCell::GetPos(int x, PageY y, RichContext rc, PageY pyy) const
|
|
{
|
|
if(!Reduce(rc))
|
|
return 0;
|
|
rc.py = Align(rc, pyy);
|
|
return text.GetPos(x, y, rc);
|
|
}
|
|
|
|
RichHotPos RichCell::GetHotPos(int x, PageY y, int tolerance, RichContext rc, PageY pyy) const
|
|
{
|
|
if(!Reduce(rc))
|
|
return RichHotPos();
|
|
rc.py = Align(rc, pyy);
|
|
return text.GetHotPos(x, y, tolerance, rc);
|
|
}
|
|
|
|
void RichCell::GatherValPos(Vector<RichValPos>& f, RichContext rc, PageY pyy, int pos, int type) const
|
|
{
|
|
if(!Reduce(rc))
|
|
return;
|
|
rc.py = Align(rc, pyy);
|
|
text.GatherValPos(f, rc, pos, type);
|
|
}
|
|
|
|
RichCell::RichCell()
|
|
{
|
|
vspan = hspan = 0;
|
|
Clear();
|
|
}
|
|
|
|
RichCell::RichCell(const RichCell& src, int)
|
|
{
|
|
format = src.format;
|
|
hspan = src.hspan;
|
|
vspan = src.vspan;
|
|
text <<= src.text;
|
|
}
|
|
|
|
END_UPP_NAMESPACE
|