RichText, RichEdit: Added SVG support

git-svn-id: svn://ultimatepp.org/upp/trunk@12811 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2019-03-06 11:49:57 +00:00
parent 14dd43277a
commit 6adf46e448
8 changed files with 80 additions and 19 deletions

View file

@ -466,6 +466,8 @@ Rectf GetSVGBoundingBox(const char *svg);
Image RenderSVGImage(Size sz, const char *svg, Event<String, String&> resloader);
Image RenderSVGImage(Size sz, const char *svg);
bool IsSVG(const char *svg);
}
#endif

View file

@ -384,14 +384,25 @@ void SvgParser::ParseG() {
else
if(Tag("text")) {
StartElement();
String text = ReadText();
text.Replace("\n", " ");
text.Replace("\r", "");
text.Replace("\t", " ");
Font fnt = state.Top().font;
bp.Text(Dbl("x"), Dbl("y") - fnt.GetAscent(), text, fnt);
auto DoText = [&] {
String text = ReadText();
text.Replace("\n", " ");
text.Replace("\r", "");
text.Replace("\t", " ");
if(text.GetCount()) {
Font fnt = state.Top().font;
bp.Text(Dbl("x"), Dbl("y") - fnt.GetAscent(), text, fnt);
}
};
DoText();
while(Tag("tspan")) {
StartElement();
DoText();
FinishElement();
PassEnd();
}
FinishElement();
PassEnd();
PassEnd();
}
else
if(Tag("g")) {
@ -438,7 +449,8 @@ bool SvgParser::Parse() {
SvgParser::SvgParser(const char *svg, Painter& sw)
: XmlParser(svg),
sw(sw), bp(sw)
sw(sw),
bp(sw)
{
Reset();
}
@ -511,4 +523,18 @@ Image RenderSVGImage(Size sz, const char *svg)
return RenderSVGImage(sz, svg, Event<String, String&>());
}
bool IsSVG(const char *svg)
{
try {
XmlParser xml(svg);
while(!xml.IsTag())
xml.Skip();
if(xml.Tag("svg"))
return true;
}
catch(XmlError e) {
}
return false;
}
}

View file

@ -110,7 +110,7 @@ void SvgParser::ProcessValue(const String& key, const String& value_)
else
if(key == "font-weight")
s.font.Bold(findarg(value, "bold", "bolder") || atoi(value) >= 500);
}
}
}
void SvgParser::Style(const char *style)

View file

