mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-23 22:03:07 -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
263
uppsrc/DocTypes/QtfEncoder.cpp
Normal file
263
uppsrc/DocTypes/QtfEncoder.cpp
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#include "DocTypes.h"
|
||||
|
||||
NAMESPACE_UPP
|
||||
|
||||
static Color DocQTFColor[] = {
|
||||
Black, LtGray, White, Red, Green, Blue, LtRed, WhiteGray, LtCyan, Yellow
|
||||
};
|
||||
|
||||
static int DocQTFFontHeight[] = {
|
||||
50, 67, 84, 100, 134, 167, 200, 234, 300, 400
|
||||
};
|
||||
|
||||
static void SeparateNumber(String& s)
|
||||
{
|
||||
if(*s.Last() >= '0' && *s.Last() <= '9')
|
||||
s.Cat(';');
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct RichObjectTypeDrawingData
|
||||
{
|
||||
void Serialize(Stream& stream);
|
||||
|
||||
Drawing drawing;
|
||||
Size dot_size;
|
||||
String comment;
|
||||
};
|
||||
|
||||
void RichObjectTypeDrawingData::Serialize(Stream& stream)
|
||||
{
|
||||
int version = 1;
|
||||
stream % version % dot_size % comment % drawing;
|
||||
}
|
||||
|
||||
static String RichObjectTypeDrawingTypeName()
|
||||
{
|
||||
return "Drawing";
|
||||
|
||||
}
|
||||
|
||||
static String FmtColor(Color c)
|
||||
{
|
||||
if(IsNull(c)) return "N";
|
||||
for(int i = 0; i < 10; i++)
|
||||
if(DocQTFColor[i] == c)
|
||||
return String(i + '0', 1);
|
||||
return NFormat("(%d.%d.%d)", c.GetR(), c.GetG(), c.GetB());
|
||||
}
|
||||
|
||||
String CharFmt(const Paragraph::Part& a, const Paragraph::Part& b)
|
||||
{
|
||||
String fmt;
|
||||
if(a.font.IsBold() != b.font.IsBold()) fmt.Cat('*');
|
||||
if(a.font.IsItalic() != b.font.IsItalic()) fmt.Cat('/');
|
||||
if(a.font.IsUnderline() != b.font.IsUnderline()) fmt.Cat('_');
|
||||
if(a.font.IsStrikeout() != b.font.IsStrikeout()) fmt.Cat('-');
|
||||
// if(a.capitals != b.capitals) fmt.Cat('c');
|
||||
if(a.delta != b.delta)
|
||||
fmt.Cat(b.delta == 0 ? a.delta < 0 ? '`' : ',' :
|
||||
b.delta < 0 ? '`' : ',');
|
||||
if(a.font.GetFace() != b.font.GetFace())
|
||||
switch(b.font.GetFace()) {
|
||||
case Font::ARIAL: fmt.Cat('A'); break;
|
||||
case Font::ROMAN: fmt.Cat('R'); break;
|
||||
case Font::COURIER: fmt.Cat('C'); break;
|
||||
case Font::STDFONT: fmt.Cat('G'); break;
|
||||
case Font::SYMBOL: fmt.Cat('S'); break;
|
||||
default:
|
||||
fmt << "!" << a.font.GetFaceName() << "!";
|
||||
}
|
||||
if(a.value != b.value)
|
||||
fmt << '^' << DeQtf(StdFormat(b.value)) << '^';
|
||||
if(a.color != b.color)
|
||||
fmt << "@" << FmtColor(b.color);
|
||||
if(a.font.GetHeight() != b.font.GetHeight()) {
|
||||
for(int i = 0; i < 10; i++)
|
||||
if(b.font.GetHeight() == DocQTFFontHeight[i]) {
|
||||
SeparateNumber(fmt);
|
||||
fmt.Cat('0' + i);
|
||||
return fmt;
|
||||
}
|
||||
fmt.Cat(NFormat("+%d", tabs(b.font.GetHeight())));
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
static String sFmtNumber(char c, int former, int current)
|
||||
{
|
||||
return former != current ? NFormat("%c%d", c, current) : String();
|
||||
}
|
||||
|
||||
String QTFEncodeParaFormat(const Paragraph::Style& format, const Paragraph::Part& charformat,
|
||||
const Paragraph::Style& style, const Paragraph::Part& charstyle,
|
||||
bool savecharformat)
|
||||
{
|
||||
String qtf;
|
||||
if(format.align != style.align)
|
||||
switch(format.align) {
|
||||
case ALIGN_LEFT: qtf << '<'; break;
|
||||
case ALIGN_RIGHT: qtf << '>'; break;
|
||||
case ALIGN_CENTER: qtf << '='; break;
|
||||
case ALIGN_JUSTIFY: qtf << '#'; break;
|
||||
}
|
||||
qtf << sFmtNumber('l', style.lm, format.lm)
|
||||
<< sFmtNumber('r', style.rm, format.rm)
|
||||
<< sFmtNumber('i', style.indent, format.indent)
|
||||
<< sFmtNumber('b', style.before, format.before)
|
||||
<< sFmtNumber('a', style.after, format.after);
|
||||
if(style.bullet != format.bullet) {
|
||||
qtf << 'O';
|
||||
qtf << (format.bullet ? "0" : "_");
|
||||
}
|
||||
if(savecharformat)
|
||||
qtf << CharFmt(charstyle, charformat);
|
||||
qtf << " ";
|
||||
return qtf;
|
||||
}
|
||||
|
||||
String QTFEncodePara(const Paragraph& p,
|
||||
const Paragraph::Style& style, const Paragraph::Part& charstyle)
|
||||
{
|
||||
Paragraph::Part paraformat;
|
||||
paraformat.font = p.GetParaFont();
|
||||
String qtf = QTFEncodeParaFormat(p.GetStyle(), paraformat, style, charstyle,
|
||||
p.GetCount() == 0);
|
||||
int d = qtf.GetLength();
|
||||
for(int i = 0; i < p.GetCount(); i++) {
|
||||
const Paragraph::Part& part = p.GetParts()[i];
|
||||
if(part.pr) {
|
||||
// const RichObject& object = part.object;
|
||||
Size sz = part.sz;
|
||||
qtf << "\r\n";
|
||||
qtf << "@@" << RichObjectTypeDrawingTypeName() << ':' << sz.cx
|
||||
<< '*' << sz.cy << "\r\n";
|
||||
DrawingDraw ddraw(sz);
|
||||
part.pr.Paint(ddraw, sz, Black, White, 0);
|
||||
RichObjectTypeDrawingData dwg;
|
||||
dwg.drawing = ddraw;
|
||||
dwg.dot_size = sz;
|
||||
StringStream datastrm;
|
||||
datastrm % dwg;
|
||||
String data = datastrm;
|
||||
const char *q = data.Begin();
|
||||
const char *slim = data.End();
|
||||
int n = 0;
|
||||
qtf.Reserve(qtf.GetLength() + 8 * data.GetLength() / 7);
|
||||
while(q < slim - 7) {
|
||||
byte seven = 0;
|
||||
byte data[8];
|
||||
data[0] = ((q[0] & 0x80) >> 7) |
|
||||
((q[1] & 0x80) >> 6) |
|
||||
((q[2] & 0x80) >> 5) |
|
||||
((q[3] & 0x80) >> 4) |
|
||||
((q[4] & 0x80) >> 3) |
|
||||
((q[5] & 0x80) >> 2) |
|
||||
((q[6] & 0x80) >> 1) |
|
||||
0x80;
|
||||
data[1] = q[0] | 0x80;
|
||||
data[2] = q[1] | 0x80;
|
||||
data[3] = q[2] | 0x80;
|
||||
data[4] = q[3] | 0x80;
|
||||
data[5] = q[4] | 0x80;
|
||||
data[6] = q[5] | 0x80;
|
||||
data[7] = q[6] | 0x80;
|
||||
qtf.Cat(data, 8);
|
||||
if(++n % 10 == 0)
|
||||
qtf << "\r\n";
|
||||
q += 7;
|
||||
}
|
||||
while(q < slim) {
|
||||
byte seven = 0;
|
||||
const char *lim = slim;
|
||||
const char *s;
|
||||
for(s = q; s < lim; s++)
|
||||
seven = (seven >> 1) | (*s & 0x80);
|
||||
seven >>= 8 - (lim - q);
|
||||
qtf.Cat(seven | 0x80);
|
||||
for(s = q; s < lim; s++)
|
||||
qtf.Cat(*s | 0x80);
|
||||
if(++n % 10 == 0)
|
||||
qtf << "\r\n";
|
||||
q += 7;
|
||||
}
|
||||
}
|
||||
else {
|
||||
String cf = CharFmt(charstyle, part);
|
||||
if(!cf.IsEmpty()) {
|
||||
qtf << '[' << cf << ' ';
|
||||
d += cf.GetLength() + 2;
|
||||
}
|
||||
for(const char *s = part.text.Begin(); s != part.text.End(); s++) {
|
||||
byte c = *s;
|
||||
if(c < 128) {
|
||||
if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'
|
||||
|| c == ' ' || c == '.' || c == ',' || c == '?' || c == '(' || c == ')'
|
||||
|| c == ';')
|
||||
{
|
||||
qtf.Cat(c);
|
||||
d++;
|
||||
}
|
||||
else if(c == 9)
|
||||
{
|
||||
qtf.Cat(127);
|
||||
d++;
|
||||
}
|
||||
else if(c == 31)
|
||||
{
|
||||
qtf.Cat('_');
|
||||
d++;
|
||||
}
|
||||
else
|
||||
{
|
||||
qtf.Cat('`');
|
||||
qtf.Cat(c);
|
||||
d += 2;
|
||||
}
|
||||
if(d > 60 && c == ' ')
|
||||
{
|
||||
qtf.Cat("\r\n");
|
||||
d = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qtf.Cat(c);
|
||||
d++;
|
||||
}
|
||||
if(d > 80)
|
||||
{
|
||||
qtf.Cat("\r\n");
|
||||
d = 0;
|
||||
}
|
||||
}
|
||||
if(!cf.IsEmpty()) {
|
||||
d++;
|
||||
qtf << ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
return qtf;
|
||||
}
|
||||
|
||||
String AsQtf(const Document& text)
|
||||
{
|
||||
Paragraph::Style empty_format;
|
||||
empty_format.Init();
|
||||
Paragraph::Part empty_part;
|
||||
String qtf;
|
||||
// qtf << "[";
|
||||
for(int i = 0; i < text.GetCount(); i++)
|
||||
if(text.IsParagraph(i)) {
|
||||
const Paragraph& p = text.GetParagraph(i);
|
||||
if(i) qtf << "\r\n&\r\n";
|
||||
qtf << "[";
|
||||
qtf << QTFEncodePara(p, empty_format, empty_part);
|
||||
qtf << "]";
|
||||
}
|
||||
qtf << "\r\n"; // ]";
|
||||
return qtf;
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
Loading…
Add table
Add a link
Reference in a new issue