mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
RichText, RichEdit: Added SVG support
git-svn-id: svn://ultimatepp.org/upp/trunk@12811 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
14dd43277a
commit
6adf46e448
8 changed files with 80 additions and 19 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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; ]]
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue