1 #include "RichText.h"
2 #include <Painter/Painter.h>
3 
4 namespace Upp {
5 
6 #ifdef NEWIMAGE
7 
8 struct RichImage : public RichObjectType {
9 	virtual String GetTypeName(const Value& v) const;
10 	virtual Size   GetPhysicalSize(const Value& data) const;
11 	virtual Size   GetPixelSize(const Value& data) const;
12 	virtual void   Paint(const Value& data, Draw& w, Size sz, void *) const;
13 	virtual Image  ToImage(int64, const Value& data, Size sz, void *) const;
14 
15 	virtual bool   Accept(PasteClip& clip);
16 	virtual Value  Read(PasteClip& clip);
17 	virtual String GetClipFmts() const;
18 	virtual String GetClip(const Value& data, const String& fmt) const;
19 
20 	typedef RichImage CLASSNAME;
21 };
22 
GetTypeName(const Value & v) const23 String RichImage::GetTypeName(const Value& v) const
24 {
25 	return "image";
26 }
27 
28 // following function pointers are set in CtrlCore (or similar host platform interface package)
29 static String      (*sGetImageClip)(const Image& img, const String& fmt);
30 static bool        (*sAcceptImage)(PasteClip& clip);
31 static Image       (*sGetImage)(PasteClip& clip);
32 static const char *(*sClipFmtsImage)();
33 
InitRichImage(String (* fGetImageClip)(const Image & img,const String & fmt),bool (* fAcceptImage)(PasteClip & clip),Image (* fGetImage)(PasteClip & clip),const char * (* fClipFmtsImage)())34 void InitRichImage(String      (*fGetImageClip)(const Image& img, const String& fmt),
35                    bool        (*fAcceptImage)(PasteClip& clip),
36                    Image       (*fGetImage)(PasteClip& clip),
37                    const char *(*fClipFmtsImage)())
38 {
39 	sGetImageClip = fGetImageClip;
40 	sAcceptImage = fAcceptImage;
41 	sGetImage = fGetImage;
42 	sClipFmtsImage = fClipFmtsImage;
43 }
44 
Accept(PasteClip & clip)45 bool RichImage::Accept(PasteClip& clip)
46 {
47 	return sAcceptImage ? sAcceptImage(clip) : false;
48 }
49 
Read(PasteClip & clip)50 Value RichImage::Read(PasteClip& clip)
51 {
52 	if(sGetImage)
53 		return StoreImageAsString(sGetImage(clip));
54 	return Null;
55 }
56 
GetClipFmts() const57 String RichImage::GetClipFmts() const
58 {
59 	if(sClipFmtsImage)
60 		return sClipFmtsImage();
61 	return Null;
62 }
63 
GetClip(const Value & data,const String & fmt) const64 String RichImage::GetClip(const Value& data, const String& fmt) const
65 {
66 	if(sGetImageClip)
67 		return sGetImageClip(LoadImageFromString(data), fmt);
68 	return Null;
69 }
70 
GetPixelSize(const Value & data) const71 Size   RichImage::GetPixelSize(const Value& data) const
72 {
73 	return GetImageStringSize(data);
74 }
75 
GetPhysicalSize(const Value & data) const76 Size   RichImage::GetPhysicalSize(const Value& data) const
77 {
78 	Size sz = GetImageStringDots(data);
79 	if(sz.cx == 0 || sz.cy == 0)
80 		sz = 600 * GetPixelSize(data) / 96;
81 	return sz;
82 }
83 
Paint(const Value & data,Draw & w,Size sz,void *) const84 void   RichImage::Paint(const Value& data, Draw& w, Size sz, void *) const
85 {
86 	Image x = LoadImageFromString(data);
87 //	Size outsz(min(sz.cx, 4 * x.GetWidth()), min(sz.cy, 4 * x.GetHeight()));
88 	w.DrawImage(0, 0, sz.cx, sz.cy, x);
89 }
90 
ToImage(int64,const Value & data,Size sz,void *) const91 Image  RichImage::ToImage(int64, const Value& data, Size sz, void *) const
92 {
93 	return Rescale(LoadImageFromString(data), sz);
94 }
95 
96 INITBLOCK {
97 	RichObject::Register("image", &Single<RichImage>());
98 };
99 
CreateImageObject(const Image & img,int cx,int cy)100 RichObject CreateImageObject(const Image& img, int cx, int cy)
101 {
102 	RichObject o = RichObject("image", StoreImageAsString(img));
103 	if(cx || cy)
104 		o.SetSize(GetRatioSize(o.GetPixelSize(), cx, cy));
105 	return o;
106 }
107 
108 struct RichPNG : public RichObjectType {
109 	virtual String GetTypeName(const Value& v) const;
110 	virtual Value  Read(const String& s) const;
111 	virtual String Write(const Value& v) const;
112 	virtual Size   GetPhysicalSize(const Value& data) const;
113 	virtual Size   GetPixelSize(const Value& data) const;
114 	virtual void   Paint(const Value& data, Draw& w, Size sz) const;
115 	virtual Image  ToImage(int64, const Value& data, Size sz, void *) const;
116 };
117 
GetTypeName(const Value & v) const118 String RichPNG::GetTypeName(const Value& v) const
119 {
120 	return IsString(v) ? "PNG" : "image";
121 }
122 
Read(const String & s) const123 Value RichPNG::Read(const String& s) const
124 {
125 	Image img = StreamRaster::LoadStringAny(s);
126 	if(img)
127 		return img;
128 	return s;
129 }
130 
Write(const Value & v) const131 String RichPNG::Write(const Value& v) const
132 {
133 	if(IsString(v))
134 		return v;
135 	return StoreImageAsString(v);
136 }
137 
GetPhysicalSize(const Value & data) const138 Size RichPNG::GetPhysicalSize(const Value& data) const
139 {
140 	if(IsString(data))
141 		return Size(0, 0);
142 	return Image(data).GetDots();
143 }
144 
GetPixelSize(const Value & data) const145 Size RichPNG::GetPixelSize(const Value& data) const
146 {
147 	if(IsString(data))
148 		return Size(0, 0);
149 	return Image(data).GetDots();
150 }
151 
Paint(const Value & data,Draw & w,Size sz) const152 void RichPNG::Paint(const Value& data, Draw& w, Size sz) const
153 {
154 	if(IsString(data)) {
155 		w.DrawRect(sz, SColorFace());
156 		DrawFrame(w, sz, SColorText());
157 		w.DrawText(2, 2, "plugin/png missing!");
158 		return;
159 	}
160 	Image x = Image(data);
161 	Size outsz(min(sz.cx, 4 * x.GetWidth()), min(sz.cy, 4 * x.GetHeight()));
162 	w.DrawImage(0, 0, outsz.cx, outsz.cy, x);
163 }
164 
ToImage(int64,const Value & data,Size sz,void *) const165 Image RichPNG::ToImage(int64, const Value& data, Size sz, void *) const
166 {
167 	if(IsString(data)) {
168 		ImageAnyDraw iw(sz);
169 		Paint(data, iw, sz);
170 		return iw;
171 	}
172 	Image x = Image(data);
173 	Size outsz(min(sz.cx, 4 * x.GetWidth()), min(sz.cy, 4 * x.GetHeight()));
174 	return Rescale(x, outsz);
175 }
176 
177 INITBLOCK {
178 	RichObject::Register("PNG", &Single<RichPNG>());
179 };
180 
181 struct RichRawImage : public RichObjectType {
182 	virtual String GetTypeName(const Value& v) const;
183 	virtual Value  Read(const String& s) const;
184 	virtual String Write(const Value& v) const;
185 	virtual Size   GetPhysicalSize(const Value& data) const;
186 	virtual Size   GetPixelSize(const Value& data) const;
187 	virtual void   Paint(const Value& data, Draw& w, Size sz, void *) const;
188 	virtual Image  ToImage(int64, const Value& data, Size sz, void *) const;
189 };
190 
GetTypeName(const Value & v) const191 String RichRawImage::GetTypeName(const Value& v) const
192 {
193 	return "rawimage";
194 }
195 
Read(const String & s) const196 Value RichRawImage::Read(const String& s) const
197 {
198 	return s;
199 }
200 
Write(const Value & v) const201 String RichRawImage::Write(const Value& v) const
202 {
203 	return v;
204 }
205 
GetPhysicalSize(const Value & data) const206 Size RichRawImage::GetPhysicalSize(const Value& data) const
207 {
208 	String s = data;
209 	StringStream ss(s);
210 	One<StreamRaster> r = StreamRaster::OpenAny(ss);
211 	if(r)
212 		return r->GetInfo().dots;
213 	else
214 	if(IsString(data) && IsSVG(~data)) {
215 		Rectf f = GetSVGBoundingBox(~data);
216 		Zoom z = GetRichTextStdScreenZoom();
217 		return z.d * (Size)f.GetSize() / z.m;
218 	}
219 	return Size(0, 0);
220 }
221 
GetPixelSize(const Value & data) const222 Size RichRawImage::GetPixelSize(const Value& data) const
223 {
224 	String s = data;
225 	StringStream ss(s);
226 	One<StreamRaster> r = StreamRaster::OpenAny(ss);
227 	if(r)
228 		return r->GetSize();
229 	else
230 	if(IsString(data) && IsSVG(~data)) {
231 		Rectf f = GetSVGBoundingBox(~data);
232 		return (Size)f.GetSize();
233 	}
234 	return Size(0, 0);
235 }
236 
Paint(const Value & data,Draw & w,Size sz,void *) const237 void RichRawImage::Paint(const Value& data, Draw& w, Size sz, void *) const
238 {
239 	String s = data;
240 	StringStream ss(s);
241 	One<StreamRaster> r = StreamRaster::OpenAny(ss);
242 	if(r) {
243 		Size isz = r->GetSize();
244 		if(isz.cx * isz.cy > sz.cx * sz.cy) { // conserve memory by scaling down from source
245 			ImageEncoder m;
246 			Rescale(m, sz, *r, r->GetSize());
247 			w.DrawImage(0, 0, sz.cx, sz.cy, m);
248 		}
249 		else
250 			w.DrawImage(0, 0, sz.cx, sz.cy, r->GetImage()); // scale up by Draw to give e.g. PDF chance to store unscaled
251 	}
252 	else
253 	if(IsString(data) && IsSVG(~data))
254 		w.DrawImage(0, 0, RenderSVGImage(sz, ~data));
255 }
256 
ToImage(int64 serial_id,const Value & data,Size sz,void *) const257 Image RichRawImage::ToImage(int64 serial_id, const Value& data, Size sz, void *) const
258 {
259 	String s = data;
260 	StringStream ss(s);
261 	One<StreamRaster> r = StreamRaster::OpenAny(ss);
262 	if(r) {
263 		struct ImgFormatLoader : ImageMaker {
264 			int64  serial_id;
265 			String s;
266 
267 			virtual String Key() const  { String x; RawCat(x, serial_id); return x; }
268 			virtual Image  Make() const {
269 				StringStream ss(s);
270 				One<StreamRaster> r = StreamRaster::OpenAny(ss);
271 				return r ? r->GetImage() : Image();
272 			}
273 		} loader;
274 		loader.serial_id = serial_id;
275 		loader.s = s;
276 		return Rescale(MakeImage(loader), sz);
277 	}
278 	else
279 	if(IsString(data) && IsSVG(~data))
280 		return RenderSVGImage(sz, ~data);
281 	return Null;
282 }
283 
284 INITBLOCK {
285 	RichObject::Register("rawimage", &Single<RichRawImage>());
286 };
287 
CreateRawImageObject(const String & s,int cx,int cy)288 RichObject CreateRawImageObject(const String& s, int cx, int cy)
289 {
290 	RichObject o = RichObject("rawimage", s);
291 	o.InitSize(cx, cy);
292 	return o;
293 }
294 
295 struct RichImlImage : public RichObjectType {
296 	virtual String GetTypeName(const Value& v) const;
297 	virtual Size   GetPhysicalSize(const Value& data) const;
298 	virtual Size   GetPixelSize(const Value& data) const;
299 	virtual void   Paint(const Value& data, Draw& w, Size sz) const;
300 	virtual Image  ToImage(int64, const Value& data, Size sz, void *) const;
301 	virtual bool   IsText() const;
302 
303 	Image Get(const Value& v) const;
304 };
305 
Get(const Value & v) const306 Image RichImlImage::Get(const Value& v) const
307 {
308 	return GetImlImage((String)v);
309 }
310 
GetTypeName(const Value & v) const311 String RichImlImage::GetTypeName(const Value& v) const
312 {
313 	return "iml";
314 }
315 
IsText() const316 bool RichImlImage::IsText() const
317 {
318 	return true;
319 }
320 
GetPhysicalSize(const Value & data) const321 Size RichImlImage::GetPhysicalSize(const Value& data) const
322 {
323 	return Get(data).GetSize();
324 }
325 
GetPixelSize(const Value & data) const326 Size RichImlImage::GetPixelSize(const Value& data) const
327 {
328 	return Get(data).GetSize();
329 }
330 
Paint(const Value & data,Draw & w,Size sz) const331 void RichImlImage::Paint(const Value& data, Draw& w, Size sz) const
332 {
333 	w.DrawImage(0, 0, sz.cx, sz.cy, Get(data));
334 }
335 
ToImage(int64,const Value & data,Size sz,void *) const336 Image RichImlImage::ToImage(int64, const Value& data, Size sz, void *) const
337 {
338 	return Rescale(Get(data), sz);
339 }
340 
341 INITBLOCK {
342 	RichObject::Register("iml", &Single<RichImlImage>());
343 };
344 
345 #endif
346 
INITIALIZER(RichImage)347 INITIALIZER(RichImage) {}
348 
349 }
350