mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
commit
263ff5f895
2665 changed files with 642923 additions and 0 deletions
376
uppsrc/RichText/ParaType.cpp
Normal file
376
uppsrc/RichText/ParaType.cpp
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
#include "RichText.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
void RichPara::Smh(Lines& lines, HeightInfo *th, int cx) const
|
||||
{
|
||||
Line& l = lines.line.Top();
|
||||
l.ascent = l.descent = l.external = 0;
|
||||
const HeightInfo *he = th + l.pos + l.len;
|
||||
for(const HeightInfo *h = th + l.pos; h < he; h++) {
|
||||
if(h->ascent > l.ascent) l.ascent = h->ascent;
|
||||
if(h->descent > l.descent) l.descent = h->descent;
|
||||
if(h->external > l.external) l.external = h->external;
|
||||
}
|
||||
if(format.linespacing == LSP15) {
|
||||
l.ascent = (3 * l.ascent) >> 1;
|
||||
l.descent = (3 * l.descent) >> 1;
|
||||
}
|
||||
if(format.linespacing == LSP20) {
|
||||
l.ascent = 2 * l.ascent;
|
||||
l.descent = 2 * l.descent;
|
||||
}
|
||||
l.xpos = format.lm;
|
||||
cx -= format.lm + format.rm;
|
||||
l.xpos += lines.GetCount() == 1 ? lines.first_indent : lines.next_indent;
|
||||
if(!l.withtabs)
|
||||
switch(format.align) {
|
||||
case ALIGN_RIGHT:
|
||||
l.xpos += cx - l.cx;
|
||||
break;
|
||||
case ALIGN_CENTER:
|
||||
l.xpos += (cx - l.cx) / 2;
|
||||
break;
|
||||
}
|
||||
l.cx -= lines.GetCount() == 1 ? lines.first_indent : lines.next_indent;
|
||||
}
|
||||
|
||||
RichPara::Tab RichPara::GetNextTab(int pos) const
|
||||
{
|
||||
int tabi = -1;
|
||||
int dist = INT_MAX;
|
||||
for(int i = 0; i < format.tab.GetCount(); i++) {
|
||||
const Tab& tab = format.tab[i];
|
||||
if(tab.pos > pos && tab.pos - pos < dist) {
|
||||
tabi = i;
|
||||
dist = tab.pos - pos;
|
||||
}
|
||||
}
|
||||
if(format.bullet == BULLET_TEXT) {
|
||||
int q = format.indent + format.lm;
|
||||
if(q > pos && q - pos < dist) {
|
||||
Tab tab;
|
||||
tab.align = ALIGN_LEFT;
|
||||
tab.pos = q;
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
if(tabi < 0) {
|
||||
Tab tab;
|
||||
tab.pos = format.tabsize ? (pos + format.tabsize) / format.tabsize * format.tabsize : 0;
|
||||
tab.align = ALIGN_LEFT;
|
||||
return tab;
|
||||
}
|
||||
return format.tab[tabi];
|
||||
}
|
||||
|
||||
struct RichPara::StorePart {
|
||||
wchar *t;
|
||||
int *w;
|
||||
int *p;
|
||||
const CharFormat **f;
|
||||
HeightInfo *h;
|
||||
int pos;
|
||||
FontInfo pfi;
|
||||
|
||||
void Store(Lines& lines, const Part& p, int pinc);
|
||||
};
|
||||
|
||||
void RichPara::StorePart::Store(Lines& lines, const Part& part, int pinc)
|
||||
{
|
||||
if(part.field && pinc) {
|
||||
for(int i = 0; i < part.fieldpart.GetCount(); i++)
|
||||
Store(lines, part.fieldpart[i], 0);
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
if(part.object) {
|
||||
*f++ = &part.format;
|
||||
Size sz = part.object.GetSize();
|
||||
*w++ = sz.cx;
|
||||
h->ydelta = part.object.GetYDelta();
|
||||
h->ascent = sz.cy - h->ydelta;
|
||||
h->descent = max(h->ydelta, 0);
|
||||
h->external = 0;
|
||||
h->object = &part.object;
|
||||
h++;
|
||||
*t++ = 'x';
|
||||
*p++ = pos;
|
||||
pos += pinc;
|
||||
}
|
||||
else {
|
||||
const wchar *s = part.text;
|
||||
const wchar *lim = part.text.End();
|
||||
Font fnt = part.format;
|
||||
FontInfo fi = fnt.Info();
|
||||
FontInfo wfi = fi;
|
||||
if(part.format.sscript) {
|
||||
fnt.Height(fnt.GetHeight() * 3 / 5);
|
||||
wfi = fnt.Info();
|
||||
}
|
||||
if(part.format.capitals) {
|
||||
CharFormat& cfmt = lines.hformat.Add();
|
||||
cfmt = part.format;
|
||||
cfmt.Height(cfmt.GetHeight() * 4 / 5);
|
||||
FontInfo cfi = cfmt.Info();
|
||||
FontInfo cwfi = cfi;
|
||||
if(part.format.sscript) {
|
||||
Font fnt = cfmt;
|
||||
fnt.Height(fnt.GetHeight() * 3 / 5);
|
||||
cwfi = fnt.Info();
|
||||
}
|
||||
|
||||
while(s < lim) {
|
||||
wchar c = *s++;
|
||||
if(c == 9) {
|
||||
*f++ = &part.format;
|
||||
h->ascent = pfi.GetAscent();
|
||||
h->descent = pfi.GetDescent();
|
||||
h->external = pfi.GetExternal();
|
||||
*w++ = 0;
|
||||
}
|
||||
else
|
||||
if(IsLower(c)) {
|
||||
*f++ = &cfmt;
|
||||
c = ToUpper(c);
|
||||
h->ascent = cfi.GetAscent();
|
||||
h->descent = cfi.GetDescent();
|
||||
h->external = cfi.GetExternal();
|
||||
*w++ = c >= 32 ? cwfi[c] : 0;
|
||||
}
|
||||
else {
|
||||
*f++ = &part.format;
|
||||
h->ascent = fi.GetAscent();
|
||||
h->descent = fi.GetDescent();
|
||||
h->external = fi.GetExternal();
|
||||
*w++ = c >= 32 ? wfi[c] : 0;
|
||||
}
|
||||
h->object = NULL;
|
||||
*t++ = c;
|
||||
*p++ = pos;
|
||||
pos += pinc;
|
||||
h++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(s < lim) {
|
||||
wchar c = *s++;
|
||||
*f++ = &part.format;
|
||||
if(c == 9) {
|
||||
h->ascent = pfi.GetAscent();
|
||||
h->descent = pfi.GetDescent();
|
||||
h->external = pfi.GetExternal();
|
||||
}
|
||||
else {
|
||||
h->ascent = fi.GetAscent();
|
||||
h->descent = fi.GetDescent();
|
||||
h->external = fi.GetExternal();
|
||||
}
|
||||
h->object = NULL;
|
||||
*p++ = pos;
|
||||
pos += pinc;
|
||||
h++;
|
||||
*w++ = c >= 32 ? wfi[c] : 0;
|
||||
*t++ = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int CountChars(const Array<RichPara::Part>& part)
|
||||
{
|
||||
int n = 0;
|
||||
for(int i = 0; i < part.GetCount(); i++) {
|
||||
const RichPara::Part& p = part[i];
|
||||
if(p.field)
|
||||
n += CountChars(p.fieldpart);
|
||||
else
|
||||
n += p.GetLength();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
RichPara::Lines RichPara::FormatLines(int acx) const
|
||||
{
|
||||
int i;
|
||||
Lines lines;
|
||||
lines.cx = acx;
|
||||
lines.len = GetLength();
|
||||
lines.clen = CountChars(part);
|
||||
lines.first_indent = lines.next_indent = format.indent;
|
||||
if(format.bullet == BULLET_TEXT)
|
||||
lines.first_indent = 0;
|
||||
else
|
||||
if(!format.bullet && !format.IsNumbered())
|
||||
lines.next_indent = 0;
|
||||
|
||||
FontInfo pfi = format.Info();
|
||||
if(lines.len == 0) {
|
||||
Line& l = lines.line.Add();
|
||||
l.pos = 0;
|
||||
l.ppos = 0;
|
||||
l.plen = 0;
|
||||
l.len = 0;
|
||||
l.cx = lines.first_indent;
|
||||
l.withtabs = false;
|
||||
HeightInfo dummy;
|
||||
Smh(lines, &dummy, lines.cx);
|
||||
l.ascent = pfi.GetAscent();
|
||||
l.descent = pfi.GetDescent();
|
||||
l.external = pfi.GetExternal();
|
||||
return lines;
|
||||
}
|
||||
|
||||
lines.text.Alloc(lines.clen);
|
||||
lines.width.Alloc(lines.clen);
|
||||
lines.pos.Alloc(lines.clen);
|
||||
lines.format.Alloc(lines.clen);
|
||||
lines.height.Alloc(lines.clen);
|
||||
|
||||
StorePart sp;
|
||||
sp.t = lines.text;
|
||||
sp.w = lines.width;
|
||||
sp.p = lines.pos;
|
||||
sp.f = lines.format;
|
||||
sp.h = lines.height;
|
||||
sp.pfi = pfi;
|
||||
sp.pos = 0;
|
||||
|
||||
for(i = 0; i < part.GetCount(); i++)
|
||||
sp.Store(lines, part[i], 1);
|
||||
|
||||
wchar *s = lines.text;
|
||||
wchar *text = s;
|
||||
wchar *end = lines.text + lines.clen;
|
||||
wchar *space = NULL;
|
||||
int *w = lines.width;
|
||||
int cx = lines.first_indent;
|
||||
int rcx = lines.cx - format.lm - format.rm;
|
||||
bool withtabs = false;
|
||||
int scx;
|
||||
while(s < end) {
|
||||
Tab t;
|
||||
if(*s == ' ') {
|
||||
space = s;
|
||||
scx = cx;
|
||||
}
|
||||
else {
|
||||
if(*s == '\t') {
|
||||
t = GetNextTab(cx + format.lm);
|
||||
space = NULL;
|
||||
}
|
||||
if(cx + *w > rcx && s > text || *s == '\t' && t.pos - format.lm >= rcx) {
|
||||
Line& l = lines.line.Add();
|
||||
l.withtabs = withtabs;
|
||||
l.pos = (int)(text - lines.text);
|
||||
if(space) {
|
||||
l.len = (int)(space - text) + 1;
|
||||
l.cx = scx;
|
||||
text = s = space + 1;
|
||||
}
|
||||
else {
|
||||
l.len = (int)(s - text);
|
||||
l.cx = cx;
|
||||
text = s;
|
||||
}
|
||||
Smh(lines, lines.height, lines.cx);
|
||||
cx = lines.next_indent;
|
||||
w = text - ~lines.text + lines.width;
|
||||
space = NULL;
|
||||
rcx = lines.cx - format.lm - format.rm;
|
||||
withtabs = false;
|
||||
t = GetNextTab(cx + format.lm);
|
||||
}
|
||||
}
|
||||
if(*s == '\t') {
|
||||
*s += t.fillchar;
|
||||
if(t.align == ALIGN_LEFT) {
|
||||
*w++ = t.pos - format.lm - cx;
|
||||
cx = t.pos - format.lm;
|
||||
}
|
||||
else {
|
||||
int tcx = 0;
|
||||
int *tw = w + 1;
|
||||
for(wchar *ts = s + 1; ts < end && *ts != '\t'; ts++)
|
||||
tcx += *tw++;
|
||||
int ww = t.pos - format.lm - cx - (t.align == ALIGN_RIGHT ? tcx : tcx / 2);
|
||||
if(ww > 0) {
|
||||
*w++ = ww;
|
||||
cx += ww;
|
||||
}
|
||||
else
|
||||
*w++ = 0;
|
||||
}
|
||||
withtabs = true;
|
||||
}
|
||||
else
|
||||
cx += *w++;
|
||||
s++;
|
||||
}
|
||||
Line& l = lines.line.Add();
|
||||
l.withtabs = withtabs;
|
||||
l.pos = (int)(text - lines.text);
|
||||
l.len = (int)(s - text);
|
||||
l.cx = cx;
|
||||
Smh(lines, lines.height, lines.cx);
|
||||
for(i = 0; i < lines.line.GetCount(); i++) {
|
||||
Line& l = lines.line[i];
|
||||
l.ppos = lines.pos[l.pos];
|
||||
l.plen = (l.pos + l.len < lines.clen ? lines.pos[l.pos + l.len] : lines.len) - l.ppos;
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
void RichPara::Lines::Justify(const RichPara::Format& format)
|
||||
{
|
||||
if(format.align != ALIGN_JUSTIFY) return;
|
||||
for(int i = 0; i < line.GetCount() - 1; i++) {
|
||||
const Line& li = line[i];
|
||||
if(!li.withtabs && li.len) {
|
||||
const wchar *s = ~text + li.pos;
|
||||
const wchar *lim = s + li.len;
|
||||
while(lim - 1 > s) {
|
||||
if(*(lim - 1) != ' ') break;
|
||||
lim--;
|
||||
}
|
||||
while(s < lim) {
|
||||
if(*s != ' ' && *s != 160) break;
|
||||
s++;
|
||||
}
|
||||
|
||||
const wchar *beg = s;
|
||||
int nspc = 0;
|
||||
while(s < lim) {
|
||||
if(*s == ' ' || *s == 160) nspc++;
|
||||
s++;
|
||||
}
|
||||
s = beg;
|
||||
if(nspc) {
|
||||
int q = ((cx - format.lm - format.rm -
|
||||
(i == 0 ? first_indent : next_indent) - li.cx) << 16)
|
||||
/ nspc;
|
||||
int *w = beg - ~text + width;
|
||||
int prec = 0;
|
||||
while(s < lim) {
|
||||
if(*s == ' ' || *s == 160) {
|
||||
*w += (prec + q) >> 16;
|
||||
prec = (prec + q) & 0xffff;
|
||||
}
|
||||
w++;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RichPara::Lines::BodyHeight()
|
||||
{
|
||||
int sum = 0;
|
||||
for(int i = 0; i < line.GetCount(); i++)
|
||||
sum += line[i].Sum();
|
||||
return sum;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
Loading…
Add table
Add a link
Reference in a new issue