Ejemplo n.º 1
0
Report& InvoiceFormatter::formatFullInvoice(InvoiceData& invoice) {
	output.Clear();

	output.Header(String("[A0> ") + String(t_("Page")) + String(" $$P]"));
	
	StringBuffer buf;
	
	buf.Cat("{{1f4 ");
	formatHeader(buf, invoice);
	buf.Cat(":: ");
	formatCompanyData(buf);
	buf.Cat(":: ");
	formatClientData(buf, invoice);
	buf.Cat(":: ");
	formatPatientData(buf, invoice);
	buf.Cat(":: ");
	formatInvoiceItems(buf, invoice);
	buf.Cat("}}");

	if (!AsString(invoice.payed_date).IsEmpty() && lang != LANG_CZ)
	{
		buf.Cat("&&&&");
		buf.Cat("{{1f4 ");
		formatBillHeader(buf, invoice, false);
		buf.Cat(":: ");
		formatBillPrice(buf, invoice);
		buf.Cat("}}");
	}

	output << ~buf;

	return output;
}
Ejemplo n.º 2
0
void XmlParser::Ent(StringBuffer& out)
{
	int outconst = 0;
	const char *t = ++term;
	if(*t == '#') {
		if(*++t == 'X' || *t == 'x') {
			for(byte c; (c = ctoi(*++t)) < 16; outconst = 16 * outconst + c)
				;
		}
		else {
			while(IsDigit(*t))
				outconst = 10 * outconst + *t++ - '0';
		}
		out.Cat(ToUtf8(outconst));
		if(*t == ';')
			t++;
		term = t;
		return;
	}
	const char *b = t;
	while(*t && *t != ';')
		t++;
	if(*t == ';') {
		int q = entity.Find(String(b, t));
		if(q >= 0) {
			out.Cat(entity[q]);
			term = t + 1;
			return;
		}
	}
	out.Cat('&');
}
Ejemplo n.º 3
0
String PackImlData(const Vector<Image>& image)
{
    StringBuffer block;
    for(int i = 0; i < image.GetCount(); i++) {
        const Image& img = image[i];
        StringStream ss;
        ss.Put(img.GetResolution() << 6);
        Size sz = img.GetSize();
        ss.Put16le(sz.cx);
        ss.Put16le(sz.cy);
        Point p = img.GetHotSpot();
        ss.Put16le(p.x);
        ss.Put16le(p.y);
        p = img.Get2ndSpot();
        ss.Put16le(p.x);
        ss.Put16le(p.y);
        block.Cat(ss.GetResult());
        const RGBA *s = img;
        const RGBA *e = s + img.GetLength();
        while(s < e) {
            block.Cat(s->r);
            block.Cat(s->g);
            block.Cat(s->b);
            block.Cat(s->a);
            s++;
        }
    }
    return ZCompress(block);
}
Ejemplo n.º 4
0
void InvoiceFormatter::formatPatientData(StringBuffer &buf, InvoiceData &invoice) {
	buf.Cat("[*A1 " + AsString(t_("Patient:")) + "] [A1 " 
		+ invoice.patient_name + ", " + invoice.patient_species);
	if (!invoice.patient_breed.IsEmpty())
		buf.Cat(" (" + invoice.patient_breed + ")");
	buf.Cat("&]");
	buf.Cat("[A1 " + escapeText(invoice.rec_text) + "] ");
}
Ejemplo n.º 5
0
String InvoiceFormatter::escapeText(String& s) {
	StringBuffer out;
	
	out.Cat("\1");
	out.Cat(s);
	out.Cat("\1");
	
	return ~out;
}
Ejemplo n.º 6
0
String RandomString(int len)
{
	StringBuffer r;
	for(int i = 0; i < len; i++)
		if(Random(30) == 0)
			r.Cat("\r\n");
		else
			r.Cat(Random(64) + 32);
	return r;
}
Ejemplo n.º 7
0
void InvoiceFormatter::formatHeader(StringBuffer &buf, InvoiceData &invoice) {
	buf.Cat("{{1:1~ ");
	buf.Cat("[*A3 " + AsString(t_("Invoice")) + "] :: [*A3 " + AsString(t_("invoice num:")) + " " + AsString(invoice.inv_id) + "]:: ");
	buf.Cat("[A1 " + AsString(t_("Create date:")) + "-|-|-|" + AsString(invoice.create_date));
	if (lang != LANG_CZ) {
		buf.Cat("&" + AsString(t_("Delivery date:")) + "-|-|" + AsString(invoice.delivery_date) + "&");
		buf.Cat(AsString(t_("Payment date:")) + "-|-|-|" + AsString(invoice.payment_date) );
	}
	buf.Cat("]:: ");
	
	// no payment type in CZ
	if (lang != LANG_CZ) {
		String type;
		switch (invoice.payment_type)
		{
				case iptCurrency:
					type = t_("currency");
					break;
				case iptBankTransfer:
					type = t_("bank transfer");
					break;
				
				default:
					type = t_("currency");
		}
		
		buf.Cat("[A1 " + AsString(t_("Payment type:")) + "-|-|" + type + "]&");
	}
	buf.Cat("}}");
}
Ejemplo n.º 8
0
void InvoiceFormatter::formatVetData(StringBuffer &buf) {
	buf.Cat("[*A1 " + AsString(t_("Doctor:")) + "&]");
	buf.Cat("[A1 {{1:1~ ");
	buf.Cat("[A1 " + vet_name + "&" + vet_address);
	buf.Cat("&" + AsString(t_("pho.")) + " 1:-|" + vet_phone1 + "&" + AsString(t_("pho.")) + " 2:-|" + vet_phone2 +"]:: ");
	buf.Cat("[A1 " + AsString(t_("IC:")) + "-|-|-|" + vet_ic + "&" + AsString(t_("DIC:")) + "-|-|-|" );
	buf.Cat( vet_dic + "&");
	if (lang != LANG_CZ)
		buf.Cat(AsString(t_("ICDPH:")) + "-|-|-|" + vet_icdph + "&");
	buf.Cat(AsString(t_("Bank account:")) + "-|" + vet_bank_acc +"] ");
	buf.Cat("}}] ");
}
Ejemplo n.º 9
0
void InvoiceList::formatCompanyData(StringBuffer &buf)
{
	buf.Cat("[*A1 " + AsString(t_("Supplier:")) + "&]");
	buf.Cat("[A1 {{1:1~ ");
	buf.Cat("[A1 " + AsString(~inv_data.name) + "&" + AsString(~inv_data.address));
	buf.Cat("&" + AsString(t_("pho.")) + " 1:-|" + AsString(~inv_data.phone1) + "&" + AsString(t_("pho.")) + " 2:-|" + AsString(~inv_data.phone2) +"]:: ");
	buf.Cat("[A1 " + AsString(t_("IC:")) + "-|-|-|" + AsString(~inv_data.ic) + "&" + AsString(t_("DIC:")) + "-|-|-|" );
	buf.Cat( AsString(~inv_data.dic) + "&");
	if (lang != LANG_CZ)
		buf.Cat(AsString(t_("ICDPH:")) + "-|-|-|" + AsString(~inv_data.icdph) + "&");
	buf.Cat(AsString(t_("Bank account:")) + "-|-|" + AsString(~inv_data.acc_num) +"] ");
	buf.Cat("}}] ");
}
Ejemplo n.º 10
0
bool InvoiceList::prepare()
{
	String sqlStatement = "select r.invoice_id, r.inv_create_date, \
					(select sum(ri.item_price) from record_item ri where ri.record_id = r.id) \
					from record r \
					where r.invoice_id is not null and r.inv_create_date between '"
					 + AsString(from) + "' and '" + AsString(to) 
					 + "' order by r.inv_create_date, r.invoice_id";
	SQL.Execute(sqlStatement);
	
	bool found = false;
	while (SQL.Fetch()) {
		found = true;
		
		VectorMap<int, String> vmap;
		vmap.Add(iliInvNum, AsString(SQL[0]));
		vmap.Add(iliDate, AsString(SQL[1]));
		vmap.Add(iliTotal, fixFuckedLinuxFormating(ConvertMoney().Format(SQL[2])));
		inv_list_items.Add(vmap);
	}
	if (!found) return false;
	
	SQL & Select(SqlSum(ITEM_PRICE.Of(RECORD_ITEM))).From(RECORD_ITEM)
		.InnerJoin(RECORD).On(RECORD_ID.Of(RECORD_ITEM) == ID.Of(RECORD))
		.Where(NotNull(INVOICE_ID.Of(RECORD)) && (Between(INV_CREATE_DATE.Of(RECORD), from, to)));
	if (SQL.Fetch())
		summary_price = SQL[0];	
	
	invoiceList.Clear();
	invoiceList.Header(String("[A0> ") + String(t_("Page")) + String(" $$P"));
	
	StringBuffer buf;
	
	buf.Cat("{{1f4 ");
	formatHeader(buf);
	buf.Cat(":: ");
	formatCompanyData(buf);
	buf.Cat(":: ");
	formatItems(buf);
	buf.Cat("}}");
	
	LOG(~buf);
	invoiceList << ~buf;

	return true;
}
Ejemplo n.º 11
0
void EscapeHtml(StringBuffer& out, const String& txt)
{
	const char *s = txt;
	const char *e = txt.End();
	while(s != e) {
		if(*s == 31)
			out.Cat("&nbsp;");
		else
		if(*s == '<')
			out.Cat("&lt;");
		else
		if(*s == '>')
			out.Cat("&gt;");
		else
		if(*s == '&')
			out.Cat("&amp;");
		else
		if(*s == '\"')
			out.Cat("&quot;");
		else
		if((byte)*s < ' ')
			out.Cat(NFormat("&#%d;", (byte)*s));
		else
			out.Cat(*s);
		s++;
	}
}
Ejemplo n.º 12
0
// Fix "space" charactes after 1000 in slovak locale. They weren't printable by default
String  fixFuckedLinuxFormating(const String &s) {
	StringBuffer out;
	
	#ifdef PLATFORM_LINUX
	for (int i=0; i<s.GetCount(); i++)
		out.Cat((s[i] == -96) ? ' ' : s[i]);
	#endif
	
	#ifdef PLATFORM_WIN32
	for (int i=0; i<s.GetCount(); i++)
	{
		if (s[i] != -62)
			out.Cat((s[i] == -96) ? ' ' : s[i]);
	}
	#endif
	
	return ~out;
}
Ejemplo n.º 13
0
WString VfkStream::ReadString(const char *b, const char **endptr) const
{
	if(*b++ != '\"')
		throw Exc("'\"' expected");
	StringBuffer out;
	for(;;) {
		const char *b0 = b;
		while(*b && *b != '\"')
			b++;
		out.Cat(b0, b - b0);
		if(*b != '\"' || *++b != '\"')
			break;
		out.Cat(*b++);
	}
	if(endptr)
		*endptr = b;
	return ToUnicode((String)out, charset);
}
Ejemplo n.º 14
0
String  XmlTag::operator()(const char *text)
{
	StringBuffer r;
	r << tag << ">";
	int fbi = r.GetCount();
	const char *s = text;
	bool wastag = true;
	bool wasslash = true;
	bool first = true;
	while(*s) {
		const char *b = s;
		while(*s == ' ' || *s == '\t')
			s++;
		if(s[0] == '<') {
			if(first)
				r << "\r\n";
			if(wastag && (wasslash || s[1] != '/'))
				r.Cat('\t');
		}
		else
		if(first) {
			r << text << end;
			return r;
		}
		first = false;
		wasslash = false;
		char last = 0;
		while(*s && *s != '\n' && *s != '\r') {
			if(*s == '<')
				wasslash = s[1] == '/';
			if(*s == '/' && s[1] == '>')
				wasslash = true;
			last = *s++;
		}
		wastag = last == '>';
		if(*s == '\r')
			s++;
		if(*s == '\n')
			s++;
		r.Cat(b, s);
	}
	r << "\r\n" << end;
	return r;
}
Ejemplo n.º 15
0
Report& InvoiceFormatter::formatBill(InvoiceData& invoice) {
	output.Clear();
	
	output.Header(String("[A0> ") + String(t_("Page")) + String(" $$P]"));
	
	StringBuffer buf;
	buf.Cat("{{1f4 ");
	formatBillHeader(buf, invoice);
	buf.Cat(":: ");
	formatCompanyData(buf);
	buf.Cat(":: ");
	formatClientData(buf, invoice);
	buf.Cat(":: ");
	formatBillPrice(buf, invoice);
	buf.Cat("}}");
	
	output << ~buf;
	
	return output;
}
Ejemplo n.º 16
0
String NaturalDeQtf(const char *s) {
	StringBuffer r;
	r.Reserve(256);
	bool cm = false;
	while(*s) {
		if(*s == ' ')
			r.Cat(cm ? ' ' : '_');
		else {
			if((byte)*s > ' ' && !IsDigit(*s) && !IsAlpha(*s) && (byte)*s < 128)
				r.Cat('`');
			r.Cat(*s);
			if(*s == ',')
				cm = true;
			else
				cm = false;
		}
		s++;
	}
	return r;
}
Ejemplo n.º 17
0
void InvoiceFormatter::formatBillHeader(StringBuffer &buf, InvoiceData &invoice, bool isStandelone) {
	if (isStandelone)
		buf.Cat("[*A3 " + AsString(t_("Receipt")) + "&]");
	else
		buf.Cat("[*A2 " + AsString(t_("Receipt")) + "&]");
	buf.Cat("[A1 " + AsString(t_("Payment of the invoice:")) +  " ");
	buf.Cat(AsString(invoice.inv_id));
	buf.Cat("&&" + AsString(t_("Payed date:")) + " ");
	buf.Cat(AsString(invoice.payed_date));
	buf.Cat("] ");
}
Ejemplo n.º 18
0
Topic ReadTopic0(const char *text)
{
	Topic topic;
	CParser p(text);
	try {
		if(p.Id("topic")) {
			topic.title = p.ReadString();
			p.Char(';');
			topic.text = p.GetPtr();
			return topic;
		}
		while(!p.IsEof()) {
			if(p.Id("TITLE")) {
				p.PassChar('(');
				topic.title = p.ReadString();
				p.PassChar(')');
			}
			else
			if(p.Id("REF")) {
				p.PassChar('(');
				p.ReadString();
				p.PassChar(')');
			}
			else
			if(p.Id("TOPIC_TEXT")) {
				p.PassChar('(');
				topic.text << p.ReadString();
				p.PassChar(')');
			}
			else
			if(p.Id("COMPRESSED")) {
				StringBuffer b;
				b.Reserve(1024);
				while(p.IsInt()) {
					b.Cat(p.ReadInt());
					p.PassChar(',');
				}
				topic.text = b;
			}
			else {
				topic.text << p.GetPtr();
				break;
			}
		}
	}
	catch(CParser::Error e) {
		topic.text = String::GetVoid();
		topic.title = e;
	}
	return topic;
}
Ejemplo n.º 19
0
void InvoiceList::formatHeader(StringBuffer &buf)
{
	buf.Cat("{{1:1~ ");
	buf.Cat("[*A3 " + AsString(t_("Invoice list")) + "] :: [*A3 ]:: ");
	buf.Cat("[A1 " + AsString(t_("Date from:")) + "-|" + AsString(from));
	buf.Cat("&" + AsString(t_("Date to:")) + "-|" + AsString(to));
	buf.Cat("]:: ");
	buf.Cat("}}");
}
Ejemplo n.º 20
0
String XmlParser::ReadTextE()
{
	StringBuffer out;
	for(;;) {
		String t = ReadText();
		if(!IsNull(t))
			out.Cat(t);
		else if(IsEnd()) {
			PassEnd();
			return out;
		}
		else
			Skip();
	}
}
Ejemplo n.º 21
0
void XmlParser::ReadAttr(StringBuffer& attrval, int c)
{
	term++;
	while(*term && *term != c)
		if(*term == '&')
			Ent(attrval);
		else {
			const char *e = term;
			while(*++e && *e != '&' && *e != c)
				;
			attrval.Cat(term, (int)(e - term));
			term = e;
		}
	if(*term == c)
		term++;
}
Ejemplo n.º 22
0
void TestBufferCat()
{
	typedef TStr<tchar> String;
	for(int n = 0; n < 2000; n++) {
		StringBuffer *b = new StringBuffer;
		String ss;
		for(int x = 0; x < n; x++) {
			int c = rand();
			b->Cat(c);
			ss.Cat(c);
			b->Begin();
		}
		NewString ns = *b;
//		LOGHEXDUMP(ns.Begin(), ns.GetCount());
//		LOGHEXDUMP(ss.Begin(), ss.GetCount());
		ASSERT(ss.GetLength() == ns.GetLength());
		ASSERT(memcmp(ns.Begin(), ss.Begin(), sizeof(tchar) * ns.GetCount() + 1) == 0);
		delete b;
	}
}
Ejemplo n.º 23
0
NAMESPACE_UPP

