2 * draw.c - draw functions
4 * Copyright © 2007-2009 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <cairo-xcb.h>
32 #include "globalconf.h"
35 #include "common/xutil.h"
37 /** Convert text from any charset to UTF-8 using iconv.
38 * \param iso The ISO string to convert.
39 * \param len The string size.
40 * \param dest The destination pointer. Memory will be allocated, up to you to
41 * free, like any char *.
42 * \param dlen The destination length, can be NULL.
43 * \return True if conversion was done.
46 draw_iso2utf8(const char *iso
, size_t len
, char **dest
, ssize_t
*dlen
)
48 static iconv_t iso2utf8
= (iconv_t
) -1;
49 static int8_t dont_need_convert
= -1;
51 if(dont_need_convert
== -1)
52 dont_need_convert
= !a_strcmp(nl_langinfo(CODESET
), "UTF-8");
54 if(!len
|| dont_need_convert
)
57 if(iso2utf8
== (iconv_t
) -1)
59 iso2utf8
= iconv_open("UTF-8", nl_langinfo(CODESET
));
60 if(iso2utf8
== (iconv_t
) -1)
63 warn("unable to convert text from %s to UTF-8, not available",
64 nl_langinfo(CODESET
));
66 warn("unable to convert text: %s", strerror(errno
));
72 size_t orig_utf8len
, utf8len
;
75 orig_utf8len
= utf8len
= 2 * len
+ 1;
76 utf8
= *dest
= p_new(char, utf8len
);
78 if(iconv(iso2utf8
, (char **) &iso
, &len
, &utf8
, &utf8len
) == (size_t) -1)
80 warn("text conversion failed: %s", strerror(errno
));
86 *dlen
= orig_utf8len
- utf8len
;
91 static cairo_user_data_key_t data_key
;
99 /** Create a surface object on the lua stack from this image data.
100 * \param L The lua stack.
101 * \param width The width of the image.
102 * \param height The height of the image
103 * \param data The image's data in ARGB format, will be copied by this function.
104 * \return Number of items pushed on the lua stack.
107 luaA_surface_from_data(lua_State
*L
, int width
, int height
, uint32_t *data
)
109 unsigned long int len
= width
* height
;
111 uint32_t *buffer
= p_new(uint32_t, len
);
112 cairo_surface_t
*surface
;
114 /* Cairo wants premultiplied alpha, meh :( */
115 for(i
= 0; i
< len
; i
++)
117 uint8_t a
= (data
[i
] >> 24) & 0xff;
118 double alpha
= a
/ 255.0;
119 uint8_t r
= ((data
[i
] >> 16) & 0xff) * alpha
;
120 uint8_t g
= ((data
[i
] >> 8) & 0xff) * alpha
;
121 uint8_t b
= ((data
[i
] >> 0) & 0xff) * alpha
;
122 buffer
[i
] = (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
126 cairo_image_surface_create_for_data((unsigned char *) buffer
,
131 /* This makes sure that buffer will be freed */
132 cairo_surface_set_user_data(surface
, &data_key
, buffer
, &free_data
);
134 /* This will increase the reference count of the surface */
135 int ret
= oocairo_surface_push(globalconf
.L
, surface
);
136 /* So we have to drop our own reference */
137 cairo_surface_destroy(surface
);
142 /** Duplicate the specified image surface.
143 * \param surface The surface to copy
144 * \return A pointer to a new cairo image surface.
147 draw_dup_image_surface(cairo_surface_t
*surface
)
149 cairo_surface_t
*res
= cairo_image_surface_create(
150 cairo_image_surface_get_format(surface
),
151 cairo_image_surface_get_width(surface
),
152 cairo_image_surface_get_height(surface
));
154 cairo_t
*cr
= cairo_create(res
);
155 cairo_set_source_surface(cr
, surface
, 0, 0);
156 cairo_set_operator(cr
, CAIRO_OPERATOR_SOURCE
);
163 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80