Exemple #1
0
/**
 * Handle notification that a CSS object is done
 *
 * \param css  CSS object
 * \param pw   Private data
 */
void nscss_content_done(struct content_css_data *css, void *pw)
{
	union content_msg_data msg_data;
	struct content *c = pw;
	uint32_t i;
	size_t size;
	css_error error;

	/* Retrieve the size of this sheet */
	error = css_stylesheet_size(css->sheet, &size);
	if (error != CSS_OK) {
		msg_data.error = "?";
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		content_set_error(c);
		return;
	}
	c->size += size;

	/* Add on the size of the imported sheets */
	for (i = 0; i < css->import_count; i++) {
		if (css->imports[i].c != NULL) {
			struct content *import = hlcache_handle_get_content(
					css->imports[i].c);

			if (import != NULL) {
				c->size += import->size;
			}
		}
	}

	/* Finally, catch the content's users up with reality */
	content_set_ready(c);
	content_set_done(c);
}
Exemple #2
0
void content_convert(struct content *c)
{
	assert(c);
	assert(c->status == CONTENT_STATUS_LOADING ||
			c->status == CONTENT_STATUS_ERROR);

	if (c->status != CONTENT_STATUS_LOADING)
		return;

	if (c->locked == true)
		return;
	
	LOG("content "URL_FMT_SPC" (%p)", nsurl_access(llcache_handle_get_url(c->llcache)), c);

	if (c->handler->data_complete != NULL) {
		c->locked = true;
		if (c->handler->data_complete(c) == false) {
			content_set_error(c);
		}
		/* Conversion to the READY state will unlock the content */
	} else {
		content_set_ready(c);
		content_set_done(c);
	}
}
Exemple #3
0
static bool javascript_convert(struct content *c)
{
	content_set_ready(c);
	content_set_done(c);

	return true;
}
Exemple #4
0
static bool nspng_convert(struct content *c)
{
	nspng_content *png_c = (nspng_content *) c;
	char *title;

	assert(png_c->png != NULL);
	assert(png_c->info != NULL);

	/* clean up png structures */
	png_destroy_read_struct(&png_c->png, &png_c->info, 0);

	/* set title text */
	title = messages_get_buff("PNGTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			c->width, c->height);
	if (title != NULL) {
		content__set_title(c, title);
		free(title);
	}

	if (png_c->bitmap != NULL) {
		bitmap_set_opaque(png_c->bitmap, bitmap_test_opaque(png_c->bitmap));
		bitmap_modified(png_c->bitmap);
	}

	image_cache_add(c, png_c->bitmap, png_cache_convert);

	content_set_ready(c);
	content_set_done(c);
	content_set_status(c, "");

	return true;
}
Exemple #5
0
static bool nsico_convert(struct content *c)
{
	nsico_content *ico = (nsico_content *) c;
	struct bmp_image *bmp;
	bmp_result res;
	union content_msg_data msg_data;
	const char *data;
	unsigned long size;
	char *title;

	/* set the ico data */
	data = content__get_source_data(c, &size);

	/* analyse the ico */
	res = ico_analyse(ico->ico, size, (unsigned char *) data);

	switch (res) {
	case BMP_OK:
		break;
	case BMP_INSUFFICIENT_MEMORY:
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	case BMP_INSUFFICIENT_DATA:
	case BMP_DATA_ERROR:
		msg_data.error = messages_get("BadICO");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	/* Store our content width, height and calculate size */
	c->width = ico->ico->width;
	c->height = ico->ico->height;
	c->size += (ico->ico->width * ico->ico->height * 4) + 16 + 44;

	/* set title text */
	title = messages_get_buff("ICOTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			c->width, c->height);
	if (title != NULL) {
		content__set_title(c, title);
		free(title);
	}

	/* select largest icon to ensure one can be selected */
	bmp = ico_find(ico->ico, 255, 255);
	if (bmp == NULL) {
		/* return error */
		LOG("Failed to select icon");
		return false;
	}

	content_set_ready(c);
	content_set_done(c);

	/* Done: update status bar */
	content_set_status(c, "");
	return true;
}
Exemple #6
0
/**
 * Convert a CONTENT_JPEG for display.
 */
static bool nsjpeg_convert(struct content *c)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	jmp_buf setjmp_buffer;
	struct jpeg_source_mgr source_mgr = { 0, 0,
		nsjpeg_init_source, nsjpeg_fill_input_buffer,
		nsjpeg_skip_input_data, jpeg_resync_to_restart,
		nsjpeg_term_source };
	union content_msg_data msg_data;
	const char *data;
	unsigned long size;
	char title[100];

	/* check image header is valid and get width/height */
	data = content__get_source_data(c, &size);

	cinfo.err = jpeg_std_error(&jerr);
	jerr.error_exit = nsjpeg_error_exit;
	jerr.output_message = nsjpeg_error_log;

	if (setjmp(setjmp_buffer)) {
		jpeg_destroy_decompress(&cinfo);

		msg_data.error = nsjpeg_error_buffer;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	jpeg_create_decompress(&cinfo);
	cinfo.client_data = &setjmp_buffer;
	source_mgr.next_input_byte = (unsigned char *) data;
	source_mgr.bytes_in_buffer = size;
	cinfo.src = &source_mgr;
	jpeg_read_header(&cinfo, TRUE);
	cinfo.out_color_space = JCS_RGB;
	cinfo.dct_method = JDCT_ISLOW;

	jpeg_calc_output_dimensions(&cinfo);

	c->width = cinfo.output_width;
	c->height = cinfo.output_height;
	c->size = c->width * c->height * 4;

	jpeg_destroy_decompress(&cinfo);

	image_cache_add(c, NULL, jpeg_cache_convert);

	snprintf(title, sizeof(title), messages_get("JPEGTitle"), 
		 c->width, c->height, size);
	content__set_title(c, title);

	content_set_ready(c);
	content_set_done(c);	
	content_set_status(c, ""); /* Done: update status bar */

	return true;
}
Exemple #7
0
bool amiga_dt_picture_convert(struct content *c)
{
	LOG(("amiga_dt_picture_convert"));

	union content_msg_data msg_data;
	int width, height;
	char title[100];
	const uint8 *data;
	UBYTE *bm_buffer;
	ULONG size;
	Object *dto;
	struct BitMapHeader *bmh;
	unsigned int bm_flags = BITMAP_NEW;
	int bm_format = PBPAFMT_RGBA;

	/* This is only relevant for picture datatypes... */

	data = (uint8 *)content__get_source_data(c, &size);

	if(dto = NewDTObject(NULL,
					DTA_SourceType, DTST_MEMORY,
					DTA_SourceAddress, data,
					DTA_SourceSize, size,
					DTA_GroupID, GID_PICTURE,
					PDTA_DestMode, PMODE_V43,
					TAG_DONE))
	{
		if(GetDTAttrs(dto, PDTA_BitMapHeader, &bmh, TAG_DONE))
		{
			width = (int)bmh->bmh_Width;
			height = (int)bmh->bmh_Height;
		}
		else return false;

		DisposeDTObject(dto);
	}
	else return false;

	c->width = width;
	c->height = height;
	c->size = width * height * 4;

	image_cache_add(c, NULL, amiga_dt_picture_cache_convert);

/*
	snprintf(title, sizeof(title), "image (%lux%lu, %lu bytes)",
		width, height, size);
	content__set_title(c, title);
*/

	content_set_ready(c);
	content_set_done(c);

	content_set_status(c, "");
	return true;
}
Exemple #8
0
static bool nsbmp_convert(struct content *c)
{
	nsbmp_content *bmp = (nsbmp_content *) c;
	bmp_result res;
	union content_msg_data msg_data;
	uint32_t swidth;
	const char *data;
	unsigned long size;
	char *title;

	/* set the bmp data */
	data = content__get_source_data(c, &size);

	/* analyse the BMP */
	res = bmp_analyse(bmp->bmp, size, (unsigned char *) data);
	switch (res) {
		case BMP_OK:
			break;
		case BMP_INSUFFICIENT_MEMORY:
			msg_data.error = messages_get("NoMemory");
			content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
			return false;
		case BMP_INSUFFICIENT_DATA:
		case BMP_DATA_ERROR:
			msg_data.error = messages_get("BadBMP");
			content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
			return false;
	}

	/* Store our content width and description */
	c->width = bmp->bmp->width;
	c->height = bmp->bmp->height;
	swidth = bmp->bmp->bitmap_callbacks.bitmap_get_bpp(bmp->bmp->bitmap) * 
			bmp->bmp->width;
	c->size += (swidth * bmp->bmp->height) + 16 + 44;

	/* set title text */
	title = messages_get_buff("BMPTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			c->width, c->height);
	if (title != NULL) {
		content__set_title(c, title);
		free(title);
	}

	/* exit as a success */
	bmp->bitmap = bmp->bmp->bitmap;
	guit->bitmap->modified(bmp->bitmap);

	content_set_ready(c);
	content_set_done(c);

	/* Done: update status bar */
	content_set_status(c, "");
	return true;
}
Exemple #9
0
static bool svg_convert(struct content *c)
{
	/*c->title = malloc(100);
	if (c->title)
		snprintf(c->title, 100, messages_get("svgTitle"),
				width, height, c->source_size);*/
	//c->size += ?;
	content_set_ready(c);
	content_set_done(c);
	/* Done: update status bar */
	content_set_status(c, "");

	return true;
}
Exemple #10
0
bool amiga_dt_picture_convert(struct content *c)
{
	LOG(("amiga_dt_picture_convert"));

	union content_msg_data msg_data;
	int width, height;
	char *title;
	UBYTE *bm_buffer;
	Object *dto;
	struct BitMapHeader *bmh;
	unsigned int bm_flags = BITMAP_NEW;
	int bm_format = PBPAFMT_RGBA;
	char *filetype;

	if(dto = amiga_dt_picture_newdtobject((struct amiga_dt_picture_content *)c))
	{
		if(GetDTAttrs(dto, PDTA_BitMapHeader, &bmh, TAG_DONE))
		{
			width = (int)bmh->bmh_Width;
			height = (int)bmh->bmh_Height;
		}
		else return false;
	}
	else return false;

	c->width = width;
	c->height = height;
	c->size = width * height * 4;

	/* set title text */
	if(filetype = amiga_dt_picture_datatype(c)) {
		title = messages_get_buff("DataTypesTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			filetype, c->width, c->height);
		if (title != NULL) {
			content__set_title(c, title);
			free(title);
		}
		free(filetype);
	}
	
	image_cache_add(c, NULL, amiga_dt_picture_cache_convert);

	content_set_ready(c);
	content_set_done(c);
	content_set_status(c, "");
	return true;
}
Exemple #11
0
bool amiga_dt_picture_convert(struct content *c)
{
	NSLOG(netsurf, INFO, "amiga_dt_picture_convert");

	int width, height;
	char *title;
	Object *dto;
	struct BitMapHeader *bmh;
	char *filetype;

	if((dto = amiga_dt_picture_newdtobject((struct amiga_dt_picture_content *)c))) {
		if(GetDTAttrs(dto, PDTA_BitMapHeader, &bmh, TAG_DONE)) {
			width = (int)bmh->bmh_Width;
			height = (int)bmh->bmh_Height;
		}
		else return false;
	}
	else return false;

	c->width = width;
	c->height = height;
	c->size = width * height * 4;

	/* set title text */
	if((filetype = amiga_dt_picture_datatype(c))) {
		title = messages_get_buff("DataTypesTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			filetype, c->width, c->height);
		if (title != NULL) {
			content__set_title(c, title);
			free(title);
		}
		free(filetype);
	}
	
	image_cache_add(c, NULL, amiga_dt_picture_cache_convert);

	content_set_ready(c);
	content_set_done(c);
	content_set_status(c, "");
	return true;
}
Exemple #12
0
static bool rsvg_convert(struct content *c)
{
	rsvg_content *d = (rsvg_content *) c;
	union content_msg_data msg_data;
	RsvgDimensionData rsvgsize;
	GError *err = NULL;

	if (rsvg_handle_close(d->rsvgh, &err) == FALSE) {
		LOG(("rsvg_handle_close returned an error: %s", err->message));
		msg_data.error = err->message;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	assert(err == NULL);

	/* we should now be able to query librsvg for the natural size of the
	 * graphic, so we can create our bitmap.
	 */

	rsvg_handle_get_dimensions(d->rsvgh, &rsvgsize);
	c->width = rsvgsize.width;
	c->height = rsvgsize.height;

	if ((d->bitmap = bitmap_create(c->width, c->height,
			BITMAP_NEW)) == NULL) {
		LOG(("Failed to create bitmap for rsvg render."));
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	if ((d->cs = cairo_image_surface_create_for_data(
			(unsigned char *)bitmap_get_buffer(d->bitmap),
			CAIRO_FORMAT_ARGB32,
			c->width, c->height,
			bitmap_get_rowstride(d->bitmap))) == NULL) {
		LOG(("Failed to create Cairo image surface for rsvg render."));
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	if ((d->ct = cairo_create(d->cs)) == NULL) {
		LOG(("Failed to create Cairo drawing context for rsvg render."));
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	rsvg_handle_render_cairo(d->rsvgh, d->ct);
	rsvg_argb_to_abgr(bitmap_get_buffer(d->bitmap),
				c->width, c->height,
				bitmap_get_rowstride(d->bitmap));

	bitmap_modified(d->bitmap);
	content_set_ready(c);
	content_set_done(c);
	/* Done: update status bar */
	content_set_status(c, "");

	return true;
}
Exemple #13
0
static bool nssprite_convert(struct content *c)
{
	nssprite_content *nssprite = (nssprite_content *) c;
	union content_msg_data msg_data;

	struct rosprite_mem_context* ctx;

	const char *data;
	unsigned long size;
	char *title;

	data = content__get_source_data(c, &size);

	ERRCHK(rosprite_create_mem_context((uint8_t *) data, size, &ctx));

	struct rosprite_area* sprite_area;
	ERRCHK(rosprite_load(rosprite_mem_reader, ctx, &sprite_area));
	rosprite_destroy_mem_context(ctx);
	nssprite->sprite_area = sprite_area;

	assert(sprite_area->sprite_count > 0);

	struct rosprite* sprite = sprite_area->sprites[0];

	nssprite->bitmap = guit->bitmap->create(sprite->width, sprite->height, BITMAP_NEW);
	if (!nssprite->bitmap) {
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}
	uint32_t* imagebuf = (uint32_t *)guit->bitmap->get_buffer(nssprite->bitmap);
	if (!imagebuf) {
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}
	unsigned char *spritebuf = (unsigned char *)sprite->image;

	/* reverse byte order of each word */
	for (uint32_t y = 0; y < sprite->height; y++) {
		for (uint32_t x = 0; x < sprite->width; x++) {
			int offset = 4 * (y * sprite->width + x);

			*imagebuf = (spritebuf[offset] << 24) |
					(spritebuf[offset + 1] << 16) |
					(spritebuf[offset + 2] << 8) |
					(spritebuf[offset + 3]);

			imagebuf++;
		}
	}

	c->width = sprite->width;
	c->height = sprite->height;

	/* set title text */
	title = messages_get_buff("SpriteTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			c->width, c->height);
	if (title != NULL) {
		content__set_title(c, title);
		free(title);
	}

	guit->bitmap->modified(nssprite->bitmap);

	content_set_ready(c);
	content_set_done(c);
	content_set_status(c, ""); /* Done: update status bar */

	return true;
}
Exemple #14
0
bool amiga_icon_convert(struct content *c)
{
	amiga_icon_content *icon_c = (amiga_icon_content *)c;	
	union content_msg_data msg_data;
	struct DiskObject *dobj;
	ULONG *imagebuf;
	unsigned char *imagebufptr = NULL;
	ULONG size;
	int width = 0, height = 0;
	long format = 0;
	int err = 0;
	uint8 r, g, b, a;
	ULONG offset;
	const char *url;
	char *filename;
	char *p;
	ULONG trans, pals1;
	struct ColorRegister *pal1;

	url = nsurl_access(content_get_url(c));
	filename = url_to_path(url);

	/* This loader will only work on local files, so fail if not a local path */
	if(filename == NULL)
	{
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	p = strstr(filename, ".info");
	*p = '\0';

	dobj = GetIconTagList(filename, NULL);	

	if(dobj == NULL)
	{
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	err = IconControl(dobj,
			ICONCTRLA_GetImageDataFormat,&format,
			ICONCTRLA_GetWidth,&width,
			ICONCTRLA_GetHeight,&height,
			TAG_DONE);

	/* Check icon is direct mapped (truecolour) or palette-mapped colour.
	   We need additional code to handle planar icons */
	if((format != IDFMT_DIRECTMAPPED) && (format==IDFMT_PALETTEMAPPED)) {
		if(dobj) FreeDiskObject(dobj);
		return false;
	}

	icon_c->bitmap = bitmap_create(width, height, BITMAP_NEW);
	if (!icon_c->bitmap) {
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		if(dobj) FreeDiskObject(dobj);
		return false;
	}
	imagebuf = (ULONG *) bitmap_get_buffer(icon_c->bitmap);
	if (!imagebuf) {
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		if(dobj) FreeDiskObject(dobj);
		return false;
	}

	err = IconControl(dobj,
			ICONCTRLA_GetImageData1, &imagebufptr,
			TAG_DONE);

	if(format==IDFMT_PALETTEMAPPED)
	{
		IconControl(dobj, ICONCTRLA_GetTransparentColor1, &trans,
		            ICONCTRLA_GetPalette1, &pal1,
	    	        ICONCTRLA_GetPaletteSize1, &pals1,
    	    	    TAG_DONE);

		imagebufptr = (unsigned char *) amiga_icon_convertcolouricon32((UBYTE *)imagebufptr,
						width, height, trans, pals1, pal1, 0xff);
	}

	/* Decoded data is ARGB, so ensure correct byte order */

	size = width * height * 4;

	for (offset = 0; offset < size; offset += 4) {
		b = imagebufptr[offset+3];
		g = imagebufptr[offset+2];
		r = imagebufptr[offset+1];
		a = imagebufptr[offset];

		*imagebuf = r << 24 | g << 16 | b << 8 | a;
		imagebuf++;
	}

	c->width = width;
	c->height = height;

	bitmap_modified(icon_c->bitmap);
	content_set_ready(c);
	content_set_done(c);
	content_set_status(c, "");

	if(dobj) FreeDiskObject(dobj);

	if(format==IDFMT_PALETTEMAPPED)
		FreeVec(imagebufptr);

	return true;
}
Exemple #15
0
bool artworks_convert(struct content *c)
{
	artworks_content *aw = (artworks_content *) c;
	union content_msg_data msg_data;
	const char *source_data;
	unsigned long source_size;
	void *init_workspace;
	void *init_routine;
	os_error *error;
	int used = -1;  /* slightly better with older OSLib versions */
	char *title;

	/* check whether AWViewer has been seen and we can therefore
		locate the ArtWorks rendering modules */
	xos_read_var_val_size("Alias$LoadArtWorksModules", 0, os_VARTYPE_STRING,
				&used, NULL, NULL);
	if (used >= 0) {
		LOG("Alias$LoadArtWorksModules not defined");
		msg_data.error = messages_get("AWNotSeen");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	/* load the modules, or do nothing if they're already loaded */
	error = xos_cli("LoadArtWorksModules");
	if (error) {
		LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
		msg_data.error = error->errmess;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	/* lookup the addresses of the init and render routines */
	error = (os_error*)_swix(AWRender_FileInitAddress, _OUT(0) | _OUT(1),
				&init_routine, &init_workspace);
	if (error) {
		LOG("AWRender_FileInitAddress: 0x%x: %s", error->errnum, error->errmess);
		msg_data.error = error->errmess;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	error = (os_error*)_swix(AWRender_RenderAddress, _OUT(0) | _OUT(1),
				&aw->render_routine,
				&aw->render_workspace);
	if (error) {
		LOG("AWRender_RenderAddress: 0x%x: %s", error->errnum, error->errmess);
		msg_data.error = error->errmess;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	source_data = content__get_source_data(c, &source_size);

	/* initialise (convert file to new format if required) */
	error = awrender_init(&source_data, &source_size,
			init_routine, init_workspace);
	if (error) {
		LOG("awrender_init: 0x%x : %s", error->errnum, error->errmess);
		msg_data.error = error->errmess;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	error = (os_error*)_swix(AWRender_DocBounds, 
			_IN(0) | _OUT(2) | _OUT(3) | _OUT(4) | _OUT(5),
			source_data,
			&aw->x0,
			&aw->y0,
			&aw->x1,
			&aw->y1);

	if (error) {
		LOG("AWRender_DocBounds: 0x%x: %s", error->errnum, error->errmess);
		msg_data.error = error->errmess;
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	LOG("bounding box: %d,%d,%d,%d", aw->x0, aw->y0, aw->x1, aw->y1);

	/* create the resizable workspace required by the
		ArtWorksRenderer rendering routine */

	aw->size = INITIAL_BLOCK_SIZE;
	aw->block = malloc(INITIAL_BLOCK_SIZE);
	if (!aw->block) {
		LOG("failed to create block for ArtworksRenderer");
		msg_data.error = messages_get("NoMemory");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	c->width  = (aw->x1 - aw->x0) / 512;
	c->height = (aw->y1 - aw->y0) / 512;

	title = messages_get_buff("ArtWorksTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			c->width, c->height);
	if (title != NULL) {
		content__set_title(c, title);
		free(title);
	}
	content_set_ready(c);
	content_set_done(c);
	/* Done: update status bar */
	content_set_status(c, "");
	return true;
}
Exemple #16
0
static bool rsvg_convert(struct content *c)
{
	rsvg_content *d = (rsvg_content *) c;
	RsvgDimensionData rsvgsize;
	GError *err = NULL;

	if (rsvg_handle_close(d->rsvgh, &err) == FALSE) {
		NSLOG(netsurf, INFO,
		      "rsvg_handle_close returned an error: %s", err->message);
		content_broadcast_errorcode(c, NSERROR_SVG_ERROR);
		return false;
	}

	assert(err == NULL);

	/* we should now be able to query librsvg for the natural size of the
	 * graphic, so we can create our bitmap.
	 */

	rsvg_handle_get_dimensions(d->rsvgh, &rsvgsize);
	c->width = rsvgsize.width;
	c->height = rsvgsize.height;

	if ((d->bitmap = guit->bitmap->create(c->width, c->height,
			BITMAP_NEW)) == NULL) {
		NSLOG(netsurf, INFO,
		      "Failed to create bitmap for rsvg render.");
		content_broadcast_errorcode(c, NSERROR_NOMEM);
		return false;
	}

	if ((d->cs = cairo_image_surface_create_for_data(
			(unsigned char *)guit->bitmap->get_buffer(d->bitmap),
			CAIRO_FORMAT_ARGB32,
			c->width, c->height,
			guit->bitmap->get_rowstride(d->bitmap))) == NULL) {
		NSLOG(netsurf, INFO,
		      "Failed to create Cairo image surface for rsvg render.");
		content_broadcast_errorcode(c, NSERROR_NOMEM);
		return false;
	}

	if ((d->ct = cairo_create(d->cs)) == NULL) {
		NSLOG(netsurf, INFO,
		      "Failed to create Cairo drawing context for rsvg render.");
		content_broadcast_errorcode(c, NSERROR_NOMEM);
		return false;
	}

	rsvg_handle_render_cairo(d->rsvgh, d->ct);
	rsvg_argb_to_abgr(guit->bitmap->get_buffer(d->bitmap),
				c->width, c->height,
				guit->bitmap->get_rowstride(d->bitmap));

	guit->bitmap->modified(d->bitmap);
	content_set_ready(c);
	content_set_done(c);
	/* Done: update status bar */
	content_set_status(c, "");

	return true;
}
Exemple #17
0
static bool nsgif_convert(struct content *c)
{
	nsgif_content *gif = (nsgif_content *) c;
	int res;
	union content_msg_data msg_data;
	const char *data;
	unsigned long size;
	char *title;

	/* Get the animation */
	data = content__get_source_data(c, &size);

	/* Initialise the GIF */
	do {
		res = gif_initialise(gif->gif, size, (unsigned char *) data);
		if (res != GIF_OK && res != GIF_WORKING && 
				res != GIF_INSUFFICIENT_FRAME_DATA) {
			switch (res) {
			case GIF_FRAME_DATA_ERROR:
			case GIF_INSUFFICIENT_DATA:
			case GIF_DATA_ERROR:
				msg_data.error = messages_get("BadGIF");
				break;
			case GIF_INSUFFICIENT_MEMORY:
				msg_data.error = messages_get("NoMemory");
				break;
			}
			content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
			return false;
		}
	} while (res != GIF_OK && res != GIF_INSUFFICIENT_FRAME_DATA);

	/* Abort on bad GIFs */
	if ((gif->gif->frame_count_partial == 0) || (gif->gif->width == 0) ||
			(gif->gif->height == 0)) {
		msg_data.error = messages_get("BadGIF");
		content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
		return false;
	}

	/* Store our content width, height and calculate size */
	c->width = gif->gif->width;
	c->height = gif->gif->height;
	c->size += (gif->gif->width * gif->gif->height * 4) + 16 + 44;

	/* set title text */
	title = messages_get_buff("GIFTitle",
			nsurl_access_leaf(llcache_handle_get_url(c->llcache)),
			c->width, c->height);
	if (title != NULL) {
		content__set_title(c, title);
		free(title);
	}

	/* Schedule the animation if we have one */
	gif->current_frame = 0;
	if (gif->gif->frame_count_partial > 1)
		guit->browser->schedule(gif->gif->frames[0].frame_delay * 10,
					nsgif_animate,
					c);

	/* Exit as a success */
	content_set_ready(c);
	content_set_done(c);

	/* Done: update status bar */
	content_set_status(c, "");
	return true;
}