2007-10-03 17:26:14 +02:00
|
|
|
/*
|
2007-09-12 14:29:51 +02:00
|
|
|
* draw.c - draw functions
|
2007-10-03 17:26:14 +02:00
|
|
|
*
|
2009-07-10 16:26:49 +02:00
|
|
|
* Copyright © 2007-2009 Julien Danjou <julien@danjou.info>
|
2007-10-03 17:26:14 +02:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
2007-09-12 14:29:51 +02:00
|
|
|
*/
|
2007-09-05 20:15:00 +02:00
|
|
|
|
2008-03-21 16:50:17 +01:00
|
|
|
#include <cairo-xcb.h>
|
|
|
|
|
2008-06-03 11:16:25 +02:00
|
|
|
#include "config.h"
|
2008-02-04 13:28:20 +01:00
|
|
|
|
|
|
|
#include <langinfo.h>
|
|
|
|
#include <iconv.h>
|
|
|
|
#include <errno.h>
|
2008-04-25 15:50:36 +02:00
|
|
|
#include <ctype.h>
|
2007-10-11 17:06:55 +02:00
|
|
|
#include <math.h>
|
2008-02-04 13:28:20 +01:00
|
|
|
|
2009-09-07 17:22:32 +02:00
|
|
|
#include "globalconf.h"
|
2009-07-10 16:26:49 +02:00
|
|
|
#include "screen.h"
|
2008-09-11 14:11:13 +02:00
|
|
|
|
2009-04-17 16:52:25 +02:00
|
|
|
#include "common/xutil.h"
|
2008-09-11 14:11:13 +02:00
|
|
|
|
2008-07-01 14:44:19 +02:00
|
|
|
/** Convert text from any charset to UTF-8 using iconv.
|
|
|
|
* \param iso The ISO string to convert.
|
|
|
|
* \param len The string size.
|
2008-12-03 14:37:35 +01:00
|
|
|
* \param dest The destination pointer. Memory will be allocated, up to you to
|
|
|
|
* free, like any char *.
|
|
|
|
* \param dlen The destination length, can be NULL.
|
|
|
|
* \return True if conversion was done.
|
2008-02-27 09:32:45 +01:00
|
|
|
*/
|
2008-12-03 14:37:35 +01:00
|
|
|
bool
|
|
|
|
draw_iso2utf8(const char *iso, size_t len, char **dest, ssize_t *dlen)
|
2008-02-04 13:28:20 +01:00
|
|
|
{
|
2008-09-16 19:51:14 +02:00
|
|
|
static iconv_t iso2utf8 = (iconv_t) -1;
|
2008-11-12 15:16:01 +01:00
|
|
|
static int8_t dont_need_convert = -1;
|
2008-02-04 13:28:20 +01:00
|
|
|
|
2008-11-12 15:16:01 +01:00
|
|
|
if(dont_need_convert == -1)
|
|
|
|
dont_need_convert = !a_strcmp(nl_langinfo(CODESET), "UTF-8");
|
2008-02-04 13:28:20 +01:00
|
|
|
|
2008-11-12 15:16:01 +01:00
|
|
|
if(!len || dont_need_convert)
|
2008-12-03 14:37:35 +01:00
|
|
|
return false;
|
2008-02-04 13:28:20 +01:00
|
|
|
|
|
|
|
if(iso2utf8 == (iconv_t) -1)
|
|
|
|
{
|
2008-07-09 08:48:51 +02:00
|
|
|
iso2utf8 = iconv_open("UTF-8", nl_langinfo(CODESET));
|
|
|
|
if(iso2utf8 == (iconv_t) -1)
|
|
|
|
{
|
|
|
|
if(errno == EINVAL)
|
|
|
|
warn("unable to convert text from %s to UTF-8, not available",
|
|
|
|
nl_langinfo(CODESET));
|
|
|
|
else
|
|
|
|
warn("unable to convert text: %s", strerror(errno));
|
|
|
|
|
2008-12-03 14:37:35 +01:00
|
|
|
return false;
|
2008-07-09 08:48:51 +02:00
|
|
|
}
|
2008-02-04 13:28:20 +01:00
|
|
|
}
|
|
|
|
|
2008-12-03 14:37:35 +01:00
|
|
|
size_t orig_utf8len, utf8len;
|
|
|
|
char *utf8;
|
|
|
|
|
|
|
|
orig_utf8len = utf8len = 2 * len + 1;
|
|
|
|
utf8 = *dest = p_new(char, utf8len);
|
2008-02-04 13:28:20 +01:00
|
|
|
|
2008-04-25 15:50:36 +02:00
|
|
|
if(iconv(iso2utf8, (char **) &iso, &len, &utf8, &utf8len) == (size_t) -1)
|
2008-02-04 13:28:20 +01:00
|
|
|
{
|
2008-05-23 22:53:59 +02:00
|
|
|
warn("text conversion failed: %s", strerror(errno));
|
2008-12-03 14:37:35 +01:00
|
|
|
p_delete(dest);
|
2009-06-15 11:24:56 +02:00
|
|
|
return false;
|
2008-02-04 13:28:20 +01:00
|
|
|
}
|
|
|
|
|
2008-12-03 14:37:35 +01:00
|
|
|
if(dlen)
|
|
|
|
*dlen = orig_utf8len - utf8len;
|
|
|
|
|
|
|
|
return true;
|
2008-02-04 13:28:20 +01:00
|
|
|
}
|
|
|
|
|
2010-08-20 11:56:23 +02:00
|
|
|
static cairo_user_data_key_t data_key;
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
free_data(void *data)
|
|
|
|
{
|
|
|
|
p_delete(&data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Create a surface object on the lua stack from this image data.
|
|
|
|
* \param L The lua stack.
|
|
|
|
* \param width The width of the image.
|
|
|
|
* \param height The height of the image
|
|
|
|
* \param data The image's data in ARGB format, will be copied by this function.
|
|
|
|
* \return Number of items pushed on the lua stack.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
luaA_surface_from_data(lua_State *L, int width, int height, uint32_t *data)
|
|
|
|
{
|
|
|
|
unsigned long int len = width * height;
|
2010-10-15 21:27:22 +02:00
|
|
|
unsigned long int i;
|
|
|
|
uint32_t *buffer = p_new(uint32_t, len);
|
|
|
|
cairo_surface_t *surface;
|
|
|
|
|
|
|
|
/* Cairo wants premultiplied alpha, meh :( */
|
|
|
|
for(i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
uint8_t a = (data[i] >> 24) & 0xff;
|
|
|
|
double alpha = a / 255.0;
|
|
|
|
uint8_t r = ((data[i] >> 16) & 0xff) * alpha;
|
|
|
|
uint8_t g = ((data[i] >> 8) & 0xff) * alpha;
|
|
|
|
uint8_t b = ((data[i] >> 0) & 0xff) * alpha;
|
|
|
|
buffer[i] = (a << 24) | (r << 16) | (g << 8) | b;
|
|
|
|
}
|
|
|
|
|
|
|
|
surface =
|
|
|
|
cairo_image_surface_create_for_data((unsigned char *) buffer,
|
2010-08-20 11:56:23 +02:00
|
|
|
CAIRO_FORMAT_ARGB32,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
width*4);
|
|
|
|
/* This makes sure that buffer will be freed */
|
|
|
|
cairo_surface_set_user_data(surface, &data_key, buffer, &free_data);
|
|
|
|
|
|
|
|
/* This will increase the reference count of the surface */
|
|
|
|
int ret = oocairo_surface_push(globalconf.L, surface);
|
|
|
|
/* So we have to drop our own reference */
|
|
|
|
cairo_surface_destroy(surface);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Duplicate the specified image surface.
|
|
|
|
* \param surface The surface to copy
|
|
|
|
* \return A pointer to a new cairo image surface.
|
|
|
|
*/
|
|
|
|
cairo_surface_t *
|
|
|
|
draw_dup_image_surface(cairo_surface_t *surface)
|
|
|
|
{
|
|
|
|
cairo_surface_t *res = cairo_image_surface_create(
|
|
|
|
cairo_image_surface_get_format(surface),
|
|
|
|
cairo_image_surface_get_width(surface),
|
|
|
|
cairo_image_surface_get_height(surface));
|
|
|
|
|
|
|
|
cairo_t *cr = cairo_create(res);
|
|
|
|
cairo_set_source_surface(cr, surface, 0, 0);
|
|
|
|
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
|
|
|
cairo_paint(cr);
|
|
|
|
cairo_destroy(cr);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|