@ -1,9 +1,9 @@
topic "SVG support";
[ $$0,0#00000000000000000000000000000000:Default]
[H6;0 $$1,0#05600065144404261032431302351956:begin]
[i448;a25;kKO9;2 $$2,0#37138531426314131252341829483370:codeitem]
[l288;2 $$3,0#27521748481378242620020725143825:desc]
[0 $$4,0#96390100711032703541132217272105:end]
[ $$0,0#00000000000000000000000000000000:Default]
[{_}%EN-US
[ {{10000@(113.42.0) [s0; [*@(229)4 SVG support]]}}&]
[s4; &]
@ -41,4 +41,9 @@ specified in SVG and uses computed bounding box. It is then scaled
into [*@3 sz] at maximum size preserving aspect ratio. Use [*@3 resloader]
to provide resources like images.&]
[s4; &]
[s1;%- &]
[s2;:Upp`:`:IsSVG`(const char`*`):%- [@(0.0.255) bool]_[* IsSVG]([@(0.0.255) const]_[@(0.0.255) c
har]_`*[*@3 svg])&]
[s3; Returns true if [%-*@3 svg] likely contains SVG image.&]
[s4; &]
[s0; ]]

View file

@ -1,4 +1,5 @@
#include "RichEdit.h"
#include <Painter/Painter.h>
namespace Upp {
@ -13,7 +14,7 @@ void RichEdit::InsertImage()
}
String data = LoadFile(fn);
StringStream ss(data);
if(!StreamRaster::OpenAny(ss)) {
if(!StreamRaster::OpenAny(ss) && !IsSVG(data)) {
Exclamation(NFormat(t_("Unsupported image format in file [* \1%s\1]."), ~imagefs));
return;
}
@ -32,12 +33,14 @@ bool RichEdit::Accept(PasteClip& d, RichText& clip, String& fmt)
Vector<String> s = GetFiles(d);
if(s.GetCount()) {
String fn = s[0];
String ext = ToUpper(GetFileExt(fn));
if(ext == ".PNG" || ext == ".JPG" || ext == ".JPEG" || ext == ".GIF" || ext == ".TIF" || ext == ".TIFF") {
if(d.Accept()) {
if(StreamRaster::LoadFileAny(fn)) {
String ext = ToLower(GetFileExt(fn));
if(findarg(ext, ".png", ".jpg", ".jpeg", ".gif", ".tif", ".tiff", ".svg") >= 0) {
if(d.Accept() && GetFileLength(fn) < 17000000) {
String data = LoadFile(fn);
StringStream ss(data);
if(StreamRaster::OpenAny(ss) || ext == ".svg" && IsSVG(LoadFile(fn))) {
RichPara p;
p.Cat(CreateRawImageObject(LoadFile(fn)), formatinfo);
p.Cat(CreateRawImageObject(data), formatinfo);
clip.Cat(p);
fmt = "files";
}
@ -48,6 +51,12 @@ bool RichEdit::Accept(PasteClip& d, RichText& clip, String& fmt)
}
d.Reject();
}
if(d.Accept("image/x-inkscape-svg")) {
RichPara p;
p.Cat(CreateRawImageObject(~d), formatinfo);
clip.Cat(p);
fmt = "files";
}
if(d.Accept("text/QTF")) {
fmt = "text/QTF";
clip = ParseQTF(~d, 0, context);

View file

@ -736,7 +736,7 @@ RichEdit::RichEdit()
ClearModify();
Finish();
imagefs.Type("Images (*.png *.gif *.jpg *.bmp)", "*.png *.gif *.jpg *.bmp");
imagefs.Type("Images (*.png *.gif *.jpg *.bmp *.svg)", "*.png *.gif *.jpg *.bmp *.svg");
singleline = false;

View file

@ -1,4 +1,5 @@
#include "RichText.h"
#include <Painter/Painter.h>
namespace Upp {
@ -24,6 +25,7 @@ String RichImage::GetTypeName(const Value& v) const
return "image";
}
// following function pointers are set in CtrlCore (or similar host platform interface package)
static String (*sGetImageClip)(const Image& img, const String& fmt);
static bool (*sAcceptImage)(PasteClip& clip);
static Image (*sGetImage)(PasteClip& clip);
@ -208,7 +210,12 @@ Size RichRawImage::GetPhysicalSize(const Value& data) const
One<StreamRaster> r = StreamRaster::OpenAny(ss);
if(r)
return r->GetInfo().dots;
return Size(0, 0);
else
if(IsString(data) && IsSVG(~data)) {
Rectf f = GetSVGBoundingBox(~data);
Zoom z = GetRichTextStdScreenZoom();
return z.d * (Size)f.GetSize() / z.m;
}
}
Size RichRawImage::GetPixelSize(const Value& data) const
@ -218,6 +225,11 @@ Size RichRawImage::GetPixelSize(const Value& data) const
One<StreamRaster> r = StreamRaster::OpenAny(ss);
if(r)
return r->GetSize();
else
if(IsString(data) && IsSVG(~data)) {
Rectf f = GetSVGBoundingBox(~data);
return (Size)f.GetSize();
}
return Size(0, 0);
}
@ -236,6 +248,9 @@ void RichRawImage::Paint(const Value& data, Draw& w, Size sz, void *) const
else
w.DrawImage(0, 0, sz.cx, sz.cy, r->GetImage()); // scale up by Draw to give e.g. PDF chance to store unscaled
}
else
if(IsString(data) && IsSVG(~data))
w.DrawImage(0, 0, RenderSVGImage(sz, ~data));
}
Image RichRawImage::ToImage(const Value& data, Size sz, void *) const
@ -247,6 +262,9 @@ Image RichRawImage::ToImage(const Value& data, Size sz, void *) const
Image x = r->GetImage();
return Rescale(x, sz);
}
else
if(IsString(data) && IsSVG(~data))
return RenderSVGImage(sz, ~data);
return Null;
}

View file

@ -2,7 +2,8 @@ description "Rich-text data structures and painting, including RTF and HTML expo
uses
plugin\png,
Draw;
Draw,
Painter;
file
RichText.h options(BUILDER_OPTION) PCH,