void RichQtfParser::FinishTable() { FinishCell(); while(table.Top().cell % Table().GetColumns()) FinishCell(); tablepart = pick(Table()); istable = true; table.Drop(); }
void RichQtfParser::FinishOldTable() { FinishCell(); Index<int> pos; Vector<int> srow; RichTable& t = Table(); Tab& b = table.Top(); for(int i = 0; i < t.GetRows(); i++) { int& s = srow.Add(); s = 0; int nx = b.rown[i]; for(int j = 0; j < nx; j++) s += t.GetSpan(i, j).cx; int xn = 0; for(int j = 0; j < nx; j++) { pos.FindAdd(xn * 10000 / s); xn += t.GetSpan(i, j).cx; } } Vector<int> h = pos.PickKeys(); if(h.GetCount() == 0) Error("table"); Sort(h); pos = pick(h); pos.Add(10000); RichTable tab; tab.SetFormat(t.GetFormat()); for(int i = 0; i < pos.GetCount() - 1; i++) { tab.AddColumn(pos[i + 1] - pos[i]); } for(int i = 0; i < t.GetRows(); i++) { int s = srow[i]; int nx = b.rown[i]; int xn = 0; int xi = 0; for(int j = 0; j < nx; j++) { Size span = t.GetSpan(i, j); xn += span.cx; int nxi = pos.Find(xn * 10000 / s); tab.SetPick(i, xi, t.GetPick(i, j)); tab.SetFormat(i, xi, t.GetFormat(i, j)); tab.SetSpan(i, xi, max(span.cy - 1, 0), nxi - xi - 1); xi = nxi; } } table.Drop(); if(table.GetCount()) table.Top().text.CatPick(pick(tab)); else target.CatPick(pick(tab)); oldtab = false; }
void RichQtfParser::Parse(const char *qtf, int _accesskey) { accesskey = _accesskey; term = qtf; while(*term) { if(Key('[')) { Flush(); fstack.Add(format); for(;;) { int c = *term; if(!c) Error("Unexpected end of text"); term++; if(c == ' ' || c == '\n') break; switch(c) { case 's': { Uuid id; c = *term; if(Key('\"') || Key('\'')) id = target.GetStyleId(GetText(c)); else { int i = ReadNumber(); if(i >= 0 && i < styleid.GetCount()) id = styleid[i]; else id = RichStyle::GetDefaultId(); } const RichStyle& s = target.GetStyle(id); bool p = format.newpage; int lng = format.language; (RichPara::Format&) format = s.format; format.styleid = id; format.language = lng; format.newpage = p; break; } case '/': format.Italic(!format.IsItalic()); break; case '*': format.Bold(!format.IsBold()); break; case '_': format.Underline(!format.IsUnderline()); break; case 'T': format.NonAntiAliased(!format.IsNonAntiAliased()); break; case '-': format.Strikeout(!format.IsStrikeout()); break; case 'c': format.capitals = !format.capitals; break; case 'd': format.dashed = !format.dashed; break; case '`': format.sscript = format.sscript == 1 ? 0 : 1; break; case ',': format.sscript = format.sscript == 2 ? 0 : 2; break; case '^': format.link = GetText('^'); break; case 'I': format.indexentry = FromUtf8(GetText(';')); break; case '+': format.Height(GetNumber()); break; case '@': format.ink = GetColor(); break; case '$': format.paper = GetColor(); break; case 'A': format.Face(Font::ARIAL); break; case 'R': format.Face(Font::ROMAN); break; case 'C': format.Face(Font::COURIER); break; case 'G': format.Face(Font::STDFONT); break; case 'S': #ifdef PLATFORM_WIN32 format.Face(Font::SYMBOL); #endif break; case '.': { int n = GetNumber(); if(n >= Font::GetFaceCount()) Error("Invalid face number"); format.Face(n); break; } case '!': { String fn = GetText('!'); int i = Font::FindFaceNameIndex(fn); if(i < 0) i = Font::ARIAL; format.Face(i); } break; case '{': { String cs = GetText('}'); if(cs.GetLength() == 1) { int c = *cs; if(c == '_') format.charset = CHARSET_UTF8; if(c >= '0' && c <= '8') format.charset = c - '0' + CHARSET_WIN1250; if(c >= 'A' && c <= 'Z') format.charset = c - '0' + CHARSET_ISO8859_1; } else { for(int i = 0; i < CharsetCount(); i++) if(stricmp(CharsetName(i), cs) == 0) { format.charset = i; break; } } break; } case '%': { String h; if(*term == '-') { format.language = 0; term++; } else if(*term == '%') { format.language = LNG_ENGLISH; term++; } else { while(*term && h.GetLength() < 5) h.Cat(*term++); format.language = LNGFromText(h); } break; } case 'g': format.Face(Font::STDFONT); format.Height(GetRichTextScreenStdFontHeight()); break; default: if(c >= '0' && c <= '9') { format.Height(QTFFontHeight[c - '0']); break; } switch(c) { case ':': format.label = GetText(':'); break; case '<': format.align = ALIGN_LEFT; break; case '>': format.align = ALIGN_RIGHT; break; case '=': format.align = ALIGN_CENTER; break; case '#': format.align = ALIGN_JUSTIFY; break; case 'l': format.lm = GetNumber(); break; case 'r': format.rm = GetNumber(); break; case 'i': format.indent = GetNumber(); break; case 'b': format.before = GetNumber(); break; case 'a': format.after = GetNumber(); break; case 'P': format.newpage = !format.newpage; break; case 'k': format.keep = !format.keep; break; case 'K': format.keepnext = !format.keepnext; break; case 'H': format.ruler = GetNumber(); break; case 'h': format.rulerink = GetColor(); break; case 'L': format.rulerstyle = GetNumber(); break; case 'Q': format.orphan = !format.orphan; break; case 'n': format.before_number = GetText(';'); break; case 'm': format.after_number = GetText(';'); break; case 'N': { memset(format.number, 0, sizeof(format.number)); format.reset_number = false; int i = 0; while(i < 8) { int c; if(Key('-')) c = RichPara::NUMBER_NONE; else if(Key('1')) c = RichPara::NUMBER_1; else if(Key('0')) c = RichPara::NUMBER_0; else if(Key('a')) c = RichPara::NUMBER_a; else if(Key('A')) c = RichPara::NUMBER_A; else if(Key('i')) c = RichPara::NUMBER_i; else if(Key('I')) c = RichPara::NUMBER_I; else break; format.number[i++] = c; } if(Key('!')) format.reset_number = true; break; } case 'o': format.bullet = RichPara::BULLET_ROUND; format.indent = 150; break; case 'O': if(Key('_')) format.bullet = RichPara::BULLET_NONE; else { int c = *term++; if(!c) Error("Unexpected end of text"); format.bullet = c == '1' ? RichPara::BULLET_ROUNDWHITE : c == '2' ? RichPara::BULLET_BOX : c == '3' ? RichPara::BULLET_BOXWHITE : c == '9' ? RichPara::BULLET_TEXT : RichPara::BULLET_ROUND; } break; case 'p': switch(*term++) { case 0: Error("Unexpected end of text"); case 'h': format.linespacing = RichPara::LSP15; break; case 'd': format.linespacing = RichPara::LSP20; break; default: format.linespacing = RichPara::LSP10; } break; case 't': if(IsDigit(*term)) //temporary fix... :( format.tabsize = ReadNumber(); break; case '~': { if(Key('~')) format.tab.Clear(); else { RichPara::Tab tab; Key('<'); if(Key('>')) tab.align = ALIGN_RIGHT; if(Key('=')) tab.align = ALIGN_CENTER; if(Key('.')) tab.fillchar = 1; if(Key('-')) tab.fillchar = 2; if(Key('_')) tab.fillchar = 3; int rightpos = Key('>') ? RichPara::TAB_RIGHTPOS : 0; tab.pos = rightpos | ReadNumber(); format.tab.Add(tab); } } break; default: continue; } } } SetFormat(); } else if(Key(']')) { Flush(); if(fstack.GetCount()) { format = fstack.Top(); fstack.Drop(); } else Error("Unmatched ']'"); } else if(Key2('{')) { if(oldtab) Error("{{ in ++ table"); if(text.GetLength() || paragraph.GetCount()) EndPart(); table.Add(); int r = IsDigit(*term) ? ReadNumber() : 1; Table().AddColumn(r); while(Key(':')) Table().AddColumn(ReadNumber()); TableFormat(); SetFormat(); } else if(Key2('}')) { if(oldtab) Error("}} in ++ table"); FinishTable(); } else if(Key2('+')) if(oldtab) FinishOldTable(); else { Flush(); if(text.GetLength() || paragraph.GetCount()) EndPart(); Tab& b = table.Add(); b.rown.Add(0); b.hspan = 1; b.Old(); oldtab = true; } else if(Key2('|')) FinishCell(); else if(Key2('-')) { FinishCell(); table.Top().rown.Add(0); } else if(Key2(':')) { if(!oldtab) FinishCell(); TableFormat(oldtab); } else if(Key2('^')) { EndPart(); breakpage = true; } else if(Key2('@')) { ReadObject(); } else if(Key2('@', '$')) { String xu; while(isxdigit(*term)) xu.Cat(*term++); int c = stou(~xu, NULL, 16); if(c >= 32) Cat(c); if(*term == ';') term++; SetFormat(); } else if(Key2('^', 'H')) target.SetHeaderQtf(GetText2('^', '^')); else if(Key2('^', 'F')) target.SetFooterQtf(GetText2('^', '^')); else if(Key2('{', ':')) { Flush(); String field = GetText(':'); String param = GetText(':'); Id fid(field); if(RichPara::fieldtype().Find(fid) >= 0) paragraph.Cat(fid, param, format); Key('}'); } else if(Key('&')) { SetFormat(); EndPart(); } else if(Key2('$')) { Flush(); int i = GetNumber(); Uuid id; RichStyle style; style.format = format; if(Key(',')) stylenext.At(i, 0) = GetNumber(); else stylenext.At(i, 0) = i; if(Key('#')) { String xu; while(isxdigit(*term)) xu.Cat(*term++); if(xu.GetLength() != 32) Error("Invalid UUID !"); id = ScanUuid(xu); } else if(i) id = Uuid::Create(); else id = RichStyle::GetDefaultId(); if(Key(':')) style.name = GetText(']'); if(fstack.GetCount()) { format = fstack.Top(); fstack.Drop(); } target.SetStyle(id, style); styleid.At(i, RichStyle::GetDefaultId()) = id; if(id == RichStyle::GetDefaultId()) { bool p = format.newpage; int lng = format.language; (RichPara::Format&) format = style.format; format.styleid = id; format.language = lng; format.newpage = p; } } else if(*term == '_') { SetFormat(); text.Cat(160); term++; } else if(Key2('-', '|')) { SetFormat(); text.Cat(9); } else if(*term == '\1') { if(istable) EndPart(); SetFormat(); const char *b = ++term; for(; *term && *term != '\1'; term++) { if((byte)*term == '\n') { text.Cat(ToUnicode(b, (int)(term - b), format.charset)); EndPart(); b = term + 1; } if((byte)*term == '\t') { text.Cat(ToUnicode(b, (int)(term - b), format.charset)); text.Cat(9); b = term + 1; } } text.Cat(ToUnicode(b, (int)(term - b), format.charset)); if(*term == '\1') term++; } else { if(!Key('`')) Key('\\'); if((byte)*term >= ' ') { SetFormat(); do { if(istable) EndPart(); if(format.charset == CHARSET_UTF8) { word code = (byte)*term++; if(code <= 0x7F) Cat(code); else if(code <= 0xDF) { if(*term == '\0') break; int c0 = (byte)*term++; if(c0 < 0x80) Error("Invalid UTF-8 sequence"); Cat(((code - 0xC0) << 6) + c0 - 0x80); } else if(code <= 0xEF) { int c0 = (byte)*term++; int c1 = (byte)*term++; if(c0 < 0x80 || c1 < 0x80) Error("Invalid UTF-8 sequence"); Cat(((code - 0xE0) << 12) + ((c0 - 0x80) << 6) + c1 - 0x80); } else Error("Invalid UTF-8 sequence"); } else Cat(ToUnicode((byte)*term++, format.charset)); } while((byte)*term >= 128 || s_nodeqtf[(byte)*term]); } else if(*term) term++; } } // if(paragraph.GetCount() == 0) // TRC 11/02/15: kills formatting of last paragraph in text // SetFormat(); if(oldtab) FinishOldTable(); else while(table.GetCount()) FinishTable(); EndPart(); FlushStyles(); }
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(); }
Array<FileSystemInfo::FileInfo> FileSystemInfo::Find(String mask, int max_count, bool unmounted) const { Array<FileInfo> fi; if(IsNull(mask)) { // root #ifdef PLATFORM_WINCE FileInfo& f = fi.Add(); f.filename = "\\"; f.root_style = ROOT_FIXED; #elif defined(PLATFORM_WIN32) char drive[4] = "?:\\"; for(int c = 'A'; c <= 'Z'; c++) { *drive = c; int n = GetDriveType(drive); if(n == DRIVE_NO_ROOT_DIR) continue; FileInfo& f = fi.Add(); f.filename = drive; char name[256], system[256]; DWORD d; if(c != 'A' && c != 'B' && n != DRIVE_REMOTE && n != DRIVE_UNKNOWN) { bool b = GetVolumeInformation(drive, name, 256, &d, &d, &d, system, 256); if(b) { if(*name) f.root_desc << " " << FromSystemCharset(name); } else if(n == DRIVE_REMOVABLE || n == DRIVE_CDROM) { if(unmounted) { f.root_desc = t_("Empty drive"); } else { fi.Drop(); continue; } } } switch(n) { default: case DRIVE_UNKNOWN: f.root_style = ROOT_UNKNOWN; break; case DRIVE_NO_ROOT_DIR: f.root_style = ROOT_NO_ROOT_DIR; break; case DRIVE_REMOVABLE: f.root_style = ROOT_REMOVABLE; break; case DRIVE_FIXED: f.root_style = ROOT_FIXED; break; case DRIVE_REMOTE: f.root_style = ROOT_REMOTE; break; case DRIVE_CDROM: f.root_style = ROOT_CDROM; break; case DRIVE_RAMDISK: f.root_style = ROOT_RAMDISK; break; } } #elif defined(PLATFORM_POSIX) FileInfo& f = fi.Add(); f.filename = "/"; f.root_style = ROOT_FIXED; #endif } else { FindFile ff; if(ff.Search(mask)) do { FileInfo& f = fi.Add(); f.filename = ff.GetName(); #ifndef PLATFORM_POSIX f.is_archive = ff.IsArchive(); f.is_compressed = ff.IsCompressed(); f.is_hidden = ff.IsHidden(); f.is_system = ff.IsSystem(); f.is_temporary = ff.IsTemporary(); #endif f.is_read_only = ff.IsReadOnly(); f.length = ff.GetLength(); #ifdef PLATFORM_POSIX f.creation_time = ff.GetLastChangeTime(); f.unix_mode = ff.GetMode(); #endif f.last_access_time = ff.GetLastAccessTime(); f.last_write_time = ff.GetLastWriteTime(); #ifdef PLATFORM_WIN32 f.creation_time = ff.GetCreationTime(); f.unix_mode = 0; #endif f.read_only = ff.IsReadOnly(); f.is_directory = ff.IsDirectory(); f.is_folder = ff.IsFolder(); f.is_file = ff.IsFile(); #ifdef PLATFORM_POSIX f.is_symlink = ff.IsSymLink(); #endif } while(ff.Next() && fi.GetCount() < max_count); } return fi; }