#define LLOG(x) // LOG(x);

static inline void sDeXmlChar(StringBuffer& result, char chr, byte charset, bool escapelf)
{
	/**/ if(chr == '<')  result.Cat("&lt;");
	else if(chr == '>')  result.Cat("&gt;");
	else if(chr == '&')  result.Cat("&amp;");
	else if(chr == '\'') result.Cat("&apos;");
	else if(chr == '\"') result.Cat("&quot;");
	else if((byte)chr < ' ' && (escapelf || chr != '\n' && chr != '\t' && chr != '\r'))
		result.Cat(NFormat("&#x%02x;", (byte)chr));
	else if(!(chr & 0x80) || charset == CHARSET_UTF8) result.Cat(chr);
	else result.Cat(ToUtf8(ToUnicode(chr, charset)));
}
Ejemplo n.º 24
0
	virtual bool operator()(int pos, const RichPara& para)// A++ bug here....
	{
		if(!IsNull(para.format.label)) {
			AddLinkRef(link, para.format.label);
			ref.FindAdd(para.format.label);
		}
		for(int i = 0; i < para.part.GetCount(); i++)
			if(para.part[i].IsText()) {
				const wchar *s = para.part[i].text;
				for(;;) {
					while(!IsLetter(*s) && !IsDigit(*s) && *s)
						s++;
					if(*s == '\0')
						break;
					StringBuffer sb;
					while(IsLetter(*s) || IsDigit(*s))
						sb.Cat(ToAscii(ToLower(*s++)));
					words.FindAdd(TopicWordIndex(sb));
				}
			}
		return false;
	}
