29#define MAX_FILE_EXTENSIONS 50
55 struct sprite *mask,
int mask_offset_x,
int mask_offset_y,
56 float scale,
bool smooth)
63 new->surface = cairo_surface_create_similar(
source->surface,
65 cr = cairo_create(new->surface);
69 cairo_set_source_surface(cr,
source->surface, -x, -y);
72 cairo_set_operator(cr, CAIRO_OPERATOR_DEST_IN);
73 cairo_set_source_surface(cr, mask->
surface, mask_offset_x-x, mask_offset_y-y);
93 sprite->
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
97 gdk_cairo_set_source_rgba(cr, &
pcolor->color);
125 if (ext[0] == NULL) {
127 GSList *formats = gdk_pixbuf_get_formats();
128 GSList *next = formats;
131 GdkPixbufFormat *format = g_slist_nth_data(next, 0);
132 gchar **mimes = gdk_pixbuf_format_get_mime_types(format);
139 char *end = strstr(mimes[i],
"/");
149 g_slist_free(formats);
174 GdkPixbuf *pb = gdk_pixbuf_new_from_file(filename, &err);
177 unsigned char *pbdata;
179 unsigned char *cairo_data;
187 log_error(
_(
"Can't load %s: %s"), filename, err->message);
194 width = gdk_pixbuf_get_width(pb);
195 height = gdk_pixbuf_get_height(pb);
196 pbdata = gdk_pixbuf_get_pixels(pb);
197 rs = gdk_pixbuf_get_rowstride(pb);
198 has_alpha = gdk_pixbuf_get_has_alpha(pb);
199 channels = gdk_pixbuf_get_n_channels(pb);
201 cairo_stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
width);
202 if (cairo_stride <= 0) {
212 for (i = 0; i <
height; i++) {
213 for (j = 0; j <
width; j++) {
217#define MULTI_UNc(a,b) ((a * b - (b / 2)) / 0xFF)
220 tmp = pbdata[j * channels + 3];
221 data[j * 4 + 3] =
MULTI_UNc(pbdata[j * channels + 2], tmp);
222 data[j * 4 + 2] =
MULTI_UNc(pbdata[j * channels + 1], tmp);
223 data[j * 4 + 1] =
MULTI_UNc(pbdata[j * channels + 0], tmp);
224 data[j * 4 + 0] = tmp;
226 tmp =
MULTI_UNc(pbdata[j * channels + 2], pbdata[j * channels + 3]);
227 data[j * 4 + 1] =
MULTI_UNc(pbdata[j * channels + 1],
228 pbdata[j * channels + 3]);
229 data[j * 4 + 2] =
MULTI_UNc(pbdata[j * channels + 0],
230 pbdata[j * channels + 3]);
231 data[j * 4 + 0] = tmp;
232 data[j * 4 + 3] = pbdata[j * channels + 3];
238 data[j * 4 + 3] = 255;
239 data[j * 4 + 0] = pbdata[j * channels + 2];
240 data[j * 4 + 1] = pbdata[j * channels + 1];
241 data[j * 4 + 2] = pbdata[j * channels + 0];
245 data += cairo_stride;
251 spr->
surface = cairo_image_surface_create_for_data(cairo_data, CAIRO_FORMAT_ARGB32,
254 || cairo_surface_status(spr->
surface) != CAIRO_STATUS_SUCCESS) {
255 log_error(
"Cairo image surface creation error");
264 fc_assert(cairo_image_surface_get_format(spr->
surface) == CAIRO_FORMAT_ARGB32);
266 if (cairo_surface_status(spr->
surface) != CAIRO_STATUS_SUCCESS) {
267 log_fatal(
"Failed reading graphics file: \"%s\"", filename);
281 cairo_surface_destroy(s->
surface);
299 new->surface = cairo_surface_create_similar(src->
surface,
300 CAIRO_CONTENT_COLOR_ALPHA, new_w, new_h);
302 cr = cairo_create(new->surface);
304 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
307 cairo_scale(cr, (
double) new_w / (
double)
width, (
double) new_h / (
double)
height);
308 cairo_set_source_surface(cr, src->
surface, 0, 0);
322 int *start_y,
int *end_x,
int *end_y)
324 unsigned char *data = cairo_image_surface_get_data(
sprite->
surface);
340 for (i = 0; i <
width && *start_x == -1; i++) {
341 for (j = 0; j <
height; j++) {
342 if (data[(j *
width + i) * 4 + endian]) {
351 for (i =
width - 1; i >= *start_x && *end_x == -1; i--) {
352 for (j = 0; j <
height; j++) {
353 if (data[(j *
width + i) * 4 + endian]) {
362 for (i = 0; i <
height && *start_y == -1; i++) {
363 for (j = *start_x; j <= *end_x; j++) {
364 if (data[(i *
width + j) * 4 + endian]) {
373 for (i =
height - 1; i >= *end_y && *end_y == -1; i--) {
374 for (j = *start_x; j <= *end_x; j++) {
375 if (data[(i *
width + j) * 4 + endian]) {
392 return crop_sprite(s, x1, y1, x2 - x1 + 1, y2 - y1 + 1, NULL, -1, -1,
421 cairo_surface_t *tmpsurf;
423 unsigned char *pixels;
428 pixels = gdk_pixbuf_get_pixels(pb);
429 rowstride = gdk_pixbuf_get_rowstride(pb);
431 tmpsurf = cairo_image_surface_create_for_data(pixels, CAIRO_FORMAT_ARGB32,
434 cr = cairo_create(tmpsurf);
436 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
439 cairo_set_source_surface(cr, surf, 0, 0);
443 for (i =
height; i > 0; i--) {
444 unsigned char *p = pixels;
445 unsigned char *end = p + 4 *
width;
448#define DIV_UNc(a,b) (((guint16) (a) * 0xFF + ((b) / 2)) / (b))
460 p[1] = p[2] = p[3] = 0;
468 p[0] = p[1] = p[2] = 0;
480 cairo_surface_destroy(tmpsurf);
505 canvas.
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
510 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
532 cairo_image_surface_get_width(
surf),
533 cairo_image_surface_get_height(
surf));
535 pic = gtk_picture_new_for_pixbuf(pb);
551 cairo_image_surface_get_width(
surf),
552 cairo_image_surface_get_height(
surf));
556 empty = gdk_paintable_new_empty(1, 1);
557 gtk_picture_set_paintable(pic, empty);
559 texture = gdk_texture_new_for_pixbuf(pb);
560 gtk_picture_set_paintable(pic, GDK_PAINTABLE(texture));
561 g_object_unref(texture);
583 cr = cairo_create(spr->
surface);
struct canvas int int struct sprite int int int int height
struct canvas int int struct sprite bool int int fog_y struct canvas struct sprite struct color * pcolor
struct canvas int int canvas_y
struct canvas int canvas_x
struct canvas int int struct sprite int int int width
void get_text_size(int *width, int *height, enum client_font font, const char *text)
void surface_put_text(cairo_t *cr, int x, int y, float zoom, enum client_font font, struct color *pcolor, const char *text)
#define FC_STATIC_CANVAS_INIT
struct color * color_alloc(int r, int g, int b)
void color_free(struct color *color)
static GtkWidget * source
void get_sprite_dimensions(struct sprite *sprite, int *width, int *height)
static void surf_destroy_callback(void *data)
void free_sprite(struct sprite *s)
struct sprite * sprite_scale(struct sprite *src, int new_w, int new_h)
struct sprite * load_gfxnumber(int num)
GdkPixbuf * surface_get_pixbuf(cairo_surface_t *surf, int width, int height)
GdkPixbuf * sprite_get_pixbuf(struct sprite *sprite)
GdkPixbuf * create_extra_pixbuf(const struct extra_type *pextra)
struct sprite * load_gfxfile(const char *filename)
#define MAX_FILE_EXTENSIONS
void sprite_get_bounding_box(struct sprite *sprite, int *start_x, int *start_y, int *end_x, int *end_y)
struct sprite * crop_blankspace(struct sprite *s)
struct sprite * crop_sprite(struct sprite *source, int x, int y, int width, int height, struct sprite *mask, int mask_offset_x, int mask_offset_y, float scale, bool smooth)
const char ** gfx_fileextensions(void)
void picture_set_from_surface(GtkPicture *pic, cairo_surface_t *surf)
GtkWidget * picture_new_from_surface(cairo_surface_t *surf)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_fatal(message,...)
#define log_error(message,...)
void put_drawn_sprites(struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y, int count, struct drawn_sprite *pdrawn, bool fog)
cairo_surface_t * surface
cairo_surface_t * surface
int fc_snprintf(char *str, size_t n, const char *format,...)
static bool is_bigendian(void)
int fill_basic_extra_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
int tileset_tile_height(const struct tileset *t)
int tileset_tile_width(const struct tileset *t)