1#pragma once
2
3/* Generated with cbindgen:0.26.0 */
4
5#include <cstdarg>
6#include <cstdint>
7#include <cstdlib>
8#include <ostream>
9#include <new>
10#include "slint_enums_internal.h"
11namespace slint::cbindgen_private { struct ParsedSVG{}; struct HTMLImage{}; using namespace vtable; namespace types{ struct NineSliceImage{}; } }
12
13namespace slint {
14namespace cbindgen_private {
15namespace types {
16
17/// This enum describes the origin to use when rendering a borrowed OpenGL texture.
18/// Use this with [`BorrowedOpenGLTextureBuilder::origin`].
19enum class BorrowedOpenGLTextureOrigin : uint8_t {
20 /// The top-left of the texture is the top-left of the texture drawn on the screen.
21 TopLeft,
22 /// The bottom-left of the texture is the top-left of the texture draw on the screen,
23 /// flipping it vertically.
24 BottomLeft,
25};
26
27/// The pixel format of a StaticTexture
28enum class PixelFormat : uint8_t {
29 /// red, green, blue. 24bits.
30 Rgb,
31 /// Red, green, blue, alpha. 32bits.
32 Rgba,
33 /// Red, green, blue, alpha. 32bits. The color are premultiplied by alpha
34 RgbaPremultiplied,
35 /// Alpha map. 8bits. Each pixel is an alpha value. The color is specified separately.
36 AlphaMap,
37};
38
39/// Represent a nine-slice image with the base image and the 4 borders
40struct NineSliceImage;
41
42/// ImageCacheKey encapsulates the different ways of indexing images in the
43/// cache of decoded images.
44union ImageCacheKey {
45 enum class Tag : uint8_t {
46 /// This variant indicates that no image cache key can be created for the image.
47 /// For example this is the case for programmatically created images.
48 Invalid = 0,
49 /// The image is identified by its path on the file system.
50 Path = 1,
51#if defined(SLINT_TARGET_WASM)
52 /// The image is identified by a URL.
53 URL = 2,
54#endif
55 /// The image is identified by the static address of its encoded data.
56 EmbeddedData = 3,
57 };
58
59 struct Path_Body {
60 Tag tag;
61 SharedString _0;
62
63 bool operator==(const Path_Body& other) const {
64 return _0 == other._0;
65 }
66 bool operator!=(const Path_Body& other) const {
67 return _0 != other._0;
68 }
69 };
70
71#if defined(SLINT_TARGET_WASM)
72 struct URL_Body {
73 Tag tag;
74 SharedString _0;
75
76 bool operator==(const URL_Body& other) const {
77 return _0 == other._0;
78 }
79 bool operator!=(const URL_Body& other) const {
80 return _0 != other._0;
81 }
82 };
83#endif
84
85 struct EmbeddedData_Body {
86 Tag tag;
87 uintptr_t _0;
88
89 bool operator==(const EmbeddedData_Body& other) const {
90 return _0 == other._0;
91 }
92 bool operator!=(const EmbeddedData_Body& other) const {
93 return _0 != other._0;
94 }
95 };
96
97 struct {
98 Tag tag;
99 };
100 Path_Body path;
101#if defined(SLINT_TARGET_WASM)
102 URL_Body url;
103#endif
104 EmbeddedData_Body embedded_data;
105
106 static ImageCacheKey Invalid() {
107 ImageCacheKey result;
108 result.tag = Tag::Invalid;
109 return result;
110 }
111
112 bool IsInvalid() const {
113 return tag == Tag::Invalid;
114 }
115
116 static ImageCacheKey Path(const SharedString &_0) {
117 ImageCacheKey result;
118 ::new (&result.path._0) (SharedString)(_0);
119 result.tag = Tag::Path;
120 return result;
121 }
122
123 bool IsPath() const {
124 return tag == Tag::Path;
125 }
126
127#if defined(SLINT_TARGET_WASM)
128 static ImageCacheKey URL(const SharedString &_0) {
129 ImageCacheKey result;
130 ::new (&result.url._0) (SharedString)(_0);
131 result.tag = Tag::URL;
132 return result;
133 }
134
135 bool IsURL() const {
136 return tag == Tag::URL;
137 }
138#endif
139
140 static ImageCacheKey EmbeddedData(const uintptr_t &_0) {
141 ImageCacheKey result;
142 ::new (&result.embedded_data._0) (uintptr_t)(_0);
143 result.tag = Tag::EmbeddedData;
144 return result;
145 }
146
147 bool IsEmbeddedData() const {
148 return tag == Tag::EmbeddedData;
149 }
150
151 bool operator==(const ImageCacheKey& other) const {
152 if (tag != other.tag) {
153 return false;
154 }
155 switch (tag) {
156 case Tag::Path: return path == other.path;
157#if defined(SLINT_TARGET_WASM)
158 case Tag::URL: return url == other.url;
159#endif
160 case Tag::EmbeddedData: return embedded_data == other.embedded_data;
161 default: break;
162 }
163 return true;
164 }
165
166 bool operator!=(const ImageCacheKey& other) const {
167 return !(*this == other);
168 }
169
170 private:
171 ImageCacheKey() {
172
173 }
174 public:
175
176
177 ~ImageCacheKey() {
178 switch (tag) {
179 case Tag::Path: path.~Path_Body(); break;
180#if defined(SLINT_TARGET_WASM)
181 case Tag::URL: url.~URL_Body(); break;
182#endif
183 case Tag::EmbeddedData: embedded_data.~EmbeddedData_Body(); break;
184 default: break;
185 }
186 }
187
188 ImageCacheKey(const ImageCacheKey& other)
189 : tag(other.tag) {
190 switch (tag) {
191 case Tag::Path: ::new (&path) (Path_Body)(other.path); break;
192#if defined(SLINT_TARGET_WASM)
193 case Tag::URL: ::new (&url) (URL_Body)(other.url); break;
194#endif
195 case Tag::EmbeddedData: ::new (&embedded_data) (EmbeddedData_Body)(other.embedded_data); break;
196 default: break;
197 }
198 }
199 ImageCacheKey& operator=(const ImageCacheKey& other) {
200 if (this != &other) {
201 this->~ImageCacheKey();
202 new (this) ImageCacheKey(other);
203 }
204 return *this;
205 }
206};
207
208/// SharedPixelBuffer is a container for storing image data as pixels. It is
209/// internally reference counted and cheap to clone.
210///
211/// You can construct a new empty shared pixel buffer with [`SharedPixelBuffer::new`],
212/// or you can clone it from an existing contiguous buffer that you might already have, using
213/// [`SharedPixelBuffer::clone_from_slice`].
214///
215/// See the documentation for [`Image`] for examples how to use this type to integrate
216/// Slint with external rendering functions.
217template<typename Pixel>
218struct SharedPixelBuffer {
219 uint32_t width;
220 uint32_t height;
221 SharedVector<Pixel> data;
222
223 bool operator==(const SharedPixelBuffer& other) const {
224 return width == other.width &&
225 height == other.height &&
226 data == other.data;
227 }
228 bool operator!=(const SharedPixelBuffer& other) const {
229 return width != other.width ||
230 height != other.height ||
231 data != other.data;
232 }
233};
234
235/// SharedImageBuffer is a container for images that are stored in CPU accessible memory.
236///
237/// The SharedImageBuffer's variants represent the different common formats for encoding
238/// images in pixels.
239struct SharedImageBuffer {
240 enum class Tag {
241 /// This variant holds the data for an image where each pixel has three color channels (red, green,
242 /// and blue) and each channel is encoded as unsigned byte.
243 RGB8,
244 /// This variant holds the data for an image where each pixel has four color channels (red, green,
245 /// blue and alpha) and each channel is encoded as unsigned byte.
246 RGBA8,
247 /// This variant holds the data for an image where each pixel has four color channels (red, green,
248 /// blue and alpha) and each channel is encoded as unsigned byte. In contrast to [`Self::RGBA8`],
249 /// this variant assumes that the alpha channel is also already multiplied to each red, green and blue
250 /// component of each pixel.
251 /// Only construct this format if you know that your pixels are encoded this way. It is more efficient
252 /// for rendering.
253 RGBA8Premultiplied,
254 };
255
256 struct RGB8_Body {
257 SharedPixelBuffer<Rgb8Pixel> _0;
258
259 bool operator==(const RGB8_Body& other) const {
260 return _0 == other._0;
261 }
262 bool operator!=(const RGB8_Body& other) const {
263 return _0 != other._0;
264 }
265 };
266
267 struct RGBA8_Body {
268 SharedPixelBuffer<Rgba8Pixel> _0;
269
270 bool operator==(const RGBA8_Body& other) const {
271 return _0 == other._0;
272 }
273 bool operator!=(const RGBA8_Body& other) const {
274 return _0 != other._0;
275 }
276 };
277
278 struct RGBA8Premultiplied_Body {
279 SharedPixelBuffer<Rgba8Pixel> _0;
280
281 bool operator==(const RGBA8Premultiplied_Body& other) const {
282 return _0 == other._0;
283 }
284 bool operator!=(const RGBA8Premultiplied_Body& other) const {
285 return _0 != other._0;
286 }
287 };
288
289 Tag tag;
290 union {
291 RGB8_Body rgb8;
292 RGBA8_Body rgba8;
293 RGBA8Premultiplied_Body rgba8_premultiplied;
294 };
295
296 static SharedImageBuffer RGB8(const SharedPixelBuffer<Rgb8Pixel> &_0) {
297 SharedImageBuffer result;
298 ::new (&result.rgb8._0) (SharedPixelBuffer<Rgb8Pixel>)(_0);
299 result.tag = Tag::RGB8;
300 return result;
301 }
302
303 bool IsRGB8() const {
304 return tag == Tag::RGB8;
305 }
306
307 static SharedImageBuffer RGBA8(const SharedPixelBuffer<Rgba8Pixel> &_0) {
308 SharedImageBuffer result;
309 ::new (&result.rgba8._0) (SharedPixelBuffer<Rgba8Pixel>)(_0);
310 result.tag = Tag::RGBA8;
311 return result;
312 }
313
314 bool IsRGBA8() const {
315 return tag == Tag::RGBA8;
316 }
317
318 static SharedImageBuffer RGBA8Premultiplied(const SharedPixelBuffer<Rgba8Pixel> &_0) {
319 SharedImageBuffer result;
320 ::new (&result.rgba8_premultiplied._0) (SharedPixelBuffer<Rgba8Pixel>)(_0);
321 result.tag = Tag::RGBA8Premultiplied;
322 return result;
323 }
324
325 bool IsRGBA8Premultiplied() const {
326 return tag == Tag::RGBA8Premultiplied;
327 }
328
329 bool operator==(const SharedImageBuffer& other) const {
330 if (tag != other.tag) {
331 return false;
332 }
333 switch (tag) {
334 case Tag::RGB8: return rgb8 == other.rgb8;
335 case Tag::RGBA8: return rgba8 == other.rgba8;
336 case Tag::RGBA8Premultiplied: return rgba8_premultiplied == other.rgba8_premultiplied;
337
338 }
339 return true;
340 }
341
342 bool operator!=(const SharedImageBuffer& other) const {
343 return !(*this == other);
344 }
345
346 private:
347 SharedImageBuffer() {
348
349 }
350 public:
351
352
353 ~SharedImageBuffer() {
354 switch (tag) {
355 case Tag::RGB8: rgb8.~RGB8_Body(); break;
356 case Tag::RGBA8: rgba8.~RGBA8_Body(); break;
357 case Tag::RGBA8Premultiplied: rgba8_premultiplied.~RGBA8Premultiplied_Body(); break;
358
359 }
360 }
361
362 SharedImageBuffer(const SharedImageBuffer& other)
363 : tag(other.tag) {
364 switch (tag) {
365 case Tag::RGB8: ::new (&rgb8) (RGB8_Body)(other.rgb8); break;
366 case Tag::RGBA8: ::new (&rgba8) (RGBA8_Body)(other.rgba8); break;
367 case Tag::RGBA8Premultiplied: ::new (&rgba8_premultiplied) (RGBA8Premultiplied_Body)(other.rgba8_premultiplied); break;
368
369 }
370 }
371 SharedImageBuffer& operator=(const SharedImageBuffer& other) {
372 if (this != &other) {
373 this->~SharedImageBuffer();
374 new (this) SharedImageBuffer(other);
375 }
376 return *this;
377 }
378};
379
380/// 2D Size in integer coordinates
381using IntSize = Size2D<uint32_t>;
382
383struct OpaqueImageVTable {
384 Layout (*drop_in_place)(VRefMut<OpaqueImageVTable>);
385 void (*dealloc)(const OpaqueImageVTable*, uint8_t *ptr, Layout layout);
386 /// Returns the image size
387 IntSize (*size)(VRef<OpaqueImageVTable>);
388 /// Returns a cache key
389 ImageCacheKey (*cache_key)(VRef<OpaqueImageVTable>);
390
391 bool operator==(const OpaqueImageVTable& other) const {
392 return drop_in_place == other.drop_in_place &&
393 dealloc == other.dealloc &&
394 size == other.size &&
395 cache_key == other.cache_key;
396 }
397 bool operator!=(const OpaqueImageVTable& other) const {
398 return drop_in_place != other.drop_in_place ||
399 dealloc != other.dealloc ||
400 size != other.size ||
401 cache_key != other.cache_key;
402 }
403};
404
405/// Expand IntRect so that cbindgen can see it. ( is in fact euclid::default::Rect<i32>)
406struct IntRect {
407 int32_t x;
408 int32_t y;
409 int32_t width;
410 int32_t height;
411
412 bool operator==(const IntRect& other) const {
413 return x == other.x &&
414 y == other.y &&
415 width == other.width &&
416 height == other.height;
417 }
418 bool operator!=(const IntRect& other) const {
419 return x != other.x ||
420 y != other.y ||
421 width != other.width ||
422 height != other.height;
423 }
424};
425
426/// Some raw pixel data which is typically stored in the binary
427struct StaticTexture {
428 /// The position and size of the texture within the image
429 IntRect rect;
430 /// The pixel format of this texture
431 PixelFormat format;
432 /// The color, for the alpha map ones
433 Color color;
434 /// index in the data array
435 uintptr_t index;
436
437 bool operator==(const StaticTexture& other) const {
438 return rect == other.rect &&
439 format == other.format &&
440 color == other.color &&
441 index == other.index;
442 }
443 bool operator!=(const StaticTexture& other) const {
444 return rect != other.rect ||
445 format != other.format ||
446 color != other.color ||
447 index != other.index;
448 }
449};
450
451/// A texture is stored in read-only memory and may be composed of sub-textures.
452struct StaticTextures {
453 /// The total size of the image (this might not be the size of the full image
454 /// as some transparent part are not part of any texture)
455 IntSize size;
456 /// The size of the image before the compiler applied any scaling
457 IntSize original_size;
458 /// The pixel data referenced by the textures
459 Slice<uint8_t> data;
460 /// The list of textures
461 Slice<StaticTexture> textures;
462
463 bool operator==(const StaticTextures& other) const {
464 return size == other.size &&
465 original_size == other.original_size &&
466 data == other.data &&
467 textures == other.textures;
468 }
469 bool operator!=(const StaticTextures& other) const {
470 return size != other.size ||
471 original_size != other.original_size ||
472 data != other.data ||
473 textures != other.textures;
474 }
475};
476
477#if !defined(SLINT_TARGET_WASM)
478/// This structure contains fields to identify and render an OpenGL texture that Slint borrows from the application code.
479/// Use this to embed a native OpenGL texture into a Slint scene.
480///
481/// The ownership of the texture remains with the application. It is the application's responsibility to delete the texture
482/// when it is not used anymore.
483///
484/// Note that only 2D RGBA textures are supported.
485struct BorrowedOpenGLTexture {
486 /// The id or name of the texture, as created by [`glGenTextures`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glGenTextures.xhtml).
487 uint32_t texture_id;
488 /// The size of the texture in pixels.
489 IntSize size;
490 /// Origin of the texture when rendering.
491 BorrowedOpenGLTextureOrigin origin;
492
493 bool operator==(const BorrowedOpenGLTexture& other) const {
494 return texture_id == other.texture_id &&
495 size == other.size &&
496 origin == other.origin;
497 }
498 bool operator!=(const BorrowedOpenGLTexture& other) const {
499 return texture_id != other.texture_id ||
500 size != other.size ||
501 origin != other.origin;
502 }
503};
504#endif
505
506/// A resource is a reference to binary data, for example images. They can be accessible on the file
507/// system or embedded in the resulting binary. Or they might be URLs to a web server and a downloaded
508/// is necessary before they can be used.
509union ImageInner {
510 enum class Tag : uint8_t {
511 /// A resource that does not represent any data.
512 ImageInner_None = 0,
513 ImageInner_EmbeddedImage = 1,
514 ImageInner_Svg = 2,
515 ImageInner_StaticTextures = 3,
516#if defined(SLINT_TARGET_WASM)
517 ImageInner_HTMLImage = 4,
518#endif
519 ImageInner_BackendStorage = 5,
520#if !defined(SLINT_TARGET_WASM)
521 ImageInner_BorrowedOpenGLTexture = 6,
522#endif
523 ImageInner_NineSlice = 7,
524 };
525
526 struct ImageInner_EmbeddedImage_Body {
527 Tag tag;
528 ImageCacheKey cache_key;
529 SharedImageBuffer buffer;
530
531 bool operator==(const ImageInner_EmbeddedImage_Body& other) const {
532 return cache_key == other.cache_key &&
533 buffer == other.buffer;
534 }
535 bool operator!=(const ImageInner_EmbeddedImage_Body& other) const {
536 return cache_key != other.cache_key ||
537 buffer != other.buffer;
538 }
539 };
540
541 struct ImageInner_Svg_Body {
542 Tag tag;
543 VRc<OpaqueImageVTable, ParsedSVG> _0;
544
545 bool operator==(const ImageInner_Svg_Body& other) const {
546 return _0 == other._0;
547 }
548 bool operator!=(const ImageInner_Svg_Body& other) const {
549 return _0 != other._0;
550 }
551 };
552
553 struct ImageInner_StaticTextures_Body {
554 Tag tag;
555 const StaticTextures *_0;
556
557 bool operator==(const ImageInner_StaticTextures_Body& other) const {
558 return _0 == other._0;
559 }
560 bool operator!=(const ImageInner_StaticTextures_Body& other) const {
561 return _0 != other._0;
562 }
563 };
564
565#if defined(SLINT_TARGET_WASM)
566 struct ImageInner_HTMLImage_Body {
567 Tag tag;
568 VRc<OpaqueImageVTable, HTMLImage> _0;
569
570 bool operator==(const ImageInner_HTMLImage_Body& other) const {
571 return _0 == other._0;
572 }
573 bool operator!=(const ImageInner_HTMLImage_Body& other) const {
574 return _0 != other._0;
575 }
576 };
577#endif
578
579 struct ImageInner_BackendStorage_Body {
580 Tag tag;
581 VRc<OpaqueImageVTable> _0;
582
583 bool operator==(const ImageInner_BackendStorage_Body& other) const {
584 return _0 == other._0;
585 }
586 bool operator!=(const ImageInner_BackendStorage_Body& other) const {
587 return _0 != other._0;
588 }
589 };
590
591#if !defined(SLINT_TARGET_WASM)
592 struct ImageInner_BorrowedOpenGLTexture_Body {
593 Tag tag;
594 BorrowedOpenGLTexture _0;
595
596 bool operator==(const ImageInner_BorrowedOpenGLTexture_Body& other) const {
597 return _0 == other._0;
598 }
599 bool operator!=(const ImageInner_BorrowedOpenGLTexture_Body& other) const {
600 return _0 != other._0;
601 }
602 };
603#endif
604
605 struct ImageInner_NineSlice_Body {
606 Tag tag;
607 VRc<OpaqueImageVTable, NineSliceImage> _0;
608
609 bool operator==(const ImageInner_NineSlice_Body& other) const {
610 return _0 == other._0;
611 }
612 bool operator!=(const ImageInner_NineSlice_Body& other) const {
613 return _0 != other._0;
614 }
615 };
616
617 struct {
618 Tag tag;
619 };
620 ImageInner_EmbeddedImage_Body embedded_image;
621 ImageInner_Svg_Body svg;
622 ImageInner_StaticTextures_Body static_textures;
623#if defined(SLINT_TARGET_WASM)
624 ImageInner_HTMLImage_Body html_image;
625#endif
626 ImageInner_BackendStorage_Body backend_storage;
627#if !defined(SLINT_TARGET_WASM)
628 ImageInner_BorrowedOpenGLTexture_Body borrowed_open_gl_texture;
629#endif
630 ImageInner_NineSlice_Body nine_slice;
631
632 static ImageInner ImageInner_None() {
633 ImageInner result;
634 result.tag = Tag::ImageInner_None;
635 return result;
636 }
637
638 bool IsImageInner_None() const {
639 return tag == Tag::ImageInner_None;
640 }
641
642 static ImageInner ImageInner_EmbeddedImage(const ImageCacheKey &cache_key,
643 const SharedImageBuffer &buffer) {
644 ImageInner result;
645 ::new (&result.embedded_image.cache_key) (ImageCacheKey)(cache_key);
646 ::new (&result.embedded_image.buffer) (SharedImageBuffer)(buffer);
647 result.tag = Tag::ImageInner_EmbeddedImage;
648 return result;
649 }
650
651 bool IsImageInner_EmbeddedImage() const {
652 return tag == Tag::ImageInner_EmbeddedImage;
653 }
654
655 static ImageInner ImageInner_Svg(const VRc<OpaqueImageVTable, ParsedSVG> &_0) {
656 ImageInner result;
657 ::new (&result.svg._0) (VRc<OpaqueImageVTable, ParsedSVG>)(_0);
658 result.tag = Tag::ImageInner_Svg;
659 return result;
660 }
661
662 bool IsImageInner_Svg() const {
663 return tag == Tag::ImageInner_Svg;
664 }
665
666 static ImageInner ImageInner_StaticTextures(const StaticTextures *const &_0) {
667 ImageInner result;
668 ::new (&result.static_textures._0) (const StaticTextures*)(_0);
669 result.tag = Tag::ImageInner_StaticTextures;
670 return result;
671 }
672
673 bool IsImageInner_StaticTextures() const {
674 return tag == Tag::ImageInner_StaticTextures;
675 }
676
677#if defined(SLINT_TARGET_WASM)
678 static ImageInner ImageInner_HTMLImage(const VRc<OpaqueImageVTable, HTMLImage> &_0) {
679 ImageInner result;
680 ::new (&result.html_image._0) (VRc<OpaqueImageVTable, HTMLImage>)(_0);
681 result.tag = Tag::ImageInner_HTMLImage;
682 return result;
683 }
684
685 bool IsImageInner_HTMLImage() const {
686 return tag == Tag::ImageInner_HTMLImage;
687 }
688#endif
689
690 static ImageInner ImageInner_BackendStorage(const VRc<OpaqueImageVTable> &_0) {
691 ImageInner result;
692 ::new (&result.backend_storage._0) (VRc<OpaqueImageVTable>)(_0);
693 result.tag = Tag::ImageInner_BackendStorage;
694 return result;
695 }
696
697 bool IsImageInner_BackendStorage() const {
698 return tag == Tag::ImageInner_BackendStorage;
699 }
700
701#if !defined(SLINT_TARGET_WASM)
702 static ImageInner ImageInner_BorrowedOpenGLTexture(const BorrowedOpenGLTexture &_0) {
703 ImageInner result;
704 ::new (&result.borrowed_open_gl_texture._0) (BorrowedOpenGLTexture)(_0);
705 result.tag = Tag::ImageInner_BorrowedOpenGLTexture;
706 return result;
707 }
708
709 bool IsImageInner_BorrowedOpenGLTexture() const {
710 return tag == Tag::ImageInner_BorrowedOpenGLTexture;
711 }
712#endif
713
714 static ImageInner ImageInner_NineSlice(const VRc<OpaqueImageVTable, NineSliceImage> &_0) {
715 ImageInner result;
716 ::new (&result.nine_slice._0) (VRc<OpaqueImageVTable, NineSliceImage>)(_0);
717 result.tag = Tag::ImageInner_NineSlice;
718 return result;
719 }
720
721 bool IsImageInner_NineSlice() const {
722 return tag == Tag::ImageInner_NineSlice;
723 }
724
725 bool operator==(const ImageInner& other) const {
726 if (tag != other.tag) {
727 return false;
728 }
729 switch (tag) {
730 case Tag::ImageInner_EmbeddedImage: return embedded_image == other.embedded_image;
731 case Tag::ImageInner_Svg: return svg == other.svg;
732 case Tag::ImageInner_StaticTextures: return static_textures == other.static_textures;
733#if defined(SLINT_TARGET_WASM)
734 case Tag::ImageInner_HTMLImage: return html_image == other.html_image;
735#endif
736 case Tag::ImageInner_BackendStorage: return backend_storage == other.backend_storage;
737#if !defined(SLINT_TARGET_WASM)
738 case Tag::ImageInner_BorrowedOpenGLTexture: return borrowed_open_gl_texture == other.borrowed_open_gl_texture;
739#endif
740 case Tag::ImageInner_NineSlice: return nine_slice == other.nine_slice;
741 default: break;
742 }
743 return true;
744 }
745
746 bool operator!=(const ImageInner& other) const {
747 return !(*this == other);
748 }
749
750 private:
751 ImageInner() {
752
753 }
754 public:
755
756
757 ~ImageInner() {
758 switch (tag) {
759 case Tag::ImageInner_EmbeddedImage: embedded_image.~ImageInner_EmbeddedImage_Body(); break;
760 case Tag::ImageInner_Svg: svg.~ImageInner_Svg_Body(); break;
761 case Tag::ImageInner_StaticTextures: static_textures.~ImageInner_StaticTextures_Body(); break;
762#if defined(SLINT_TARGET_WASM)
763 case Tag::ImageInner_HTMLImage: html_image.~ImageInner_HTMLImage_Body(); break;
764#endif
765 case Tag::ImageInner_BackendStorage: backend_storage.~ImageInner_BackendStorage_Body(); break;
766#if !defined(SLINT_TARGET_WASM)
767 case Tag::ImageInner_BorrowedOpenGLTexture: borrowed_open_gl_texture.~ImageInner_BorrowedOpenGLTexture_Body(); break;
768#endif
769 case Tag::ImageInner_NineSlice: nine_slice.~ImageInner_NineSlice_Body(); break;
770 default: break;
771 }
772 }
773
774 ImageInner(const ImageInner& other)
775 : tag(other.tag) {
776 switch (tag) {
777 case Tag::ImageInner_EmbeddedImage: ::new (&embedded_image) (ImageInner_EmbeddedImage_Body)(other.embedded_image); break;
778 case Tag::ImageInner_Svg: ::new (&svg) (ImageInner_Svg_Body)(other.svg); break;
779 case Tag::ImageInner_StaticTextures: ::new (&static_textures) (ImageInner_StaticTextures_Body)(other.static_textures); break;
780#if defined(SLINT_TARGET_WASM)
781 case Tag::ImageInner_HTMLImage: ::new (&html_image) (ImageInner_HTMLImage_Body)(other.html_image); break;
782#endif
783 case Tag::ImageInner_BackendStorage: ::new (&backend_storage) (ImageInner_BackendStorage_Body)(other.backend_storage); break;
784#if !defined(SLINT_TARGET_WASM)
785 case Tag::ImageInner_BorrowedOpenGLTexture: ::new (&borrowed_open_gl_texture) (ImageInner_BorrowedOpenGLTexture_Body)(other.borrowed_open_gl_texture); break;
786#endif
787 case Tag::ImageInner_NineSlice: ::new (&nine_slice) (ImageInner_NineSlice_Body)(other.nine_slice); break;
788 default: break;
789 }
790 }
791 ImageInner& operator=(const ImageInner& other) {
792 if (this != &other) {
793 this->~ImageInner();
794 new (this) ImageInner(other);
795 }
796 return *this;
797 }
798};
799
800/// An image type that can be displayed by the Image element. You can construct
801/// Image objects from a path to an image file on disk, using [`Self::load_from_path`].
802///
803/// Another typical use-case is to render the image content with Rust code.
804/// For this it's most efficient to create a new SharedPixelBuffer with the known dimensions
805/// and pass the mutable slice to your rendering function. Afterwards you can create an
806/// Image.
807///
808/// The following example creates a 320x200 RGB pixel buffer and calls an external
809/// low_level_render() function to draw a shape into it. Finally the result is
810/// stored in an Image with [`Self::from_rgb8()`]:
811/// ```
812/// # use i_slint_core::graphics::{SharedPixelBuffer, Image, Rgb8Pixel};
813///
814/// fn low_level_render(width: u32, height: u32, buffer: &mut [u8]) {
815/// // render beautiful circle or other shapes here
816/// }
817///
818/// let mut pixel_buffer = SharedPixelBuffer::<Rgb8Pixel>::new(320, 200);
819///
820/// low_level_render(pixel_buffer.width(), pixel_buffer.height(),
821/// pixel_buffer.make_mut_bytes());
822///
823/// let image = Image::from_rgb8(pixel_buffer);
824/// ```
825///
826/// Another use-case is to import existing image data into Slint, by
827/// creating a new Image through cloning of another image type.
828///
829/// The following example uses the popular [image crate](https://docs.rs/image/) to
830/// load a `.png` file from disk, apply brightening filter on it and then import
831/// it into an [`Image`]:
832/// ```no_run
833/// # use i_slint_core::graphics::{SharedPixelBuffer, Image, Rgba8Pixel};
834/// let mut cat_image = image::open("cat.png").expect("Error loading cat image").into_rgba8();
835///
836/// image::imageops::colorops::brighten_in_place(&mut cat_image, 20);
837///
838/// let buffer = SharedPixelBuffer::<Rgba8Pixel>::clone_from_slice(
839/// cat_image.as_raw(),
840/// cat_image.width(),
841/// cat_image.height(),
842/// );
843/// let image = Image::from_rgba8(buffer);
844/// ```
845///
846/// A popular software (CPU) rendering library in Rust is tiny-skia. The following example shows
847/// how to use tiny-skia to render into a [`SharedPixelBuffer`]:
848/// ```
849/// # use i_slint_core::graphics::{SharedPixelBuffer, Image, Rgba8Pixel};
850/// let mut pixel_buffer = SharedPixelBuffer::<Rgba8Pixel>::new(640, 480);
851/// let width = pixel_buffer.width();
852/// let height = pixel_buffer.height();
853/// let mut pixmap = tiny_skia::PixmapMut::from_bytes(
854/// pixel_buffer.make_mut_bytes(), width, height
855/// ).unwrap();
856/// pixmap.fill(tiny_skia::Color::TRANSPARENT);
857///
858/// let circle = tiny_skia::PathBuilder::from_circle(320., 240., 150.).unwrap();
859///
860/// let mut paint = tiny_skia::Paint::default();
861/// paint.shader = tiny_skia::LinearGradient::new(
862/// tiny_skia::Point::from_xy(100.0, 100.0),
863/// tiny_skia::Point::from_xy(400.0, 400.0),
864/// vec![
865/// tiny_skia::GradientStop::new(0.0, tiny_skia::Color::from_rgba8(50, 127, 150, 200)),
866/// tiny_skia::GradientStop::new(1.0, tiny_skia::Color::from_rgba8(220, 140, 75, 180)),
867/// ],
868/// tiny_skia::SpreadMode::Pad,
869/// tiny_skia::Transform::identity(),
870/// ).unwrap();
871///
872/// pixmap.fill_path(&circle, &paint, tiny_skia::FillRule::Winding, Default::default(), None);
873///
874/// let image = Image::from_rgba8_premultiplied(pixel_buffer);
875/// ```
876///
877/// ### Sending Image to a thread
878///
879/// `Image` is not [`Send`], because it uses internal cache that are local to the Slint thread.
880/// If you want to create image data in a thread and send that to slint, construct the
881/// [`SharedPixelBuffer`] in a thread, and send that to Slint's UI thread.
882///
883/// ```rust,no_run
884/// # use i_slint_core::graphics::{SharedPixelBuffer, Image, Rgba8Pixel};
885/// std::thread::spawn(move || {
886/// let mut pixel_buffer = SharedPixelBuffer::<Rgba8Pixel>::new(640, 480);
887/// // ... fill the pixel_buffer with data as shown in the previous example ...
888/// slint::invoke_from_event_loop(move || {
889/// // this will run in the Slint's UI thread
890/// let image = Image::from_rgba8_premultiplied(pixel_buffer);
891/// // ... use the image, eg:
892/// // my_ui_handle.upgrade().unwrap().set_image(image);
893/// });
894/// });
895/// ```
896using Image = ImageInner;
897
898/// 2D Size
899using Size = Size2D<float>;
900
901extern "C" {
902
903void slint_image_load_from_path(const SharedString *path, Image *image);
904
905void slint_image_load_from_embedded_data(Slice<uint8_t> data, Slice<uint8_t> format, Image *image);
906
907IntSize slint_image_size(const Image *image);
908
909const SharedString *slint_image_path(const Image *image);
910
911void slint_image_from_embedded_textures(const StaticTextures *textures, Image *image);
912
913bool slint_image_compare_equal(const Image *image1, const Image *image2);
914
915/// Call [`Image::set_nine_slice_edges`]
916void slint_image_set_nine_slice_edges(Image *image,
917 uint16_t top,
918 uint16_t right,
919 uint16_t bottom,
920 uint16_t left);
921
922} // extern "C"
923
924} // namespace types
925} // namespace cbindgen_private
926} // namespace slint
927

source code of slint/target/debug/build/slint-cpp-d3acc71f258707cf/out/generated_include/slint_image_internal.h