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