1 /*
2  *                           0BSD
3  *
4  *                    BSD Zero Clause License
5  *
6  *  Copyright (c) 2019 Hermann Meyer
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted.
10 
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  *
19  */
20 
21 #include "xpngloader.h"
22 
23 /*
24  * @brief      load png data from binary blob into cairo surface
25 */
26 
png_stream_reader(void * _stream,unsigned char * data,unsigned int length)27 cairo_status_t png_stream_reader (void *_stream, unsigned char *data, unsigned int length) {
28     binary_stream * stream = (binary_stream *) _stream;
29     memcpy(data, &stream->data[stream->position],length);
30     stream->position += length;
31     return CAIRO_STATUS_SUCCESS;
32 }
33 
cairo_image_surface_create_from_stream(const unsigned char * name)34 cairo_surface_t *cairo_image_surface_create_from_stream ( const unsigned char* name) {
35     binary_stream png_stream;
36     png_stream.data = name;
37     png_stream.position = 0;
38     return cairo_image_surface_create_from_png_stream(&png_stream_reader, (void *)&png_stream);
39 }
40 
widget_get_png(Widget_t * w,const unsigned char * name)41 void widget_get_png(Widget_t *w, const unsigned char* name) {
42     cairo_surface_t *getpng = cairo_image_surface_create_from_stream (name);
43     int width = cairo_image_surface_get_width(getpng);
44     int height = cairo_image_surface_get_height(getpng);
45     cairo_surface_destroy(w->image);
46     w->image = NULL;
47 
48     w->image = cairo_surface_create_similar (w->surface,
49                         CAIRO_CONTENT_COLOR_ALPHA, width, height);
50     cairo_t *cri = cairo_create (w->image);
51     cairo_set_source_surface (cri, getpng,0,0);
52     cairo_paint (cri);
53     cairo_surface_destroy(getpng);
54     cairo_destroy(cri);
55 }
56 
widget_get_scaled_png(Widget_t * w,const unsigned char * name)57 void widget_get_scaled_png(Widget_t *w, const unsigned char* name) {
58     cairo_surface_t *getpng = cairo_image_surface_create_from_stream (name);
59     int width = cairo_image_surface_get_width(getpng);
60     int height = cairo_image_surface_get_height(getpng);
61     int width_t = w->scale.init_width;
62     int height_t = w->scale.init_height;
63     double x = (double)width_t/(double)width;
64     double y = (double)height_t/(double)height;
65     cairo_surface_destroy(w->image);
66     w->image = NULL;
67 
68     w->image = cairo_surface_create_similar (w->surface,
69                         CAIRO_CONTENT_COLOR_ALPHA, width_t, height_t);
70     cairo_t *cri = cairo_create (w->image);
71     cairo_scale(cri, x,y);
72     cairo_set_source_surface (cri, getpng,0,0);
73     cairo_paint (cri);
74     cairo_surface_destroy(getpng);
75     cairo_destroy(cri);
76 }
77 
widget_get_surface_ptr(Widget_t * w,Widget_t * wid)78 void widget_get_surface_ptr(Widget_t *w, Widget_t *wid) {
79     w->image = wid->image;
80     w->flags |= REUSE_IMAGE;
81 }
82 
surface_get_png(Widget_t * w,cairo_surface_t * sf,const unsigned char * name)83 cairo_surface_t * surface_get_png(Widget_t *w, cairo_surface_t *sf, const unsigned char* name) {
84     cairo_surface_t *getpng = cairo_image_surface_create_from_stream (name);
85     int width = cairo_image_surface_get_width(getpng);
86     int height = cairo_image_surface_get_height(getpng);
87 
88     sf = cairo_surface_create_similar (w->surface,
89                         CAIRO_CONTENT_COLOR_ALPHA, width, height);
90     cairo_t *cri = cairo_create (sf);
91     cairo_set_source_surface (cri, getpng,0,0);
92     cairo_paint (cri);
93     cairo_surface_destroy(getpng);
94     cairo_destroy(cri);
95     return sf;
96 }
97 
widget_set_icon_from_surface(Widget_t * w,Pixmap * icon_,cairo_surface_t * image)98 void widget_set_icon_from_surface(Widget_t *w, Pixmap *icon_, cairo_surface_t *image) {
99     int width = cairo_xlib_surface_get_width(image);
100     int height = cairo_xlib_surface_get_height(image);
101     XWindowAttributes atr;
102     XGetWindowAttributes (w->app->dpy, w->widget, &atr);
103     Pixmap icon = XCreatePixmap(w->app->dpy, w->widget, width, height, atr.depth);
104     cairo_surface_t *surface = cairo_xlib_surface_create (w->app->dpy, icon,
105                   DefaultVisual(w->app->dpy, DefaultScreen(w->app->dpy)), width, height);
106     cairo_t *cri = cairo_create (surface);
107     Colors *c = get_color_scheme(w->app, PRELIGHT_);
108     cairo_set_source_rgba(cri, c->bg[0],  c->bg[1], c->bg[2],  c->bg[3]);
109     cairo_paint(cri);
110     cairo_set_source_surface (cri, image,0,0);
111     cairo_paint(cri);
112     cairo_surface_destroy(surface);
113     cairo_destroy(cri);
114     icon_ = &icon;
115 
116     XWMHints* win_hints = XAllocWMHints();
117     assert(win_hints);
118     win_hints->flags = IconPixmapHint;
119     win_hints->icon_pixmap = icon;
120     XSetWMHints(w->app->dpy, w->widget, win_hints);
121     XFree(win_hints);
122 }
123 
widget_set_icon_from_png(Widget_t * w,Pixmap * icon_,const unsigned char * name)124 void widget_set_icon_from_png(Widget_t *w, Pixmap *icon_, const unsigned char* name) {
125     cairo_surface_t *image = cairo_image_surface_create_from_stream (name);
126     int width = cairo_image_surface_get_width(image);
127     int height = cairo_image_surface_get_height(image);
128     XWindowAttributes atr;
129     XGetWindowAttributes (w->app->dpy, w->widget, &atr);
130     Pixmap icon = XCreatePixmap(w->app->dpy, w->widget, width, height, atr.depth);
131     cairo_surface_t *surface = cairo_xlib_surface_create (w->app->dpy, icon,
132                   DefaultVisual(w->app->dpy, DefaultScreen(w->app->dpy)), width, height);
133     cairo_t *cri = cairo_create (surface);
134     Colors *c = get_color_scheme(w->app, PRELIGHT_);
135     cairo_set_source_rgba(cri, c->bg[0],  c->bg[1], c->bg[2],  c->bg[3]);
136     cairo_paint(cri);
137     cairo_set_source_surface (cri, image,0,0);
138     cairo_paint(cri);
139     cairo_surface_destroy(image);
140     cairo_surface_destroy(surface);
141     cairo_destroy(cri);
142     icon_ = &icon;
143 
144     XWMHints* win_hints = XAllocWMHints();
145     assert(win_hints);
146     win_hints->flags = IconPixmapHint;
147     win_hints->icon_pixmap = icon;
148     XSetWMHints(w->app->dpy, w->widget, win_hints);
149     XFree(win_hints);
150 }
151 
152 /*
153 cairo_surface_t* iamge = cairo_image_surface_create_from_stream( LDVAR(image_name_png));
154 */
155