Ejemplo n.º 25
0
force_inline
static void sCatAsString(StringBuffer& out, const Value& v)
{
	LTIMING("sCatAsString");
	if(IsNull(v))
		return;
	if(v.Is<RawHtmlText>()) {
		LTIMING("Cat RawHtml");
		out.Cat(ValueTo<RawHtmlText>(v).text);
	}
	else {
		String h;
		if(v.Is<String>())
			h = ValueTo<String>(v);
		else {
			LTIMING("AsString");
			h = AsString(v);
		}
		LTIMING("Escape html");
		EscapeHtml(out, h);
	}
}
Ejemplo n.º 26
0
String PackRLE(const RGBA *s, int len)
{
	StringBuffer r;
	const RGBA *e = s + len;
	while(s < e) {
		const RGBA *q = s;
		if(s->a == 0) {
			s++;
			while(s < e && s->a == 0 && s - q < 0x3f)
				s++;
			r.Cat((0x80|0x40) + (int)(s - q));
		}
		else
		if(s + 1 < e && s[0] == s[1]) {
			s++;
			while(s + 1 < e && s[0] == s[1] && s - q < 0x3e)
				s++;
			s++;
			r.Cat(0x80 + (int)(s - q));
			r.Cat(q->b);
			r.Cat(q->g);
			r.Cat(q->r);
		}
		else {
			s++;
			while(s + 1 < e && s->a && s[0] != s[1] && s - q < 0x3f)
				s++;
			r.Cat((int)(s - q));
			while(q < s) {
				r.Cat(q->b);
				r.Cat(q->g);
				r.Cat(q->r);
				q++;
			}
		}
	}
	return r;
}
Ejemplo n.º 27
0
void InvoiceFormatter::formatBillPrice(StringBuffer &buf, InvoiceData &invoice)
{
	buf.Cat("[*A1 " + AsString(t_("Amount payed:")) + " -|-|");
	buf.Cat(fixFuckedLinuxFormating(ConvertMoney().Format(invoice.summary_price)));
	buf.Cat(" " + AsString(t_("CUR")) + "]&");
	buf.Cat("[A1 " + AsString(t_("Amount in words:")) + " ");
	
	String xxx = AsString(invoice.summary_price);
	int idx = xxx.Find('.');
	int d;
	String s = xxx;
	if (idx > 0)
		s = xxx.Left(idx);
	sscanf(~s, "%d", &d);
	
	NumberToTextConverter *converter = new SlovakNumberToTextConverter();
	buf.Cat(converter->convert(d));
	delete ((SlovakNumberToTextConverter *)converter);
	
	buf.Cat(" " + AsString(t_("CUR")) + "] ");
}
Ejemplo n.º 28
0
Report& InvoiceFormatter::formatRecord(InvoiceData& invoice) {
	output.Clear();
	
	output.Header(String("[A0> ") + String(t_("Page")) + String(" $$P]"));
	
	StringBuffer buf;
	buf.Cat("{{1f4 ");
	formatRecordHeader(buf, invoice);
	buf.Cat(":: ");
	formatVetData(buf);
	buf.Cat(":: ");
	formatOwnerData(buf, invoice);
	buf.Cat(":: ");
	formatPatientData(buf, invoice);
	buf.Cat(":: ");
	formatRecordItems(buf, invoice);
	buf.Cat("}}");
	
	output << ~buf;
	
	return output;
}
Ejemplo n.º 29
0
void RichQtfParser::ReadObject()
{
	Flush();
	RichObject obj;
	if(*term == '#') {
		term++;
	#ifdef CPU_64
		obj = *(RichObject *)stou64(term, &term);
	#else
		obj = *(RichObject *)stou(term, &term);
	#endif
		term++;
	}
	else {
		String type;
		while(IsAlNum(*term) || *term == '_')
			type.Cat(*term++);
		Size sz;
		Key(':');
		sz.cx = ReadNumber();
		bool keepratio = false;
		if(Key('&'))
			keepratio = true;
		else
			Key('*');
		sz.cy = ReadNumber();
		int yd = 0;
		if(Key('/'))
			yd = GetNumber();
		while(*term && (byte)*term < 32)
			term++;
		String odata;
		if(Key('`'))
			while(*term) {
				if(*term == '`') {
					term++;
					if(*term == '`')
						odata.Cat('`');
					else
						break;
				}
				else
				if((byte)*term >= 32)
					odata.Cat(*term);
				term++;
			}
		else
		if(Key('(')) {
			const char *b = term;
			while(*term && *term != ')')
				term++;
			odata = Base64Decode(b, term);
			if(*term == ')')
				term++;
		}
		else {
			StringBuffer data;
			for(;;) {
				while(*term < 32 && *term > 0) term++;
				if((byte)*term >= ' ' && (byte)*term <= 127 || *term == '\0') break;
				byte seven = *term++;
				for(int i = 0; i < 7; i++) {
					while((byte)*term < 32 && (byte)*term > 0) term++;
					if((byte)*term >= ' ' && (byte)*term <= 127 || *term == '\0') break;
					data.Cat((*term++ & 0x7f) | ((seven << 7) & 0x80));
					seven >>= 1;
				}
			}
			odata = data;
		}
		obj.Read(type, odata, sz, context);
		obj.KeepRatio(keepratio);
		obj.SetYDelta(yd);
	}
	paragraph.Cat(obj, format);
}
Ejemplo n.º 30
0
void RichPara::UnpackParts(Stream& in, const RichPara::CharFormat& chrstyle,
                           Array<RichPara::Part>& part, const Array<RichObject>& obj,
                           int& oi) {
	part.Add();
	part.Top().format = format;
	int c;
	while((c = in.Term()) >= 0)
		if(c < 31 && c != 9 && c != FIELD) {
			do
				switch(in.Get()) {
				case BOLD0:
					format.NoBold();
					break;
				case BOLD1:
					format.Bold();
					break;
				case BOLDS:
					format.Bold(chrstyle.IsBold());
					break;
				case ITALIC0:
					format.NoItalic();
					break;
				case ITALIC1:
					format.Italic();
					break;
				case ITALICS:
					format.Italic(chrstyle.IsItalic());
					break;
				case UNDERLINE0:
					format.NoUnderline();
					break;
				case UNDERLINE1:
					format.Underline();
					break;
				case UNDERLINES:
					format.Underline(chrstyle.IsUnderline());
					break;
				case STRIKEOUT0:
					format.NoStrikeout();
					break;
				case STRIKEOUT1:
					format.Strikeout();
					break;
				case STRIKEOUTS:
					format.Strikeout(chrstyle.IsStrikeout());
					break;
				case CAPITALS0:
					format.capitals = false;
					break;
				case CAPITALS1:
					format.capitals = true;
					break;
				case CAPITALSS:
					format.capitals = chrstyle.capitals;
					break;
				case DASHED0:
					format.dashed = false;
					break;
				case DASHED1:
					format.dashed = true;
					break;
				case DASHEDS:
					format.dashed = chrstyle.dashed;
					break;
				case SSCRIPT:
					format.sscript = in.Get();
					if(format.sscript == 3)
						format.sscript = chrstyle.sscript;
					break;
				case FACE:
					c = in.Get16();
					format.Face(c == 0xffff ? chrstyle.GetFace() : c);
					break;
				case HEIGHT:
					c = in.Get16();
					format.Height(c == 0xffff ? chrstyle.GetHeight() : c);
					break;
				case LINK:
					in % format.link;
					break;
				case INDEXENTRY:
					in % format.indexentry;
					break;
				case INK:
					in % format.ink;
					break;
				case PAPER:
					in % format.paper;
					break;
				case LANGUAGE:
					format.language = in.Get32();
					break;
				case EXT:
					switch(in.Get()) {
					case NONAA0:
						format.NonAntiAliased(false);
						break;
					case NONAA1:
						format.NonAntiAliased(true);
						break;
					case NONAAS:
						format.NonAntiAliased(chrstyle.IsNonAntiAliased());
						break;
					}
				}
			while((c = in.Term()) < 31 && c != 9 && c != FIELD && c >= 0);
			if(part.Top().text.GetLength())
				part.Add();
			part.Top().format = format;
		}
		else
		if(in.Term() == FIELD) {
			RichPara::Format pformat = format;
			if(part.Top().text.GetLength()) {
				part.Add();
				part.Top().format = pformat;
			}
			in.Get();
			Part& p = part.Top();
			String id;
			in % id;
			p.field = id;
			in % p.fieldparam;
			String s;
			in % s;
			StringStream sn(s);
			UnpackParts(sn, chrstyle, p.fieldpart, obj, oi);
			part.Add();
			part.Top().format = format = pformat;
		}
		else
		if(in.Term() == OBJECT) {
			if(part.Top().text.GetLength()) {
				part.Add();
				part.Top().format = format;
			}
			part.Top().object = obj[oi++];
			part.Top().format = format;
			part.Add();
			part.Top().format = format;
			in.Get();
		}
		else {
			StringBuffer b;
			b.Reserve(512);
			while(in.Term() >= 32 || in.Term() == 9)
				b.Cat(in.Get());
			part.Top().text.Cat(FromUtf8(~b));
		}
	if(part.Top().text.GetLength() == 0 && part.Top().IsText())
		part.Drop();
}