From 6e83c52ef22aee95d9a54f6774a78c640b6b4561 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Sun, 27 Jul 2025 09:35:53 +0200 Subject: [PATCH] RichText, RichEdit: Developing Diagram --- examples/TextToSvgPath/TextToSvgPath.lay | 22 ++++---- uppsrc/RichEdit/Diagram.iml | 43 ++++++++++++++ uppsrc/RichEdit/Diagram.lay | 8 +-- uppsrc/RichEdit/DiagramEditor.cpp | 15 ++--- uppsrc/RichEdit/DiagramEditor.h | 4 +- uppsrc/RichEdit/DiagramMouse.cpp | 21 ++++++- uppsrc/RichEdit/SelectSymbol.cpp | 71 ++++++++++++++++++++++-- uppsrc/RichText/Diagram.cpp | 14 +++++ uppsrc/RichText/Diagram.h | 3 + uppsrc/RichText/DiagramShape.cpp | 13 +++++ upptst/Diagram/main.cpp | 6 +- 11 files changed, 185 insertions(+), 35 deletions(-) diff --git a/examples/TextToSvgPath/TextToSvgPath.lay b/examples/TextToSvgPath/TextToSvgPath.lay index 56cf4eb7a..c8790a163 100644 --- a/examples/TextToSvgPath/TextToSvgPath.lay +++ b/examples/TextToSvgPath/TextToSvgPath.lay @@ -1,15 +1,15 @@ LAYOUT(TextToSvgPathLayout, 704, 588) - ITEM(Label, dv___0, SetLabel(t_("Text")).LeftPosZ(8, 33).TopPosZ(28, 19)) - ITEM(EditString, text, HSizePosZ(44, 8).TopPosZ(28, 19)) - ITEM(Label, dv___2, SetLabel(t_("Font")).LeftPosZ(8, 33).TopPosZ(4, 19)) - ITEM(DropList, face, LeftPosZ(44, 188).TopPosZ(4, 19)) - ITEM(Label, dv___4, SetLabel(t_("Height")).LeftPosZ(252, 39).TopPosZ(4, 19)) - ITEM(WithDropChoice, height, LeftPosZ(292, 56).TopPosZ(4, 19)) - ITEM(Option, bold, SetLabel(t_("Bold")).LeftPosZ(356, 52).TopPosZ(4, 20)) - ITEM(Option, italic, SetLabel(t_("Italic")).LeftPosZ(408, 52).TopPosZ(4, 20)) - ITEM(LineEdit, svgpath, HSizePosZ(8, 8).VSizePosZ(52, 268)) + ITEM(Upp::Label, dv___0, SetLabel(t_("Text")).LeftPosZ(8, 33).TopPosZ(28, 19)) + ITEM(Upp::EditString, text, HSizePosZ(44, 8).TopPosZ(28, 19)) + ITEM(Upp::Label, dv___2, SetLabel(t_("Font")).LeftPosZ(8, 33).TopPosZ(4, 19)) + ITEM(Upp::DropList, face, LeftPosZ(44, 188).TopPosZ(4, 19)) + ITEM(Upp::Label, dv___4, SetLabel(t_("Height")).LeftPosZ(252, 39).TopPosZ(4, 19)) + ITEM(Upp::WithDropChoice, height, LeftPosZ(292, 56).TopPosZ(4, 19)) + ITEM(Upp::Option, bold, SetLabel(t_("Bold")).LeftPosZ(356, 52).TopPosZ(4, 20)) + ITEM(Upp::Option, italic, SetLabel(t_("Italic")).LeftPosZ(408, 52).TopPosZ(4, 20)) + ITEM(Upp::LineEdit, svgpath, HSizePosZ(8, 8).VSizePosZ(52, 268)) UNTYPED(preview, HSizePosZ(8, 8).BottomPosZ(4, 260)) - ITEM(Button, copy, SetLabel(t_("Copy path to clipboard")).RightPosZ(8, 128).TopPosZ(4, 20)) - ITEM(Option, singleline, SetLabel(t_("Single line")).LeftPosZ(484, 80).TopPosZ(4, 20)) + ITEM(Upp::Button, copy, SetLabel(t_("Copy path to clipboard")).RightPosZ(8, 128).TopPosZ(4, 20)) + ITEM(Upp::Option, singleline, SetLabel(t_("Single line")).LeftPosZ(484, 80).TopPosZ(4, 20)) END_LAYOUT diff --git a/uppsrc/RichEdit/Diagram.iml b/uppsrc/RichEdit/Diagram.iml index 72d966286..75aaa1bf6 100644 --- a/uppsrc/RichEdit/Diagram.iml +++ b/uppsrc/RichEdit/Diagram.iml @@ -27,6 +27,7 @@ IMAGE_ID(PaperA__UHD) IMAGE_ID(MoveFront__UHD) IMAGE_ID(MoveBack__UHD) IMAGE_ID(Size__UHD) +IMAGE_ID(FontSvg__UHD) IMAGE_ID(DisplayGrid) IMAGE_ID(Diagram) IMAGE_ID(RoundRect) @@ -54,6 +55,7 @@ IMAGE_ID(PaperA) IMAGE_ID(MoveFront) IMAGE_ID(MoveBack) IMAGE_ID(Size) +IMAGE_ID(FontSvg) IMAGE_BEGIN_DATA IMAGE_DATA(120,156,237,217,81,138,194,48,20,70,97,151,51,203,114,255,155,112,200,67,176,136,218,73,39,241,220,191,158,15,242,166) @@ -480,3 +482,44 @@ IMAGE_DATA(181,63,185,239,255,63,31,147,220,109,255,55,75,250,249,237,143,83,220 IMAGE_DATA(162,254,58,106,175,162,254,58,106,175,162,254,42,234,175,163,246,42,234,175,162,254,58,106,175,162,254,58,106,175,162,254) IMAGE_DATA(73,146,36,25,224,21,2,152,45,35,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) IMAGE_END_DATA(448, 1) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,152,217,145,219,48,12,64,89,78,102,155,96,21,249,78,41,104,33,29,161,137,244,147,132,147,213,68,246,90) +IMAGE_DATA(22,110,144,18,222,12,190,178,38,174,71,201,206,183,159,237,71,43,138,162,40,138,162,40,138,162,184,40,253,111,192,103) +IMAGE_DATA(252,38,4,238,254,190,184,47,99,255,195,5,138,51,239,162,60,186,31,90,103,202,163,123,227,225,207,246,110,235,129,125) +IMAGE_DATA(20,57,80,191,235,104,60,42,174,139,183,63,245,62,187,54,17,254,140,168,119,217,117,137,240,167,222,101,215,37,202,159) +IMAGE_DATA(122,14,93,147,237,29,134,237,255,255,7,66,243,121,183,213,51,232,190,88,249,84,20,26,127,32,161,222,98,62,198,187) +IMAGE_DATA(168,158,65,118,236,191,55,60,207,118,255,111,87,250,14,89,254,200,25,30,104,191,11,92,193,167,122,135,241,24,251,214) +IMAGE_DATA(60,187,175,54,79,201,61,90,185,95,13,214,222,236,99,156,189,234,179,168,252,57,199,211,157,125,172,232,80,249,115,140) +IMAGE_DATA(228,249,124,55,135,134,15,229,207,87,50,220,89,209,161,242,231,53,89,238,108,177,10,229,207,87,178,221,89,201,161,242) +IMAGE_DATA(231,17,108,249,222,92,217,159,158,83,102,8,220,89,120,199,10,119,149,59,179,76,188,221,205,246,229,57,208,183,93,19) +IMAGE_DATA(102,247,231,185,62,47,178,93,57,10,239,59,163,133,227,79,228,243,244,168,46,47,178,61,153,97,230,18,102,124,246,224) +IMAGE_DATA(155,26,60,230,201,185,67,229,207,35,51,249,211,19,234,160,230,204,140,153,161,246,128,206,117,112,246,104,121,39,145,145) +IMAGE_DATA(183,252,121,132,179,179,62,73,29,150,46,115,243,150,63,143,140,123,28,185,175,35,178,102,138,194,220,229,207,63,168,243) +IMAGE_DATA(235,142,53,80,29,246,152,101,182,23,222,119,23,118,33,205,191,125,254,213,217,222,245,83,224,244,98,233,177,102,166,145) +IMAGE_DATA(241,106,119,239,122,242,238,107,203,129,196,191,247,132,211,43,103,142,20,178,189,176,234,155,179,203,217,106,215,208,19,235) +IMAGE_DATA(152,117,222,175,226,153,153,125,57,171,221,18,96,212,209,13,243,114,188,205,14,216,213,205,153,215,12,129,231,171,80,145) +IMAGE_DATA(229,49,50,115,103,239,96,53,111,182,0,234,66,132,100,248,211,153,121,43,116,209,105,107,97,195,221,163,21,217,243,188) +IMAGE_DATA(99,96,179,247,8,152,53,88,192,117,246,10,49,118,7,140,240,172,197,210,33,110,173,96,144,51,123,151,145,174,104,233) +IMAGE_DATA(205,231,119,158,21,220,188,191,20,185,62,62,63,159,189,95,235,24,61,141,29,127,87,204,134,194,135,113,221,22,126,71) +IMAGE_DATA(229,29,247,200,250,14,101,6,10,231,32,165,59,245,161,237,65,154,183,7,229,153,45,162,189,217,64,97,189,30,187,220) +IMAGE_DATA(227,237,238,168,205,179,247,72,111,52,115,214,0,196,26,53,33,197,178,6,104,49,191,31,50,220,201,130,58,203,205,239) +IMAGE_DATA(232,30,179,119,179,74,128,112,190,90,168,245,109,12,135,144,241,57,109,143,217,123,89,41,80,48,95,13,157,88,87,23) +IMAGE_DATA(126,142,114,214,25,217,59,89,45,80,48,99,9,84,7,142,156,150,58,116,116,222,17,217,251,88,53,60,161,238,30,78) +IMAGE_DATA(206,1,226,57,154,222,164,57,238,30,200,156,51,7,36,214,96,121,22,199,203,61,229,143,60,58,99,206,84,58,49,55) +IMAGE_DATA(213,95,234,121,146,179,55,178,247,176,114,88,59,228,177,95,32,158,187,15,48,174,185,194,102,151,239,232,196,156,92,103) +IMAGE_DATA(169,231,74,251,202,222,193,234,193,221,231,17,72,200,37,245,85,210,23,21,16,158,95,241,47,128,49,235,35,58,49,151) +IMAGE_DATA(20,79,127,164,231,87,232,247,186,65,201,129,138,243,145,152,67,122,47,64,112,126,133,141,63,212,217,247,128,28,82,127) +IMAGE_DATA(154,224,252,10,27,127,48,32,135,196,31,110,206,46,204,81,161,131,114,62,40,115,68,248,211,132,57,42,228,116,231,243) +IMAGE_DATA(55,162,252,145,230,185,123,72,161,206,91,75,148,63,3,20,230,186,115,72,161,204,26,21,231,111,68,250,51,40,135,98) +IMAGE_DATA(230,76,57,27,20,231,111,68,251,211,132,249,238,26,82,174,236,79,23,230,188,99,72,153,217,31,139,188,229,208,121,160) +IMAGE_DATA(112,182,212,157,90,236,17,137,185,172,243,74,115,223,41,164,115,142,244,39,178,175,87,80,123,189,99,104,152,217,31,107) +IMAGE_DATA(186,176,142,43,7,170,38,122,47,127,6,229,144,237,140,35,242,0,35,143,165,179,71,148,67,118,51,166,230,234,1,57) +IMAGE_DATA(172,242,121,214,117,165,176,0,136,185,208,249,124,143,222,40,116,97,125,171,135,21,156,249,113,29,66,198,217,251,232,154) +IMAGE_DATA(134,132,72,107,93,49,184,123,60,195,99,183,28,47,189,238,6,23,56,169,235,10,97,237,78,19,212,0,111,206,234,77) +IMAGE_DATA(119,151,61,250,227,160,173,127,230,240,154,45,8,235,129,167,176,232,177,59,245,40,193,170,167,25,194,123,174,56,65,143) +IMAGE_DATA(224,220,163,148,213,61,242,118,167,181,252,223,33,232,223,162,138,49,159,25,238,216,204,51,205,116,104,53,160,229,251,113) +IMAGE_DATA(20,224,216,247,25,25,119,172,135,116,230,195,168,125,22,151,50,189,217,19,229,208,200,179,178,59,207,100,184,4,109,30) +IMAGE_DATA(111,246,120,207,1,227,90,73,99,243,201,242,62,226,231,153,43,220,187,81,99,185,83,88,160,125,30,173,114,103,10,95) +IMAGE_DATA(56,207,228,89,223,205,69,81,20,69,17,198,31,18,202,155,177,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) +IMAGE_END_DATA(1216, 1) diff --git a/uppsrc/RichEdit/Diagram.lay b/uppsrc/RichEdit/Diagram.lay index e2bbbed61..553ddf267 100644 --- a/uppsrc/RichEdit/Diagram.lay +++ b/uppsrc/RichEdit/Diagram.lay @@ -8,11 +8,9 @@ LAYOUT(SizeLayout, 212, 164) END_LAYOUT LAYOUT(SelectSymbolLayout, 596, 572) - ITEM(Upp::Switch, group, SetLabel(t_("All\nSymbols\nArrows\nShapes\nDingbats\nMathematical")).LeftPosZ(4, 400).TopPosZ(4, 19)) - ITEM(Upp::EditString, search, LeftPosZ(408, 184).TopPosZ(4, 19)) + ITEM(Upp::Switch, group, SetLabel(t_("All\nSymbols\nArrows\nShapes\nDingbats\nMathematical")).LeftPosZ(208, 400).TopPosZ(4, 19)) + ITEM(Upp::EditString, search, LeftPosZ(4, 184).TopPosZ(4, 19)) ITEM(Upp::RichTextView, symbols, LeftPosZ(4, 588).TopPosZ(28, 432)) - ITEM(Upp::RichTextView, variants, LeftPosZ(4, 588).TopPosZ(464, 68)) - ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(456, 64).TopPosZ(540, 24)) - ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(526, 64).TopPosZ(540, 24)) + ITEM(Upp::RichTextView, variants, LeftPosZ(4, 588).TopPosZ(464, 104)) END_LAYOUT diff --git a/uppsrc/RichEdit/DiagramEditor.cpp b/uppsrc/RichEdit/DiagramEditor.cpp index 688de1138..a4daad6df 100644 --- a/uppsrc/RichEdit/DiagramEditor.cpp +++ b/uppsrc/RichEdit/DiagramEditor.cpp @@ -87,18 +87,17 @@ void DiagramEditor::Skin() { SetBar(); - int cy = GetStdFontCy(); - - Size shape_sz = Size(DPI(24), cy); + Size icon_sz = IconSz(); shape.ClearList(); - for(int i = 0; i < DiagramItem::SHAPE_COUNT; i++) { + shape.SetLineCy(icon_sz.cy); + for(int i = 0; i < DiagramItem::SHAPE_SVGPATH; i++) { DiagramItem m; m.pt[0] = Point(2, 2); - m.pt[1] = Point(shape_sz.cx - 2, cy - 2); + m.pt[1] = Point(icon_sz.cx - 2, icon_sz.cy - 2); m.width = DPI(1); m.shape = i; - shape.Add(i, MakeIcon(m, shape_sz)); + shape.Add(i, MakeIcon(m, icon_sz)); } struct Dialine : DiagramItem { @@ -111,6 +110,7 @@ void DiagramEditor::Skin() }; auto LDL = [=](DropList& dl, bool left) { + dl.SetLineCy(icon_sz.cy); dl.ClearList(); for(int i = DiagramItem::CAP_NONE; i < DiagramItem::CAP_COUNT; i++) { dl.Add(i, CapIcon(left ? i : 0, left ? 0 : i)); @@ -121,10 +121,11 @@ void DiagramEditor::Skin() LDL(line_end, false); line_dash.ClearList(); + line_dash.SetLineCy(icon_sz.cy); for(int i = 0; i < DiagramItem::DASH_COUNT; i++) { Dialine m; m.dash = i; - line_dash.Add(i, MakeIcon(m, shape_sz)); + line_dash.Add(i, MakeIcon(m, icon_sz)); } } diff --git a/uppsrc/RichEdit/DiagramEditor.h b/uppsrc/RichEdit/DiagramEditor.h index d947afba3..66adaeb5b 100644 --- a/uppsrc/RichEdit/DiagramEditor.h +++ b/uppsrc/RichEdit/DiagramEditor.h @@ -36,7 +36,7 @@ struct ColumnPopUp : Ctrl { const VectorMap>>& UnicodeSymbols(); -bool SelectUnicodeSymbol(int& codepoint, Font& font); +String SelectFontSymbolSvg(Sizef& sz); class DiagramEditor : public Ctrl, Diagram::PaintInfo { public: @@ -127,7 +127,7 @@ private: double GetZoom() const { return DPI(1) * 0.01 * zoom_percent; } void Map(Point& p); Image MakeIcon(DiagramItem& m, Size isz); - Size IconSz() { return Size(DPI(24), GetStdFontCy()); } + Size IconSz() { return Size(DPI(24), DPI(16)); } Image ShapeIcon(int i); Image CapIcon(int start, int end); Image DashIcon(int i); diff --git a/uppsrc/RichEdit/DiagramMouse.cpp b/uppsrc/RichEdit/DiagramMouse.cpp index 9c4394045..3fe96a86a 100644 --- a/uppsrc/RichEdit/DiagramMouse.cpp +++ b/uppsrc/RichEdit/DiagramMouse.cpp @@ -332,7 +332,7 @@ void DiagramEditor::RightDown(Point p, dword keyflags) shape.columns = 3; shape.isz = IconSz() + Size(DPI(4), DPI(4)); shape.WhenPaintItem = [=](Draw& w, Size isz, int ii, bool sel) { - PopPaint(w, ShapeIcon(ii), sel); + PopPaint(w, ii == DiagramItem::SHAPE_SVGPATH ? DiagramImg::FontSvg() : ShapeIcon(ii), sel); }; tool = -1; @@ -341,6 +341,14 @@ void DiagramEditor::RightDown(Point p, dword keyflags) if(si < 0) return; + + Sizef size; + String svgpath; + if(si == DiagramItem::SHAPE_SVGPATH) { + svgpath = SelectFontSymbolSvg(size); + if(IsNull(svgpath)) + return; + } CancelSelection(); @@ -369,7 +377,16 @@ void DiagramEditor::RightDown(Point p, dword keyflags) m.pt[1] = p; } m.shape = si; // shape must be set before SetAttrs to avoid Normalise - SetAttrs(ATTR_ALL & ~ATTR_SHAPE); + m.data = svgpath; + m.size = size; + if(si == DiagramItem::SHAPE_SVGPATH) { + m.ink = Null; + m.paper = Black(); + m.pt[1] = m.pt[0] + size; + SetAttrs(ATTR_ALL & ~(ATTR_SHAPE|ATTR_PAPER|ATTR_INK)); + } + else + SetAttrs(ATTR_ALL & ~ATTR_SHAPE); Sync(); } diff --git a/uppsrc/RichEdit/SelectSymbol.cpp b/uppsrc/RichEdit/SelectSymbol.cpp index 985988c2f..628470ada 100644 --- a/uppsrc/RichEdit/SelectSymbol.cpp +++ b/uppsrc/RichEdit/SelectSymbol.cpp @@ -2,7 +2,46 @@ namespace Upp { +String AsSvgPath(Font font, int c, Sizef& sz) { + struct TextToSvg : FontGlyphConsumer { + String t; // here we accumulate the SVG path text + Rectf bounds = Rectf(DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX); + Pointf offset = Pointf(0, 0); + double scale = 1; + + void Put(Pointf p) { + bounds.left = min(bounds.left, p.x); + bounds.right = max(bounds.right, p.x); + bounds.top = min(bounds.top, p.y); + bounds.bottom = max(bounds.bottom, p.y); + bounds.Union(p); + p = (p + offset) * scale; + t << Format("%.2f %.2f ", p.x, p.y); + } + + virtual void Move(Pointf p) { t << 'M'; Put(p); } + virtual void Line(Pointf p) { t << 'L'; Put(p); } + virtual void Quadratic(Pointf p1, Pointf p2) { t << 'Q'; Put(p1); Put(p2); } + virtual void Cubic(Pointf p1, Pointf p2, Pointf p3) { t << 'C'; Put(p1); Put(p2); Put(p2); } + virtual void Close() { t << 'Z'; } + } t; + + font.Render(t, 0, 0, c); + + t.t.Clear(); + t.offset = -t.bounds.TopLeft(); + t.scale = 100 / t.bounds.GetHeight(); + sz = t.bounds.GetSize() * t.scale; + + font.Render(t, 0, 0, c); + + return t.t; +} + struct SelectSymbolDlg : WithSelectSymbolLayout { + Vector> svg; + int result; + SelectSymbolDlg(); void Sync(); @@ -11,7 +50,7 @@ struct SelectSymbolDlg : WithSelectSymbolLayout { SelectSymbolDlg::SelectSymbolDlg() { - CtrlLayoutOKCancel(*this, "Insert"); + CtrlLayout(*this, "Insert symbol"); search.NullText(t_("Search")); search.SetFilter(CharFilterDefaultToUpperAscii); group <<= 0; @@ -19,6 +58,10 @@ SelectSymbolDlg::SelectSymbolDlg() symbols.NoHyperlinkDecoration(); symbols.WhenLink << [=](const String& s) { Variants(Atoi(s)); }; + + result = -1; + variants.NoHyperlinkDecoration(); + variants.WhenLink << [=](const String& s) { result = Atoi(s); Break(IDOK); }; } void SelectSymbolDlg::Sync() @@ -39,21 +82,39 @@ void SelectSymbolDlg::Sync() void SelectSymbolDlg::Variants(int codepoint) { String qtf = "[A5 "; + Index h; for(int i = 0; i < Font::GetFaceCount(); i++) { Font fnt(i, 10); if(HasCodepoint(fnt, codepoint)) { - qtf << "[!" << fnt.GetFaceName() << "! " << WString(codepoint, 1) << "] "; + Sizef szf0; + String svgpath = AsSvgPath(fnt, codepoint, szf0); + Size szf = szf0 * DPI(1); + Size sz((int)ceil(szf.cx), (int)ceil(szf.cy)); + ImagePainter sw(sz); + sw.Clear(); + sw.Scale(DPI(1)); + sw.Path(svgpath).Fill(SBlack()); + Image img = sw; + if(h.Find(img) < 0) { + qtf << "[^" << h.GetCount() << "^ " << " " << AsQTF(CreatePNGObject(img, sz.cx, sz.cy)) << "], "; + h.Add(img); + svg.Add(MakeTuple(szf0, svgpath)); + } } } variants.SetQTF(qtf); } -bool SelectUnicodeSymbol(int& codepoint, Font& font) +String SelectFontSymbolSvg(Sizef& sz) { SelectSymbolDlg dlg; dlg.Sync(); - dlg.Run(); - return true; + if(dlg.Execute() != IDOK || dlg.result < 0 || dlg.result >= dlg.svg.GetCount()) + return Null; + + Tuple h = dlg.svg[dlg.result]; + sz = h.a; + return h.b; } } \ No newline at end of file diff --git a/uppsrc/RichText/Diagram.cpp b/uppsrc/RichText/Diagram.cpp index 36295d454..76562cb2d 100644 --- a/uppsrc/RichText/Diagram.cpp +++ b/uppsrc/RichText/Diagram.cpp @@ -30,6 +30,8 @@ void DiagramItem::Reset() width = 2; ink = Black(); paper = White(); + data.Clear(); + size = Null; cap[0] = cap[1] = CAP_NONE; dash = 0; @@ -138,6 +140,10 @@ void DiagramItem::Save(StringBuffer& r) const return String("null"); return Format("%02x%02x%02x", (int)c.GetR(), (int)c.GetG(), (int)c.GetB()); }; + if(data.GetCount()) + r << " data " << AsCString(data); + if(!IsNull(size)) + r << " size " << size.cx << ' ' << size.cy; if(ink != Black()) r << " ink " << col(ink); if(paper != White()) @@ -195,6 +201,14 @@ void DiagramItem::Load(CParser& p) else if(p.Id("dash")) dash = clamp(p.ReadInt(), 0, (int)DASH_COUNT); + else + if(p.Id("data")) + data = p.ReadString(); + else + if(p.Id("size")) { + size.cx = p.ReadDouble(); + size.cy = p.ReadDouble(); + } else p.Skip(); } diff --git a/uppsrc/RichText/Diagram.h b/uppsrc/RichText/Diagram.h index 4015aa000..0dace9089 100644 --- a/uppsrc/RichText/Diagram.h +++ b/uppsrc/RichText/Diagram.h @@ -16,6 +16,8 @@ struct DiagramItem : Point2 { double width; Color ink; Color paper; + Sizef size; + String data; enum { SHAPE_LINE, @@ -34,6 +36,7 @@ struct DiagramItem : Point2 { SHAPE_ARROWDOWN, SHAPE_ARROWUP, SHAPE_ARROWVERT, + SHAPE_SVGPATH, SHAPE_COUNT, }; diff --git a/uppsrc/RichText/DiagramShape.cpp b/uppsrc/RichText/DiagramShape.cpp index b78876406..f5a52d86d 100644 --- a/uppsrc/RichText/DiagramShape.cpp +++ b/uppsrc/RichText/DiagramShape.cpp @@ -8,6 +8,7 @@ Index DiagramItem::Shape = { "line", "rect", "round_rect", "triangle1", "triangle2", "arrow_left", "arrow_right", "arrow_horz", "arrow_down", "arrow_up", "arrow_vert", + "svgpath", }; Vector DiagramItem::GetConnections() const @@ -305,6 +306,14 @@ void DiagramItem::Paint(Painter& w, dword style, const Index *conn) cons .Close(); } break; + case SHAPE_SVGPATH: + if(data.GetCount() && !IsNull(size)) { + w.Begin(); + w.Offset(r.TopLeft()); + w.Scale(w1 / size.cx, h / size.cy); + w.Path(data); + } + break; default: w.Rectangle(r); break; @@ -320,6 +329,10 @@ void DiagramItem::Paint(Painter& w, dword style, const Index *conn) cons DoDash(); Stroke(); break; + case SHAPE_SVGPATH: + if(data.GetCount() && !IsNull(size)) + w.End(); + break; } int txt_cy = txt.GetHeight(pi.zoom, text_rect.GetWidth()); diff --git a/upptst/Diagram/main.cpp b/upptst/Diagram/main.cpp index 8e12a6647..89f0ce16f 100644 --- a/upptst/Diagram/main.cpp +++ b/upptst/Diagram/main.cpp @@ -4,12 +4,12 @@ using namespace Upp; GUI_APP_MAIN { -/* int cp; +/* + int cp; Font fnt; SelectUnicodeSymbol(cp, fnt); return; -*/ - +//*/ TopWindow app; app.Sizeable().Zoomable(); DiagramEditor de;