static cairo_test_status_t
test_cairo_image_surface_get_height (cairo_surface_t *surface)
{
    unsigned int height = cairo_image_surface_get_height (surface);
    return height == 0 || surface_has_type (surface, CAIRO_SURFACE_TYPE_IMAGE) ? CAIRO_TEST_SUCCESS : CAIRO_TEST_ERROR;
}
static GtkWidget *
gth_file_tool_grayscale_get_options (GthFileTool *base)
{
	GthFileToolGrayscale *self;
	GtkWidget            *window;
	GtkWidget            *viewer_page;
	GtkWidget            *viewer;
	cairo_surface_t      *source;
	GtkWidget            *options;
	int                   width, height;
	GtkAllocation         allocation;

	self = (GthFileToolGrayscale *) base;

	window = gth_file_tool_get_window (base);
	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
		return NULL;

	cairo_surface_destroy (self->priv->destination);
	cairo_surface_destroy (self->priv->preview);

	viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
	source = gth_image_viewer_page_tool_get_source (GTH_IMAGE_VIEWER_PAGE_TOOL (self));
	if (source == NULL)
		return NULL;

	width = cairo_image_surface_get_width (source);
	height = cairo_image_surface_get_height (source);
	gtk_widget_get_allocation (GTK_WIDGET (viewer), &allocation);
	if (scale_keeping_ratio (&width, &height, PREVIEW_SIZE * allocation.width, PREVIEW_SIZE * allocation.height, FALSE))
		self->priv->preview = _cairo_image_surface_scale_bilinear (source, width, height);
	else
		self->priv->preview = cairo_surface_reference (source);

	self->priv->destination = cairo_surface_reference (self->priv->preview);
	self->priv->apply_to_original = FALSE;
	self->priv->closing = FALSE;

	self->priv->builder = _gtk_builder_new_from_file ("grayscale-options.ui", "file_tools");
	options = _gtk_builder_get_widget (self->priv->builder, "options");
	gtk_widget_show (options);

	g_signal_connect (GET_WIDGET ("ok_button"),
			  "clicked",
			  G_CALLBACK (ok_button_clicked_cb),
			  self);
	g_signal_connect_swapped (GET_WIDGET ("cancel_button"),
				  "clicked",
				  G_CALLBACK (gth_file_tool_cancel),
				  self);
	g_signal_connect (GET_WIDGET ("brightness_radiobutton"),
			  "clicked",
			  G_CALLBACK (method_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("saturation_radiobutton"),
			  "clicked",
			  G_CALLBACK (method_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("average_radiobutton"),
			  "clicked",
			  G_CALLBACK (method_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("preview_checkbutton"),
			  "toggled",
			  G_CALLBACK (preview_checkbutton_toggled_cb),
			  self);

	self->priv->preview_tool = gth_preview_tool_new ();
	gth_preview_tool_set_image (GTH_PREVIEW_TOOL (self->priv->preview_tool), self->priv->preview);
	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->preview_tool);
	apply_changes (self);

	return options;
}
Beispiel #3
0
 static std::size_t height(data_type_t const& data_in) {
   return cairo_image_surface_get_height(data_in);
 }
Beispiel #4
0
void
_gtk_9slice_render (Gtk9Slice *slice,
                    cairo_t   *cr,
                    gdouble    x,
                    gdouble    y,
                    gdouble    width,
                    gdouble    height)
{
  int img_width, img_height;
  cairo_surface_t *surface;

  cairo_save (cr);

  /* Top side */
  surface = slice->surfaces[BORDER_MIDDLE][BORDER_TOP];
  img_height = cairo_image_surface_get_height (surface);

  render_border (cr, surface, SIDE_TOP,
                 x + slice->distances[SIDE_LEFT], y,
                 width - slice->distances[SIDE_LEFT] - slice->distances[SIDE_RIGHT],
                 (gdouble) img_height,
                 slice->modifiers[SIDE_TOP]);

  /* Bottom side */
  surface = slice->surfaces[BORDER_MIDDLE][BORDER_BOTTOM];
  img_height = cairo_image_surface_get_height (surface);

  render_border (cr, surface, SIDE_BOTTOM,
                 x + slice->distances[SIDE_LEFT], y + height - img_height,
                 width - slice->distances[SIDE_LEFT] - slice->distances[SIDE_RIGHT],
                 (gdouble) img_height,
                 slice->modifiers[SIDE_BOTTOM]);

  /* Left side */
  surface = slice->surfaces[BORDER_LEFT][BORDER_MIDDLE];
  img_width = cairo_image_surface_get_width (surface);

  render_border (cr, surface, SIDE_LEFT,
                 x, y + slice->distances[SIDE_TOP],
                 (gdouble) img_width,
                 height - slice->distances[SIDE_TOP] - slice->distances[SIDE_BOTTOM],
                 slice->modifiers[SIDE_LEFT]);

  /* Right side */
  surface = slice->surfaces[BORDER_RIGHT][BORDER_MIDDLE];
  img_width = cairo_image_surface_get_width (surface);

  render_border (cr, surface, SIDE_RIGHT,
                 x + width - img_width, y + slice->distances[SIDE_TOP],
                 (gdouble) img_width,
                 height - slice->distances[SIDE_TOP] - slice->distances[SIDE_BOTTOM],
                 slice->modifiers[SIDE_RIGHT]);

  /* Top/Left corner */
  surface = slice->surfaces[BORDER_LEFT][BORDER_TOP];
  img_width = cairo_image_surface_get_width (surface);
  img_height = cairo_image_surface_get_height (surface);
  render_corner (cr, surface, x, y, (gdouble) img_width, (gdouble) img_height);

  /* Top/right corner */
  surface = slice->surfaces[BORDER_RIGHT][BORDER_TOP];
  img_width = cairo_image_surface_get_width (surface);
  img_height = cairo_image_surface_get_height (surface);
  render_corner (cr, surface, x + width - img_width, y,
                 (gdouble) img_width, (gdouble) img_height);

  /* Bottom/left corner */
  surface = slice->surfaces[BORDER_LEFT][BORDER_BOTTOM];
  img_width = cairo_image_surface_get_width (surface);
  img_height = cairo_image_surface_get_height (surface);
  render_corner (cr, surface, x, y + height - img_height,
                 (gdouble) img_width, (gdouble) img_height);

  /* Bottom/right corner */
  surface = slice->surfaces[BORDER_RIGHT][BORDER_BOTTOM];
  img_width = cairo_image_surface_get_width (surface);
  img_height = cairo_image_surface_get_height (surface);
  render_corner (cr, surface, x + width - img_width, y + height - img_height,
                 (gdouble) img_width, (gdouble) img_height);

  cairo_restore (cr);
}
Beispiel #5
0
void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) {
	double width = cairo_image_surface_get_width(image);
	double height = cairo_image_surface_get_height(image);

	switch (scaling_mode) {
	case SCALING_MODE_STRETCH:
		cairo_scale(window->cairo,
				(double) window->width / width,
				(double) window->height / height);
		cairo_set_source_surface(window->cairo, image, 0, 0);
		break;
	case SCALING_MODE_FILL:
	{
		double window_ratio = (double) window->width / window->height;
		double bg_ratio = width / height;

		if (window_ratio > bg_ratio) {
			double scale = (double) window->width / width;
			cairo_scale(window->cairo, scale, scale);
			cairo_set_source_surface(window->cairo, image,
					0,
					(double) window->height/2 / scale - height/2);
		} else {
			double scale = (double) window->height / height;
			cairo_scale(window->cairo, scale, scale);
			cairo_set_source_surface(window->cairo, image,
					(double) window->width/2 / scale - width/2,
					0);
		}
		break;
	}
	case SCALING_MODE_FIT:
	{
		double window_ratio = (double) window->width / window->height;
		double bg_ratio = width / height;

		if (window_ratio > bg_ratio) {
			double scale = (double) window->height / height;
			cairo_scale(window->cairo, scale, scale);
			cairo_set_source_surface(window->cairo, image,
					(double) window->width/2 / scale - width/2,
					0);
		} else {
			double scale = (double) window->width / width;
			cairo_scale(window->cairo, scale, scale);
			cairo_set_source_surface(window->cairo, image,
					0,
					(double) window->height/2 / scale - height/2);
		}
		break;
	}
	case SCALING_MODE_CENTER:
		cairo_set_source_surface(window->cairo, image,
				(double) window->width/2 - width/2,
				(double) window->height/2 - height/2);
		break;
	case SCALING_MODE_TILE:
	{
		cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
		cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
		cairo_set_source(window->cairo, pattern);
		break;
	}
	}

	cairo_paint(window->cairo);
}
Beispiel #6
0
static int
surface_get_gdk_pixbuf (lua_State *L) {
    cairo_surface_t **surface;
    cairo_format_t format;
    int width, height, stridei, strideo;
    unsigned char *buffer, *rowpo, *po;
    const char *rowpi, *pi;
    size_t buffer_len;
    int x, y;
    int has_alpha;

    surface = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_SURFACE);
    if (cairo_surface_get_type(*surface) != CAIRO_SURFACE_TYPE_IMAGE)
        return luaL_error(L, "pixbufs can only be made from image surfaces");

    format = cairo_image_surface_get_format(*surface);
    if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24)
        return luaL_error(L, "can't make pixbuf from this image format");
    has_alpha = (format == CAIRO_FORMAT_ARGB32);

    width = cairo_image_surface_get_width(*surface);
    height = cairo_image_surface_get_height(*surface);
    stridei = cairo_image_surface_get_stride(*surface);
    if (has_alpha)
        strideo = stridei;  /* might as well keep Cairo stride */
    else
        strideo = ((3 * width) + 7) & ~7;   /* align to 8 bytes */
    buffer_len = strideo * height;
    buffer = malloc(buffer_len);
    assert(buffer);

    rowpi = (const char *) cairo_image_surface_get_data(*surface);
    rowpo = buffer;

    /* Copy pixels from Cairo's pixel format to GdkPixbuf's, which is slightly
     * different. */
    if (IS_BIG_ENDIAN) {
        for (y = 0; y < height; ++y) {
            pi = rowpi;
            po = rowpo;
            for (x = 0; x < width; ++x) {
                *po++ = pi[1];
                *po++ = pi[2];
                *po++ = pi[3];
                if (has_alpha)
                    *po++ = pi[0];
                pi += 4;
            }
            rowpi += stridei;
            rowpo += strideo;
        }
    }
    else {
        for (y = 0; y < height; ++y) {
            pi = rowpi;
            po = rowpo;
            for (x = 0; x < width; ++x) {
                *po++ = pi[2];
                *po++ = pi[1];
                *po++ = pi[0];
                if (has_alpha)
                    *po++ = pi[3];
                pi += 4;
            }
            rowpi += stridei;
            rowpo += strideo;
        }
    }

    /* The buffer needs to be copied in to a Lua string so that it can
     * be passed to Lua-Gnome. */
    lua_pushlstring(L, (const char *) buffer, buffer_len);
    free(buffer);

    /* Use Lua-Gnome function to construct the GdkPixbuf object, so that we
     * don't have to link directly with GDK, and so that the resulting object
     * can be used with the rest of Lua-Gnome. */
    get_gtk_module_function(L, "gdk_pixbuf_new_from_data");
    lua_pushvalue(L, -2);
    get_gtk_module_function(L, "GDK_COLORSPACE_RGB");
    lua_pushboolean(L, has_alpha);
    lua_pushnumber(L, 8);
    lua_pushnumber(L, width);
    lua_pushnumber(L, height);
    lua_pushnumber(L, strideo);
    lua_pushnil(L);
    lua_pushnil(L);
    lua_call(L, 9, 1);

    /* Keep a reference to the Lua string used to store the data, since
     * it needs to be kept around for as long as the object is in use. */
    lua_pushvalue(L, -2);
    lua_setfield(L, -2, "_pixbuf_buffer_string");

    return 1;
}
Beispiel #7
0
static void
render_spect_border (cairo_surface_t * surface, const char * filename, double left, double width, double seconds, double top, double height, double min_freq, double max_freq, bool log_freq)
{
	char text [512] ;
	cairo_t * cr ;
	cairo_text_extents_t extents ;
	cairo_matrix_t matrix ;

	TICKS ticks ;
	int k, tick_count ;

	cr = cairo_create (surface) ;

	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0) ;
	cairo_set_line_width (cr, BORDER_LINE_WIDTH) ;

	/* Print title. */
	cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL) ;
	cairo_set_font_size (cr, 1.0 * TITLE_FONT_SIZE) ;

	snprintf (text, sizeof (text), "Spectrogram: %s", filename) ;
	cairo_text_extents (cr, text, &extents) ;
	cairo_move_to (cr, left + 2, top - extents.height / 2) ;
	cairo_show_text (cr, text) ;

	/* Print labels. */
	cairo_select_font_face (cr, font_family, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL) ;
	cairo_set_font_size (cr, 1.0 * NORMAL_FONT_SIZE) ;

	/* Border around actual spectrogram. */
	cairo_rectangle (cr, left, top, width, height) ;

	/* Put ticks on Time axis */
	tick_count = calculate_ticks (0.0, seconds, width, false, &ticks) ;
	for (k = 0 ; k < tick_count ; k++)
	{	y_line (cr, left + ticks.distance [k], top + height, TICK_LEN) ;
		if (JUST_A_TICK (ticks, k))
			continue ;
		str_print_value (text, sizeof (text), ticks.value [k],
			ticks.decimal_places_to_print) ;
		cairo_text_extents (cr, text, &extents) ;
		cairo_move_to (cr, left + ticks.distance [k] - extents.width / 2, top + height + 8 + extents.height) ;
		cairo_show_text (cr, text) ;
		} ;

	/* Put ticks on Frequency axis */
	tick_count = calculate_ticks (min_freq, max_freq, height, log_freq, &ticks) ;
	for (k = 0 ; k < tick_count ; k++)
	{	x_line (cr, left + width, top + height - ticks.distance [k], TICK_LEN) ;
		if (JUST_A_TICK (ticks, k))
			continue ;
		str_print_value (text, sizeof (text), ticks.value [k],
			ticks.decimal_places_to_print) ;
		cairo_text_extents (cr, text, &extents) ;
		cairo_move_to (cr, left + width + 12, top + height - ticks.distance [k] + extents.height / 4.5) ;
		cairo_show_text (cr, text) ;
		} ;

	cairo_set_font_size (cr, 1.0 * NORMAL_FONT_SIZE) ;

	/* Label X axis. */
	snprintf (text, sizeof (text), "Time (secs)") ;
	cairo_text_extents (cr, text, &extents) ;
	cairo_move_to (cr, left + (width - extents.width) / 2, cairo_image_surface_get_height (surface) - 8) ;
	cairo_show_text (cr, text) ;

	/* Label Y axis (rotated). */
	snprintf (text, sizeof (text), "Frequency (Hz)") ;
	cairo_text_extents (cr, text, &extents) ;

	cairo_get_font_matrix (cr, &matrix) ;
	cairo_matrix_rotate (&matrix, -0.5 * M_PI) ;
	cairo_set_font_matrix (cr, &matrix) ;

	cairo_move_to (cr, cairo_image_surface_get_width (surface) - 12, top + (height + extents.width) / 2) ;
	cairo_show_text (cr, text) ;

	cairo_destroy (cr) ;
} /* render_spect_border */
void
draw_shadow (cairo_t* cr,
	     gdouble  width,
	     gdouble  height,
	     gint     shadow_radius,
	     gint     corner_radius)
{
	cairo_surface_t* tmp_surface = NULL;
	cairo_surface_t* new_surface = NULL;
	cairo_pattern_t* pattern     = NULL;
	cairo_t*         cr_surf     = NULL;
	cairo_matrix_t   matrix;
	raico_blur_t*    blur        = NULL;

	tmp_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
						  4 * shadow_radius,
						  4 * shadow_radius);
	if (cairo_surface_status (tmp_surface) != CAIRO_STATUS_SUCCESS)
		return;

	cr_surf = cairo_create (tmp_surface);
	if (cairo_status (cr_surf) != CAIRO_STATUS_SUCCESS)
	{
		cairo_surface_destroy (tmp_surface);
		return;
	}

	cairo_scale (cr_surf, 1.0f, 1.0f);
	cairo_set_operator (cr_surf, CAIRO_OPERATOR_CLEAR);
	cairo_paint (cr_surf);
	cairo_set_operator (cr_surf, CAIRO_OPERATOR_OVER);
	cairo_set_source_rgba (cr_surf, 0.0f, 0.0f, 0.0f, 0.75f);
	cairo_arc (cr_surf,
		   2 * shadow_radius,
		   2 * shadow_radius,
		   2.0f * corner_radius,
		   0.0f,
		   360.0f * (G_PI / 180.f));
	cairo_fill (cr_surf);
	cairo_destroy (cr_surf);

	// create and setup blur
	blur = raico_blur_create (RAICO_BLUR_QUALITY_LOW);
	raico_blur_set_radius (blur, shadow_radius);

	// now blur it
	raico_blur_apply (blur, tmp_surface);

	// blur no longer needed
	raico_blur_destroy (blur);

	new_surface = cairo_image_surface_create_for_data (
			cairo_image_surface_get_data (tmp_surface),
			cairo_image_surface_get_format (tmp_surface),
			cairo_image_surface_get_width (tmp_surface) / 2,
			cairo_image_surface_get_height (tmp_surface) / 2,
			cairo_image_surface_get_stride (tmp_surface));
	pattern = cairo_pattern_create_for_surface (new_surface);
	if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS)
	{
		cairo_surface_destroy (tmp_surface);
		cairo_surface_destroy (new_surface);
		return;
	}

	// top left
	cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
	cairo_set_source (cr, pattern);
	cairo_rectangle (cr,
			 0.0f,
			 0.0f,
			 width - 2 * shadow_radius,
			 2 * shadow_radius);
	cairo_fill (cr);

	// bottom left
	cairo_matrix_init_scale (&matrix, 1.0f, -1.0f);
	cairo_matrix_translate (&matrix, 0.0f, -height);
	cairo_pattern_set_matrix (pattern, &matrix);
	cairo_rectangle (cr,
			 0.0f,
			 2 * shadow_radius,
			 2 * shadow_radius,
			 height - 2 * shadow_radius);
	cairo_fill (cr);

	// top right
	cairo_matrix_init_scale (&matrix, -1.0f, 1.0f);
	cairo_matrix_translate (&matrix, -width, 0.0f);
	cairo_pattern_set_matrix (pattern, &matrix);
	cairo_rectangle (cr,
			 width - 2 * shadow_radius,
			 0.0f,
			 2 * shadow_radius,
			 height - 2 * shadow_radius);
	cairo_fill (cr);

	// bottom right
	cairo_matrix_init_scale (&matrix, -1.0f, -1.0f);
	cairo_matrix_translate (&matrix, -width, -height);
	cairo_pattern_set_matrix (pattern, &matrix);
	cairo_rectangle (cr,
			 2 * shadow_radius,
			 height - 2 * shadow_radius,
			 width - 2 * shadow_radius,
			 2 * shadow_radius);
	cairo_fill (cr);

	// clean up
	cairo_pattern_destroy (pattern);
	cairo_surface_destroy (tmp_surface);
	cairo_surface_destroy (new_surface);
}
Beispiel #9
0
static cairo_surface_t* _cairocks_create_embossed_surface(
	cairo_surface_t* surface,
	double           azimuth,
	double           elevation,
	double           height,
	double           ambient,
	double           diffuse
) {
	unsigned char* src    = cairo_image_surface_get_data(surface);
	int            w      = cairo_image_surface_get_width(surface);
	int            h      = cairo_image_surface_get_height(surface);
	int            stride = cairo_image_surface_get_stride(surface);

	cairo_surface_t* dst_surface = cairo_image_surface_create(CAIRO_FORMAT_A8, w, h);

	unsigned char* dst = cairo_image_surface_get_data(dst_surface);

	double scale = height / (4.0f * 255.0f);

	double Lx = cos(azimuth) * cos(elevation);
	double Ly = sin(azimuth) * cos(elevation);
	double Lz = sin(elevation);

	int y;
	int x;

	memset(dst, minc(ambient + diffuse * Lz), stride * h);

	/* I'm going to set a minimum requirement size for embossing here for now, since
	the matrix "d" below assumes 3x3. Later, if it's necessary for such small 
	surfaces, we could rectify this. */
	if(w < 4 || h < 4) goto dirty_ret;

	for(y = 0; y < h; y++) {
		for(x = 0; x < w; x++) {
			double       Nx;
			double       Ny;
			double       Nz;
			double       NdotL;
			double       d[3][3];
			int          i;
			int          j;

			for(i = 0; i < 3; i++) {
				for(j = 0; j < 3; j++) {
					d[i][j] = (unsigned char)(src[OFFSET(x + i - 1, y + j - 1, w, h, stride)]);
				}
			}

			/* Compute the normal from the source. */
			Nx  = d[2][0] + (2.0f * d[2][1]) + d[2][2];
			Nx -= d[0][0] + (2.0f * d[0][1]) + d[0][2];
			Nx /= 9;
			Nx *= scale;

			Ny  = d[0][2] + (2.0f * d[1][2]) + d[2][2];
			Ny -= d[0][0] + (2.0f * d[1][0]) + d[2][0];
			Ny /= 9;
			Ny *= scale;

			Nz  = 0.5;

			NdotL = (Nx * Lx) + (Ny * Ly) + (Nz * Lz);
			NdotL = (NdotL > 0.0) ? NdotL : 0.0;

			dst[(y * stride) + x] = minc(ambient + (diffuse * NdotL));
		}
	}

dirty_ret:
	cairo_surface_mark_dirty(dst_surface);

	return dst_surface;
}
Beispiel #10
0
bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dstHeight, wxDC* source, int xsrc, int ysrc, int srcWidth, int srcHeight, wxRasterOperationMode rop, bool useMask, int xsrcMask, int ysrcMask)
{
    wxCHECK_MSG(IsOk(), false, "invalid DC");
    wxCHECK_MSG(source && source->IsOk(), false, "invalid source DC");

    cairo_t* cr = NULL;
    if (m_graphicContext)
        cr = static_cast<cairo_t*>(m_graphicContext->GetNativeContext());
    cairo_t* cr_src = NULL;
    wxGraphicsContext* gc_src = source->GetGraphicsContext();
    if (gc_src)
        cr_src = static_cast<cairo_t*>(gc_src->GetNativeContext());

    if (cr == NULL || cr_src == NULL)
        return false;

    const int xsrc_dev = source->LogicalToDeviceX(xsrc);
    const int ysrc_dev = source->LogicalToDeviceY(ysrc);

    cairo_surface_t* surfaceSrc = cairo_get_target(cr_src);
    cairo_surface_flush(surfaceSrc);

    cairo_surface_t* surfaceTmp = NULL;
    // If destination (this) and source wxDC refer to the same Cairo context
    // it means that we operate on one surface and results of drawing
    // can be invalid if destination and source regions overlap.
    // In such situation we have to copy source surface to the temporary
    // surface and use this copy in the drawing operations.
    if ( cr == cr_src )
    {
        // Check if destination and source regions overlap.
        // If necessary, copy source surface to the temporary one.
        if (wxRect(xdest, ydest, dstWidth, dstHeight)
            .Intersects(wxRect(xsrc, ysrc, srcWidth, srcHeight)))
        {
            const int w = cairo_image_surface_get_width(surfaceSrc);
            const int h = cairo_image_surface_get_height(surfaceSrc);
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
            if ( cairo_version() >= CAIRO_VERSION_ENCODE(1, 12, 0) )
            {
                surfaceTmp = cairo_surface_create_similar_image(surfaceSrc,
                     cairo_image_surface_get_format(surfaceSrc),
                     w, h);
            }
            else
#endif // Cairo 1.12
            {
                surfaceTmp = cairo_surface_create_similar(surfaceSrc,
                     CAIRO_CONTENT_COLOR_ALPHA,
                     w, h);
            }
            cairo_t* crTmp = cairo_create(surfaceTmp);
            cairo_set_source_surface(crTmp, surfaceSrc, 0, 0);
            cairo_rectangle(crTmp, 0.0, 0.0, w, h);
            cairo_set_operator(crTmp, CAIRO_OPERATOR_SOURCE);
            cairo_fill(crTmp);
            cairo_destroy(crTmp);
            cairo_surface_flush(surfaceTmp);
            surfaceSrc = surfaceTmp;
        }
    }
    cairo_save(cr);
    cairo_translate(cr, xdest, ydest);
    cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
    double sx, sy;
    source->GetUserScale(&sx, &sy);
    cairo_scale(cr, dstWidth / (sx * srcWidth), dstHeight / (sy * srcHeight));
    cairo_set_source_surface(cr, surfaceSrc, -xsrc_dev, -ysrc_dev);
    const wxRasterOperationMode rop_save = m_logicalFunction;
    SetLogicalFunction(rop);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
    cairo_surface_t* maskSurf = NULL;
    if (useMask)
    {
        const wxBitmap& bitmap = source->GetImpl()->GetSelectedBitmap();
        if (bitmap.IsOk())
        {
            wxMask* mask = bitmap.GetMask();
            if (mask)
                maskSurf = *mask;
        }
    }
    if (maskSurf)
    {
        int xsrcMask_dev = xsrc_dev;
        int ysrcMask_dev = ysrc_dev;
        if (xsrcMask != -1)
            xsrcMask_dev = source->LogicalToDeviceX(xsrcMask);
        if (ysrcMask != -1)
            ysrcMask_dev = source->LogicalToDeviceY(ysrcMask);
        cairo_clip(cr);
        cairo_mask_surface(cr, maskSurf, -xsrcMask_dev, -ysrcMask_dev);
    }
    else
    {
        cairo_fill(cr);
    }
    cairo_restore(cr);
    if ( surfaceTmp )
    {
        cairo_surface_destroy(surfaceTmp);
    }
    m_logicalFunction = rop_save;
    return true;
}
Beispiel #11
0
static GtkWidget *
gth_file_tool_resize_get_options (GthFileTool *base)
{
	GthFileToolResize *self = (GthFileToolResize *) base;
	cairo_surface_t   *source;
	GtkWidget         *window;
	GtkWidget         *viewer_page;
	GtkWidget         *viewer;
	GtkAllocation      allocation;
	int                preview_width;
	int                preview_height;
	GtkWidget         *options;
	char              *text;

	source = gth_image_viewer_page_tool_get_source (GTH_IMAGE_VIEWER_PAGE_TOOL (self));
	if (source == NULL)
		return NULL;

	self->priv->original_width = cairo_image_surface_get_width (source);
	self->priv->original_height = cairo_image_surface_get_height (source);

	window = gth_file_tool_get_window (base);
	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
	viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));

	gtk_widget_get_allocation (GTK_WIDGET (viewer), &allocation);
	preview_width = self->priv->original_width;
	preview_height = self->priv->original_height;
	if (scale_keeping_ratio (&preview_width, &preview_height, allocation.width, allocation.height, FALSE))
		self->priv->preview = _cairo_image_surface_scale_fast (source, preview_width, preview_height);
	else
		self->priv->preview = cairo_surface_reference (source);

	_gtk_widget_get_screen_size (window, &self->priv->screen_width, &self->priv->screen_height);
	self->priv->new_image = NULL;
	self->priv->new_width = self->priv->original_width;
	self->priv->new_height = self->priv->original_height;
	self->priv->high_quality = g_settings_get_boolean (self->priv->settings, PREF_RESIZE_HIGH_QUALITY);
	self->priv->unit = g_settings_get_enum (self->priv->settings, PREF_RESIZE_UNIT);
	self->priv->builder = _gtk_builder_new_from_file ("resize-options.ui", "file_tools");
	self->priv->apply_to_original = FALSE;

	update_dimensione_info_label (self,
				      "original_dimensions_label",
				      self->priv->original_width,
				      self->priv->original_height,
				      TRUE);

	options = _gtk_builder_get_widget (self->priv->builder, "options");
	gtk_widget_show (options);

	if (self->priv->unit == GTH_UNIT_PIXELS) {
		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 0);
		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 0);
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")),
					   g_settings_get_double (self->priv->settings, PREF_RESIZE_WIDTH));
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")),
					   g_settings_get_double (self->priv->settings, PREF_RESIZE_HEIGHT));
	}
	else if (self->priv->unit == GTH_UNIT_PERCENTAGE) {
		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")), 2);
		gtk_spin_button_set_digits (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")), 2);
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_width_spinbutton")),
					   g_settings_get_double (self->priv->settings, PREF_RESIZE_WIDTH));
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("resize_height_spinbutton")),
					   g_settings_get_double (self->priv->settings, PREF_RESIZE_HEIGHT));
	}
	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")), self->priv->unit);

	self->priv->ratio_combobox = _gtk_combo_box_new_with_texts (_("None"), _("Square"), NULL);
	text = g_strdup_printf (_("%d x %d (Image)"), self->priv->original_width, self->priv->original_height);
	gtk_label_set_text (GTK_LABEL (GET_WIDGET ("image_size_label")), text);
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->priv->ratio_combobox), text);
	g_free (text);
	text = g_strdup_printf (_("%d x %d (Screen)"), self->priv->screen_width, self->priv->screen_height);
	gtk_label_set_text (GTK_LABEL (GET_WIDGET ("screen_size_label")), text);
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (self->priv->ratio_combobox), text);
	g_free (text);
	_gtk_combo_box_append_texts (GTK_COMBO_BOX_TEXT (self->priv->ratio_combobox),
				     _("5:4"),
				     _("4:3 (DVD, Book)"),
				     _("7:5"),
				     _("3:2 (Postcard)"),
				     _("16:10"),
				     _("16:9 (DVD)"),
				     _("1.85:1"),
				     _("2.39:1"),
				     _("Custom"),
				     NULL);
	gtk_widget_show (self->priv->ratio_combobox);
	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("ratio_combobox_box")), self->priv->ratio_combobox, TRUE, TRUE, 0);

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("high_quality_checkbutton")),
				      self->priv->high_quality);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("invert_ratio_checkbutton")),
				      g_settings_get_boolean (self->priv->settings, PREF_RESIZE_ASPECT_RATIO_INVERT));

	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_w_spinbutton")),
				   MAX (g_settings_get_int (self->priv->settings, PREF_RESIZE_ASPECT_RATIO_WIDTH), 1));
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("ratio_h_spinbutton")),
				   MAX (g_settings_get_int (self->priv->settings, PREF_RESIZE_ASPECT_RATIO_HEIGHT), 1));

	g_signal_connect_swapped (GET_WIDGET ("options_close_button"),
				  "clicked",
				  G_CALLBACK (gtk_widget_hide),
				  GET_WIDGET ("options_dialog"));
	g_signal_connect (GET_WIDGET ("options_dialog"),
			  "delete-event",
			  G_CALLBACK (gtk_widget_hide_on_delete),
			  NULL);
	g_signal_connect (GET_WIDGET ("resize_width_spinbutton"),
			  "value-changed",
			  G_CALLBACK (selection_width_value_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("resize_height_spinbutton"),
			  "value-changed",
			  G_CALLBACK (selection_height_value_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("high_quality_checkbutton"),
			  "toggled",
			  G_CALLBACK (high_quality_checkbutton_toggled_cb),
			  self);
	g_signal_connect (GET_WIDGET ("unit_combobox"),
			  "changed",
			  G_CALLBACK (unit_combobox_changed_cb),
			  self);
	g_signal_connect (self->priv->ratio_combobox,
			  "changed",
			  G_CALLBACK (ratio_combobox_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("ratio_w_spinbutton"),
			  "value_changed",
			  G_CALLBACK (ratio_value_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("ratio_h_spinbutton"),
			  "value_changed",
			  G_CALLBACK (ratio_value_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("invert_ratio_checkbutton"),
			  "toggled",
			  G_CALLBACK (invert_ratio_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("image_size_button"),
			  "clicked",
			  G_CALLBACK (image_size_button_clicked_cb),
			  self);
	g_signal_connect (GET_WIDGET ("screen_size_button"),
			  "clicked",
			  G_CALLBACK (screen_size_button_clicked_cb),
			  self);

	gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->ratio_combobox),
				  g_settings_get_enum (self->priv->settings, PREF_RESIZE_ASPECT_RATIO));

	gth_image_viewer_set_zoom_quality (GTH_IMAGE_VIEWER (viewer), GTH_ZOOM_QUALITY_HIGH);

	return options;
}
Beispiel #12
0
int main(int argc, char **argv) {
    char *image_path = NULL;
    char *scaling_mode_str = "fit";

    init_log(L_INFO);

    static struct option long_options[] = {
        {"help", no_argument, NULL, 'h'},
        {"image", required_argument, NULL, 'i'},
        {"scaling", required_argument, NULL, 's'},
        {"tiling", no_argument, NULL, 't'},
        {"version", no_argument, NULL, 'v'},
        {0, 0, 0, 0}
    };

    const char *usage =
        "Usage: swaylock [options...]\n"
        "\n"
        "  -h, --help             Show help message and quit.\n"
        "  -s, --scaling          Scaling mode: stretch, fill, fit, center, tile.\n"
        "  -t, --tiling           Same as --scaling=tile.\n"
        "  -v, --version          Show the version number and quit.\n"
        "  -i, --image <path>     Display the given image.\n";

    int c;
    while (1) {
        int option_index = 0;
        c = getopt_long(argc, argv, "hi:s:tv", long_options, &option_index);
        if (c == -1) {
            break;
        }
        switch (c) {
        case 'i':
            image_path = optarg;
            break;
        case 's':
            scaling_mode_str = optarg;
            break;
        case 't':
            scaling_mode_str = "tile";
            break;
        case 'v':
#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE
            fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH);
#else
            fprintf(stdout, "version not detected\n");
#endif
            exit(EXIT_SUCCESS);
            break;
        default:
            fprintf(stderr, "%s", usage);
            exit(EXIT_FAILURE);
        }
    }

    // TODO: support locking without image
    if (!image_path) {
        fprintf(stderr, "No image specified!\n");
        exit(EXIT_FAILURE);
    }

    password = malloc(1024); // TODO: Let this grow
    password[0] = '\0';
    surfaces = create_list();
    registry = registry_poll();

    if (!registry->swaylock) {
        sway_abort("swaylock requires the compositor to support the swaylock extension.");
    }

    int i;
    for (i = 0; i < registry->outputs->length; ++i) {
        struct output_state *output = registry->outputs->items[i];
        struct window *window = window_setup(registry, output->width, output->height, true);
        if (!window) {
            sway_abort("Failed to create surfaces.");
        }
        list_add(surfaces, window);
    }

    registry->input->notify = notify_key;

#ifdef WITH_GDK_PIXBUF
    GError *err = NULL;
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err);
    if (!pixbuf) {
        sway_abort("Failed to load background image.");
    }
    cairo_surface_t *image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
    g_object_unref(pixbuf);
#else
    cairo_surface_t *image = cairo_image_surface_create_from_png(argv[1]);
#endif //WITH_GDK_PIXBUF
    if (!image) {
        sway_abort("Failed to read background image.");
    }
    double width = cairo_image_surface_get_width(image);
    double height = cairo_image_surface_get_height(image);

    enum scaling_mode scaling_mode = SCALING_MODE_STRETCH;
    if (strcmp(scaling_mode_str, "stretch") == 0) {
        scaling_mode = SCALING_MODE_STRETCH;
    } else if (strcmp(scaling_mode_str, "fill") == 0) {
        scaling_mode = SCALING_MODE_FILL;
    } else if (strcmp(scaling_mode_str, "fit") == 0) {
        scaling_mode = SCALING_MODE_FIT;
    } else if (strcmp(scaling_mode_str, "center") == 0) {
        scaling_mode = SCALING_MODE_CENTER;
    } else if (strcmp(scaling_mode_str, "tile") == 0) {
        scaling_mode = SCALING_MODE_TILE;
    } else {
        sway_abort("Unsupported scaling mode: %s", scaling_mode_str);
    }

    for (i = 0; i < surfaces->length; ++i) {
        struct window *window = surfaces->items[i];
        if (window_prerender(window) && window->cairo) {
            switch (scaling_mode) {
            case SCALING_MODE_STRETCH:
                cairo_scale(window->cairo,
                            (double) window->width / width,
                            (double) window->height / height);
                cairo_set_source_surface(window->cairo, image, 0, 0);
                break;
            case SCALING_MODE_FILL:
            {
                double window_ratio = (double) window->width / window->height;
                double bg_ratio = width / height;

                if (window_ratio > bg_ratio) {
                    double scale = (double) window->width / width;
                    cairo_scale(window->cairo, scale, scale);
                    cairo_set_source_surface(window->cairo, image,
                                             0,
                                             (double) window->height/2 / scale - height/2);
                } else {
                    double scale = (double) window->height / height;
                    cairo_scale(window->cairo, scale, scale);
                    cairo_set_source_surface(window->cairo, image,
                                             (double) window->width/2 / scale - width/2,
                                             0);
                }
                break;
            }
            case SCALING_MODE_FIT:
            {
                double window_ratio = (double) window->width / window->height;
                double bg_ratio = width / height;

                if (window_ratio > bg_ratio) {
                    double scale = (double) window->height / height;
                    cairo_scale(window->cairo, scale, scale);
                    cairo_set_source_surface(window->cairo, image,
                                             (double) window->width/2 / scale - width/2,
                                             0);
                } else {
                    double scale = (double) window->width / width;
                    cairo_scale(window->cairo, scale, scale);
                    cairo_set_source_surface(window->cairo, image,
                                             0,
                                             (double) window->height/2 / scale - height/2);
                }
                break;
            }
            case SCALING_MODE_CENTER:
                cairo_set_source_surface(window->cairo, image,
                                         (double) window->width/2 - width/2,
                                         (double) window->height/2 - height/2);
                break;
            case SCALING_MODE_TILE:
            {
                cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image);
                cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
                cairo_set_source(window->cairo, pattern);
                break;
            }
            default:
                sway_abort("Scaling mode '%s' not implemented yet!", scaling_mode_str);
            }

            cairo_paint(window->cairo);

            window_render(window);
        }
    }

    cairo_surface_destroy(image);

    bool locked = false;
    while (wl_display_dispatch(registry->display) != -1) {
        if (!locked) {
            for (i = 0; i < registry->outputs->length; ++i) {
                struct output_state *output = registry->outputs->items[i];
                struct window *window = surfaces->items[i];
                lock_set_lock_surface(registry->swaylock, output->output, window->surface);
            }
            locked = true;
        }
    }

    for (i = 0; i < surfaces->length; ++i) {
        struct window *window = surfaces->items[i];
        window_teardown(window);
    }
    list_free(surfaces);
    registry_teardown(registry);

    return 0;
}
  void flush()
  {
    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A8, _totalWidth, _maxHeight);
    cairo_t *cr = cairo_create(surface);
    int pos = 0;
    cairo_set_source_rgba (cr, 0., 0., 0., 0);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    cairo_paint(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_font_options_t *fontOptions = cairo_font_options_create();
    cairo_get_font_options(cr, fontOptions);
    cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
    cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY);
    cairo_set_font_options(cr, fontOptions);
    cairo_font_options_destroy(fontOptions);

    cairo_set_source_rgba(cr, 1, 1, 1, 1);
    for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end();  ++it) {
      cairo_move_to(cr, pos - it->xBearing, -it->yBearing);
      cairo_set_font_size(cr, it->fontSize);
      cairo_set_font_face(cr, it->fontFace);
      cairo_show_text(cr, it->text.c_str());
      cairo_font_face_destroy(it->fontFace);
      pos += it->width;
    }
    cairo_destroy(cr);
    //setup matrices
    GLint matrixMode;
    GLuint textureId;
    glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
    glMatrixMode (GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity ();
    glMatrixMode (GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity ();
    float winw = Fl_Window::current()->w();
    float winh = Fl_Window::current()->h();
    glScalef (2.0f / winw, 2.0f /  winh, 1.0f);
    glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f);
    //write the texture on screen
    glEnable(GL_TEXTURE_RECTANGLE_ARB);
    glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureId);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA,
                 cairo_image_surface_get_width(surface),
                 cairo_image_surface_get_height(surface), 0,
                 GL_ALPHA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data(surface));
    //glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SRC0_ALPHA);
    //printf("error %i %s\n", __LINE__, gluErrorString(glGetError()));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    pos = 0;
    for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end();  ++it) {
      glTranslatef(it->x, it->y, it->z);
      glColor4f(it->r, it->g, it->b, it->alpha);
      int Lx = it->width;
      int Ly = it->height;

      glBegin (GL_QUADS);
      glTexCoord2f (pos, 0);
      glVertex2f (0.0f, Ly);
      glTexCoord2f (pos + Lx, 0);
      glVertex2f (Lx, Ly);
      glTexCoord2f (pos + Lx, Ly);
      glVertex2f (Lx, 0.0f);
      glTexCoord2f (pos, Ly);
      glVertex2f (0.0f, 0.0f);
      glEnd ();
      pos += Lx;
      glTranslatef(-it->x, -it->y, -it->z);
    }
    glDeleteTextures(1, &textureId);

    glPopAttrib();

    // reset original matrices
    glPopMatrix(); // GL_MODELVIEW
    glMatrixMode (GL_PROJECTION);
    glPopMatrix();
    glMatrixMode (matrixMode);
    _elements.clear();
    _maxHeight = 0;
    _totalWidth = 0;
    cairo_surface_destroy(surface);
  }
Beispiel #14
0
GtkWidget *create_class_page (void)
{
#if 1
  GtkWidget *vbox;
  gchar *path;

  vbox = gtk_vbox_new (FALSE, 0);

  priv->kb = utt_keyboard_new ();
  path = g_build_filename (PKGDATADIR, "keyboard_wubi.png", NULL);
  utt_keyboard_set_image (UTT_KEYBOARD (priv->kb), path);
  g_free (path);
  gtk_box_pack_start (GTK_BOX (vbox), priv->kb, FALSE, FALSE, 0);
  return vbox;
#else
  GtkWidget *vbox;
  GtkWidget *frame, *hbox, *hbox2, *align;
  GtkWidget *ch_draw[6];
  GtkWidget *kb_draw;
  cairo_surface_t *kb_image;
  gint i;
  gchar *path;

  vbox = gtk_vbox_new (FALSE, 0);
  frame = gtk_frame_new (_("Display Zone"));
  hbox = gtk_hbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (frame), hbox);
  gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
  gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);

  /* padding */
  hbox2 = gtk_hbox_new (FALSE, 0);
  gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0);
  for (i = 0; i < 6; i++) {
    ch_draw[i] = gtk_drawing_area_new ();
    gtk_widget_set_size_request (ch_draw[i], 48, 48);
    hbox2 = gtk_hbox_new (FALSE, 0);
    gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0);
    align = gtk_alignment_new (0.5, 0.5, 0, 0);
    gtk_container_add (GTK_CONTAINER (align), ch_draw[i]);
    gtk_box_pack_start (GTK_BOX (hbox2), align, TRUE, TRUE, 0);
  }
  /* padding */
  hbox2 = gtk_hbox_new (FALSE, 0);
  gtk_box_pack_start (GTK_BOX (hbox), hbox2, TRUE, TRUE, 0);

  kb_draw = gtk_drawing_area_new ();
  path = g_build_filename (PKGDATADIR, "keyboard_wubi.png", NULL);
  if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
    g_error (G_STRLOC ": %s doesn't exists.", path);
  }
  kb_image = cairo_image_surface_create_from_png (path);
  g_free (path);

  gtk_widget_add_events (kb_draw, GDK_KEY_PRESS_MASK);
  /* set can focus and grab focus, so we can receive key press event */
  gtk_widget_set_can_focus (kb_draw, TRUE);
  gtk_widget_set_size_request (kb_draw,
			       cairo_image_surface_get_width (kb_image),
			       cairo_image_surface_get_height (kb_image));
  align = gtk_alignment_new (0.5, 0.5, 0, 0);
  gtk_container_add (GTK_CONTAINER (align), kb_draw);
  gtk_container_set_border_width (GTK_CONTAINER (align), 4);
  gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);

  return vbox;
#endif
}
guac_palette* guac_palette_alloc(cairo_surface_t* surface) {

    int x, y;

    int width = cairo_image_surface_get_width(surface);
    int height = cairo_image_surface_get_height(surface);
    int stride = cairo_image_surface_get_stride(surface);
    unsigned char* data = cairo_image_surface_get_data(surface);

    /* Allocate palette */
    guac_palette* palette = (guac_palette*) malloc(sizeof(guac_palette));
    memset(palette, 0, sizeof(guac_palette));

    for (y=0; y<height; y++) {
        for (x=0; x<width; x++) {

            /* Get pixel color */
            int color = ((uint32_t*) data)[x] & 0xFFFFFF;

            /* Calculate hash code */
            int hash = ((color & 0xFFF000) >> 12) ^ (color & 0xFFF);

            guac_palette_entry* entry;

            /* Search for open palette entry */
            for (;;) {
                
                entry = &(palette->entries[hash]);

                /* If we've found a free space, use it */
                if (entry->index == 0) {

                    png_color* c;

                    /* Stop if already at capacity */
                    if (palette->size == 256) {
                        guac_palette_free(palette);
                        return NULL;
                    }

                    /* Store in palette */
                    c = &(palette->colors[palette->size]);
                    c->blue  = (color      ) & 0xFF;
                    c->green = (color >> 8 ) & 0xFF;
                    c->red   = (color >> 16) & 0xFF;

                    /* Add color to map */
                    entry->index = ++palette->size;
                    entry->color = color;

                    break;

                }

                /* Otherwise, if already stored here, done */
                if (entry->color == color)
                    break;

                /* Otherwise, collision. Move on to another bucket */
                hash = (hash+1) & 0xFFF;

            }
        }

        /* Advance to next data row */
        data += stride;

    }
static gpointer
equalize_exec (GthAsyncTask *task,
	       gpointer      user_data)
{
	EqualizeData    *equalize_data = user_data;
	cairo_surface_t *source;
	cairo_format_t   format;
	int              width;
	int              height;
	int              source_stride;
	cairo_surface_t *destination;
	int              destination_stride;
	unsigned char   *p_source_line;
	unsigned char   *p_destination_line;
	unsigned char   *p_source;
	unsigned char   *p_destination;
	gboolean         cancelled;
	double           progress;
	int              x, y;
	unsigned char    red, green, blue, alpha;

	/* initialize the extra data */

	source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task));
	equalize_histogram_setup (equalize_data, source);

	/* convert the image */

	format = cairo_image_surface_get_format (source);
	width = cairo_image_surface_get_width (source);
	height = cairo_image_surface_get_height (source);
	source_stride = cairo_image_surface_get_stride (source);

	destination = cairo_image_surface_create (format, width, height);
	destination_stride = cairo_image_surface_get_stride (destination);
	p_source_line = _cairo_image_surface_flush_and_get_data (source);
	p_destination_line = _cairo_image_surface_flush_and_get_data (destination);
	for (y = 0; y < height; y++) {
		gth_async_task_get_data (task, NULL, &cancelled, NULL);
		if (cancelled)
			return NULL;

		progress = (double) y / height;
		gth_async_task_set_data (task, NULL, NULL, &progress);

		p_source = p_source_line;
		p_destination = p_destination_line;
		for (x = 0; x < width; x++) {
			CAIRO_GET_RGBA (p_source, red, green, blue, alpha);
			red   = equalize_func (equalize_data, GTH_HISTOGRAM_CHANNEL_RED, red);
			green = equalize_func (equalize_data, GTH_HISTOGRAM_CHANNEL_GREEN, green);
			blue  = equalize_func (equalize_data, GTH_HISTOGRAM_CHANNEL_BLUE, blue);
			CAIRO_SET_RGBA (p_destination, red, green, blue, alpha);

			p_source += 4;
			p_destination += 4;
		}
		p_source_line += source_stride;
		p_destination_line += destination_stride;
	}

	cairo_surface_mark_dirty (destination);
	gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination);

	cairo_surface_destroy (destination);
	cairo_surface_destroy (source);

	return NULL;
}
Beispiel #17
0
/**
 * _st_create_shadow_cairo_pattern:
 * @shadow_spec: the definition of the shadow
 * @src_pattern: surface pattern for which we create the shadow
 *               (must be a surface pattern)
 *
 * This is a utility function for creating shadows used by
 * st-theme-node.c; it's in this file to share the gaussian
 * blur implementation. The usage of this function is quite different
 * depending on whether shadow_spec->inset is %TRUE or not. If
 * shadow_spec->inset is %TRUE, the caller should pass in a @src_pattern
 * which is the <i>inverse</i> of what they want shadowed, and must take
 * care of the spread and offset from the shadow spec themselves. If
 * shadow_spec->inset is %FALSE then the caller should pass in what they
 * want shadowed directly, and this function takes care of the spread and
 * the offset.
 */
cairo_pattern_t *
_st_create_shadow_cairo_pattern (StShadow        *shadow_spec,
                                 cairo_pattern_t *src_pattern)
{
  static cairo_user_data_key_t shadow_pattern_user_data;
  cairo_t *cr;
  cairo_surface_t *src_surface;
  cairo_surface_t *surface_in;
  cairo_surface_t *surface_out;
  cairo_pattern_t *dst_pattern;
  guchar          *pixels_in, *pixels_out;
  gint             width_in, height_in, rowstride_in;
  gint             width_out, height_out, rowstride_out;
  cairo_matrix_t   shadow_matrix;
  int i, j;

  g_return_val_if_fail (shadow_spec != NULL, NULL);
  g_return_val_if_fail (src_pattern != NULL, NULL);

  cairo_pattern_get_surface (src_pattern, &src_surface);

  width_in  = cairo_image_surface_get_width  (src_surface);
  height_in = cairo_image_surface_get_height (src_surface);

  /* We want the output to be a color agnostic alpha mask,
   * so we need to strip the color channels from the input
   */
  if (cairo_image_surface_get_format (src_surface) != CAIRO_FORMAT_A8)
    {
      surface_in = cairo_image_surface_create (CAIRO_FORMAT_A8,
                                               width_in, height_in);

      cr = cairo_create (surface_in);
      cairo_set_source_surface (cr, src_surface, 0, 0);
      cairo_paint (cr);
      cairo_destroy (cr);
    }
  else
    {
      surface_in = cairo_surface_reference (src_surface);
    }

  pixels_in = cairo_image_surface_get_data (surface_in);
  rowstride_in = cairo_image_surface_get_stride (surface_in);

  pixels_out = blur_pixels (pixels_in, width_in, height_in, rowstride_in,
                            shadow_spec->blur,
                            &width_out, &height_out, &rowstride_out);
  cairo_surface_destroy (surface_in);

  /* Invert pixels for inset shadows */
  if (shadow_spec->inset)
    {
      for (j = 0; j < height_out; j++)
        {
          guchar *p = pixels_out + rowstride_out * j;
          for (i = 0; i < width_out; i++, p++)
            *p = ~*p;
        }
    }

  surface_out = cairo_image_surface_create_for_data (pixels_out,
                                                     CAIRO_FORMAT_A8,
                                                     width_out,
                                                     height_out,
                                                     rowstride_out);
  cairo_surface_set_user_data (surface_out, &shadow_pattern_user_data,
                               pixels_out, (cairo_destroy_func_t) g_free);

  dst_pattern = cairo_pattern_create_for_surface (surface_out);
  cairo_surface_destroy (surface_out);

  cairo_pattern_get_matrix (src_pattern, &shadow_matrix);

  if (shadow_spec->inset)
    {
      /* For inset shadows, offsets and spread radius have already been
       * applied to the original pattern, so all left to do is shift the
       * blurred image left, so that it aligns centered under the
       * unblurred one
       */
      cairo_matrix_translate (&shadow_matrix,
                              (width_out - width_in) / 2.0,
                              (height_out - height_in) / 2.0);
      cairo_pattern_set_matrix (dst_pattern, &shadow_matrix);
      return dst_pattern;
    }

  /* Read all the code from the cairo_pattern_set_matrix call
   * at the end of this function to here from bottom to top,
   * because each new affine transformation is applied in
   * front of all the previous ones */

  /* 6. Invert the matrix back */
  cairo_matrix_invert (&shadow_matrix);

  /* 5. Adjust based on specified offsets */
  cairo_matrix_translate (&shadow_matrix,
                          shadow_spec->xoffset,
                          shadow_spec->yoffset);

  /* 4. Recenter the newly scaled image */
  cairo_matrix_translate (&shadow_matrix,
                          - shadow_spec->spread,
                          - shadow_spec->spread);

  /* 3. Scale up the blurred image to fill the spread */
  cairo_matrix_scale (&shadow_matrix,
                      (width_in + 2.0 * shadow_spec->spread) / width_in,
                      (height_in + 2.0 * shadow_spec->spread) / height_in);

  /* 2. Shift the blurred image left, so that it aligns centered
   * under the unblurred one */
  cairo_matrix_translate (&shadow_matrix,
                          - (width_out - width_in) / 2.0,
                          - (height_out - height_in) / 2.0);

  /* 1. Invert the matrix so we can work with it in pattern space
   */
  cairo_matrix_invert (&shadow_matrix);

  cairo_pattern_set_matrix (dst_pattern, &shadow_matrix);

  return dst_pattern;
}
Beispiel #18
0
int
ink_cairo_surface_get_height(cairo_surface_t *surface)
{
    assert(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE);
    return cairo_image_surface_get_height(surface);
}
static gpointer
negative_exec (GthAsyncTask *task,
	       gpointer      user_data)
{
	cairo_surface_t *source;
	cairo_format_t   format;
	int              width;
	int              height;
	int              source_stride;
	cairo_surface_t *destination;
	int              destination_stride;
	unsigned char   *p_source_line;
	unsigned char   *p_destination_line;
	unsigned char   *p_source;
	unsigned char   *p_destination;
	gboolean         cancelled;
	double           progress;
	int              x, y;
	unsigned char    red, green, blue, alpha;

	source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task));
	format = cairo_image_surface_get_format (source);
	width = cairo_image_surface_get_width (source);
	height = cairo_image_surface_get_height (source);
	source_stride = cairo_image_surface_get_stride (source);

	destination = cairo_image_surface_create (format, width, height);
	destination_stride = cairo_image_surface_get_stride (destination);
	p_source_line = _cairo_image_surface_flush_and_get_data (source);
	p_destination_line = _cairo_image_surface_flush_and_get_data (destination);
	for (y = 0; y < height; y++) {
		gth_async_task_get_data (task, NULL, &cancelled, NULL);
		if (cancelled)
			return NULL;

		progress = (double) y / height;
		gth_async_task_set_data (task, NULL, NULL, &progress);

		p_source = p_source_line;
		p_destination = p_destination_line;
		for (x = 0; x < width; x++) {
			CAIRO_GET_RGBA (p_source, red, green, blue, alpha);
			CAIRO_SET_RGBA (p_destination,
					255 - red,
					255 - green,
					255 - blue,
					alpha);

			p_source += 4;
			p_destination += 4;
		}
		p_source_line += source_stride;
		p_destination_line += destination_stride;
	}

	cairo_surface_mark_dirty (destination);
	gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination);

	cairo_surface_destroy (destination);
	cairo_surface_destroy (source);

	return NULL;
}
Beispiel #20
0
static gint
get_surface_size (cairo_surface_t *surface)
{
  return MAX (cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
}
Beispiel #21
0
static void
render_to_surface (const RENDER * render, SNDFILE *infile, int samplerate, sf_count_t filelen, cairo_surface_t * surface)
{
	float ** mag_spec = NULL ; // Indexed by [w][h]

	spectrum *spec ;
	double max_mag = 0.0 ;
	int width, height, w, speclen ;

	if (render->border)
	{	width = lrint (cairo_image_surface_get_width (surface) - LEFT_BORDER - RIGHT_BORDER) ;
		height = lrint (cairo_image_surface_get_height (surface) - TOP_BORDER - BOTTOM_BORDER) ;
		}
	else
	{	width = render->width ;
		height = render->height ;
		}

	if (width < 1)
	{	printf ("Error : 'width' parameter must be >= %d\n",
			render->border ? (int) (LEFT_BORDER + RIGHT_BORDER) + 1 : 1) ;
		exit (1) ;
		} ;

	if (height < 1)
	{	printf ("Error : 'height' parameter must be >= %d\n",
			render->border ? (int) (TOP_BORDER + BOTTOM_BORDER) + 1 : 1) ;
		exit (1) ;
		} ;

	/*
	** Choose a speclen value, the spectrum length.
	** The FFT window size is twice this.
	*/
	if (render->fft_freq != 0.0)
		/* Choose an FFT window size of 1/fft_freq seconds of audio */
		speclen = (samplerate / render->fft_freq + 1) / 2 ;
	else
		/* Long enough to represent frequencies down to 20Hz. */
		speclen = height * (samplerate / 20 / height + 1) ;

	/* Find the nearest fast value for the FFT size. */
	{	int d ;	/* difference */

		for (d = 0 ; /* Will terminate */ ; d++)
		{	/* Logarithmically, the integer above is closer than
			** the integer below, so prefer it to the one below.
			*/
			if (is_good_speclen (speclen + d))
			{	speclen += d ;
				break ;
				}
			/* FFT length must also be >= the output height,
			** otherwise repeated pixel rows occur in the output.
			*/
			if (speclen - d >= height && is_good_speclen (speclen - d))
			{	speclen -= d ;
				break ;
				}
			}
		}

	mag_spec = calloc (width, sizeof (float *)) ;
	if (mag_spec == NULL)
	{	printf ("%s : Not enough memory.\n", __func__) ;
		exit (1) ;
		} ;
	for (w = 0 ; w < width ; w++)
	{	if ((mag_spec [w] = calloc (height, sizeof (float))) == NULL)
		{	printf ("%s : Not enough memory.\n", __func__) ;
			exit (1) ;
			} ;
		} ;

	spec = create_spectrum (speclen, render->window_function) ;

	if (spec == NULL)
	{	printf ("%s : line %d : create plan failed.\n", __FILE__, __LINE__) ;
		exit (1) ;
		} ;

	for (w = 0 ; w < width ; w++)
	{	double single_max ;

		read_mono_audio (infile, filelen, spec->time_domain, 2 * speclen, w, width) ;

		single_max = calc_magnitude_spectrum (spec) ;
		max_mag = MAX (max_mag, single_max) ;

		interp_spec (mag_spec [w], height, spec->mag_spec, speclen, render, samplerate) ;
		} ;

	destroy_spectrum (spec) ;

	if (render->border)
	{	RECT heat_rect ;

		heat_rect.left = 12 ;
		heat_rect.top = TOP_BORDER + TOP_BORDER / 2 ;
		heat_rect.width = 12 ;
		heat_rect.height = height - TOP_BORDER / 2 ;

		render_spectrogram (surface, render->spec_floor_db, mag_spec, max_mag, LEFT_BORDER, TOP_BORDER, width, height, render->gray_scale) ;

		render_heat_map (surface, render->spec_floor_db, &heat_rect, render->gray_scale) ;

		render_spect_border (surface, render->filename, LEFT_BORDER, width, filelen / (1.0 * samplerate), TOP_BORDER, height, render->min_freq, render->max_freq, render->log_freq) ;
		render_heat_border (surface, render->spec_floor_db, &heat_rect) ;
		}
	else
		render_spectrogram (surface, render->spec_floor_db, mag_spec, max_mag, 0, 0, width, height, render->gray_scale) ;

	for (w = 0 ; w < width ; w++)
		free (mag_spec [w]) ;
	free (mag_spec) ;

	return ;
} /* render_to_surface */
Beispiel #22
0
bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
{
    // This implementation is taken from GraphicsContext3DCairo.

    if (!m_image)
        return false;

    // We need this to stay in scope because the native image is just a shallow copy of the data.
    m_decoder = new ImageSource(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied, ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);

    if (!m_decoder)
        return false;

    ImageSource& decoder = *m_decoder;
    m_alphaOp = AlphaDoNothing;

    if (m_image->data()) {
        decoder.setData(m_image->data(), true);

        if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
            return false;

        m_imageSurface = decoder.createFrameAtIndex(0);
    } else {
        m_imageSurface = m_image->nativeImageForCurrentFrame();
        // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel,
        // which is true at present and may be changed in the future and needs adjustment accordingly.
        // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port,
        // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
        if (!premultiplyAlpha && m_imageHtmlDomSource != HtmlDomVideo)
            m_alphaOp = AlphaDoUnmultiply;
    }

    if (!m_imageSurface)
        return false;

    m_imageWidth = cairo_image_surface_get_width(m_imageSurface.get());
    m_imageHeight = cairo_image_surface_get_height(m_imageSurface.get());

    if (!m_imageWidth || !m_imageHeight)
        return false;

    if (cairo_image_surface_get_format(m_imageSurface.get()) != CAIRO_FORMAT_ARGB32)
        return false;

    uint srcUnpackAlignment = 1;
    size_t bytesPerRow = cairo_image_surface_get_stride(m_imageSurface.get());
    size_t bitsPerPixel = 32;
    unsigned padding = bytesPerRow - bitsPerPixel / 8 * m_imageWidth;

    if (padding) {
        srcUnpackAlignment = padding + 1;
        while (bytesPerRow % srcUnpackAlignment)
            ++srcUnpackAlignment;
    }

    m_imagePixelData = cairo_image_surface_get_data(m_imageSurface.get());
    m_imageSourceFormat = DataFormatBGRA8;
    m_imageSourceUnpackAlignment = srcUnpackAlignment;

    return true;
}
Beispiel #23
0
void gui_init(dt_lib_module_t *self)
{
  char filename[PATH_MAX] = { 0 };
  char datadir[PATH_MAX] = { 0 };
  /* initialize ui widgets */
  dt_lib_darktable_t *d = (dt_lib_darktable_t *)g_malloc0(sizeof(dt_lib_darktable_t));
  self->data = (void *)d;

  /* create drawing area */
  self->widget = gtk_event_box_new();

  /* connect callbacks */
  g_signal_connect(G_OBJECT(self->widget), "draw", G_CALLBACK(_lib_darktable_draw_callback), self);
  g_signal_connect(G_OBJECT(self->widget), "button-press-event",
                   G_CALLBACK(_lib_darktable_button_press_callback), self);

  /* create a cairo surface of dt icon */
  char *logo;
  dt_logo_season_t season = get_logo_season();
  if(season != DT_LOGO_SEASON_NONE)
    logo = g_strdup_printf("%%s/pixmaps/idbutton-%d.%%s", (int)season);
  else
    logo = g_strdup("%s/pixmaps/idbutton.%s");

  dt_loc_get_datadir(datadir, sizeof(datadir));
  snprintf(filename, sizeof(filename), logo, datadir, "svg");

  // first we try the SVG
  {
    GError *error = NULL;
    RsvgHandle *svg = rsvg_handle_new_from_file(filename, &error);
    if(!svg || error)
    {
      fprintf(stderr,
              "warning: can't load darktable logo from SVG file `%s', falling back to PNG version\n%s\n",
              filename, error->message);
      g_error_free(error);
      error = NULL;
      goto png_fallback;
    }

    cairo_surface_t *surface;
    cairo_t *cr;

    RsvgDimensionData dimension;
    rsvg_handle_get_dimensions(svg, &dimension);

    int width = DT_PIXEL_APPLY_DPI(dimension.width) * darktable.gui->ppd,
        height = DT_PIXEL_APPLY_DPI(dimension.height) * darktable.gui->ppd;
    int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);

    d->image_buffer = (guint8 *)calloc(stride * height, sizeof(guint8));
    surface
        = dt_cairo_image_surface_create_for_data(d->image_buffer, CAIRO_FORMAT_ARGB32, width, height, stride);
    if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
    {
      free(d->image_buffer);
      d->image_buffer = NULL;
      g_object_unref(svg);
      fprintf(stderr, "warning: can't load darktable logo from SVG file `%s', falling back to PNG version\n",
              filename);
      goto png_fallback;
    }

    cr = cairo_create(surface);
    cairo_scale(cr, darktable.gui->dpi_factor, darktable.gui->dpi_factor);
    rsvg_handle_render_cairo(svg, cr);
    cairo_destroy(cr);
    cairo_surface_flush(surface);

    d->image = surface;
    g_object_unref(svg);
  }

  goto done;

png_fallback:
  // let's fall back to the PNG
  {
    cairo_surface_t *surface;
    cairo_t *cr;

    snprintf(filename, sizeof(filename), logo, datadir, "png");
    surface = cairo_image_surface_create_from_png(filename);
    if(cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
    {
      fprintf(stderr, "warning: can't load darktable logo from PNG file `%s'\n", filename);
      d->image = NULL;
      goto done;
    }
    int png_width = cairo_image_surface_get_width(surface),
        png_height = cairo_image_surface_get_height(surface);

    // blow up the PNG. Ugly, but at least it has the correct size afterwards :-/
    int width = DT_PIXEL_APPLY_DPI(png_width) * darktable.gui->ppd,
        height = DT_PIXEL_APPLY_DPI(png_height) * darktable.gui->ppd;
    int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);

    d->image_buffer = (guint8 *)calloc(stride * height, sizeof(guint8));
    d->image
        = dt_cairo_image_surface_create_for_data(d->image_buffer, CAIRO_FORMAT_ARGB32, width, height, stride);
    if(cairo_surface_status(d->image) != CAIRO_STATUS_SUCCESS)
    {
      free(d->image_buffer);
      d->image_buffer = NULL;
      cairo_surface_destroy(surface);
      fprintf(stderr, "warning: can't load darktable logo from PNG file `%s'\n", filename);
      d->image = NULL;
      goto done;
    }

    cr = cairo_create(d->image);
    cairo_rectangle(cr, 0, 0, width, height);
    cairo_scale(cr, darktable.gui->dpi_factor, darktable.gui->dpi_factor);
    cairo_set_source_surface(cr, surface, 0, 0);
    cairo_fill(cr);
    cairo_destroy(cr);
    cairo_surface_flush(d->image);

    cairo_surface_destroy(surface);
  }

done:
  g_free(logo);

  d->image_width = d->image ? dt_cairo_image_surface_get_width(d->image) : 0;
  d->image_height = d->image ? dt_cairo_image_surface_get_height(d->image) : 0;

  /* set size of drawing area */
  gtk_widget_set_size_request(self->widget, d->image_width + (int)DT_PIXEL_APPLY_DPI(180),
                              d->image_height + (int)DT_PIXEL_APPLY_DPI(8));
}
Beispiel #24
0
/* 
 * function to draw the rectangular selection
 */
static void
paint_selection (cairo_t *ci, Detect * d)
{

	double t =  microtime();

	int w = cairo_image_surface_get_width (surface);
	int h = cairo_image_surface_get_height (surface);

	/** draw brush */ /*
	cairo_surface_t* test;
	cairo_t *cb;
	double brush_w = 70, brush_h = 70;
	int w = cairo_image_surface_get_width (image);
	int h = cairo_image_surface_get_height (image);

	test = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h );
	cb = cairo_create(test);
	cairo_scale (cb, brush_w/w, brush_h/h);
	cairo_set_source_surface (cb, image, 0, 0);
	cairo_mask_surface(cb, test, 0, 0);

	cairo_paint(cb);

	cairo_destroy (cb);

//    cairo_set_source_rgb (ci, 0.5,0.5,0.5);
	cairo_paint(ci);

	cairo_set_source_surface (ci, test, mouse->x-(brush_w/2),mouse->y-(brush_h/2));
	cairo_paint(ci);
	*/	

   d_events * events;
   d_events::iterator it_events;
   events = d->GetEvents();
   MousePosition mouse;

	/*	mouse->x = 100;
	mouse->y = 100;
	mouse->prev_x = 250;
	mouse->prev_y = 100;*/

   //cairo_save (ci);

   //printf("size %d \n",events->size());

   for(it_events = events->begin(); it_events!= events->end(); it_events++){ 
      if(it_events->second.live ){

          mouse.x = (gint) (w*(1-it_events->second.x));
          mouse.y = (gint) (h*it_events->second.y);
          mouse.prev_x = (gint) (w*(1-it_events->second.last[1].x));
          mouse.prev_y = (gint) (h*(it_events->second.last[1].y));
          mouse.bold = it_events->second.size; 

         // printf("mouse: %d %d %d | ", mouse.x, mouse.y, mouse.bold);
          //printf("mouse: %d %d %d | ", mouse.prev_x, mouse.prev_y, mouse.bold);
          //printf("mouse: %f %f | %f %f \n", it_events->second.x, it_events->second.y, it_events->second.last[1].x, it_events->second.last[1].y);

        /*cairo_set_source_rgba (ci, 255,0,0, 1.);
        cairo_arc (ci, mouse.x,mouse.y, 20, 0, 2 * M_PI);
        cairo_fill_preserve (ci);
        cairo_stroke (ci);*/

        //printf("%f %f\n",mouse->f_x,mouse->f_y);
        //if(!(mouse->f_x>0 && mouse->f_y > 0)) return;

        //mouse->x = (int) (w-mouse->f_x*w);
        //mouse->y = (int) (mouse->f_y*h);
        //printf("(%d %d) %d %d < %f %f\n",w,h,mouse->x,mouse->y,mouse->f_x,mouse->f_y);

        /* proložení vykreslování */
        float test_t = sqrt(pow(mouse.x-mouse.prev_x,2) + pow(mouse.y-mouse.prev_y,2));

        int size_brush;
        //omezení pokud jsou velké skoky
        if(test_t==0 || test_t > 100) break;

        if(brush_type == 0 || brush_type==3){
            size_brush = (mouse.bold / 2) - 5;
            if(size_brush < 5) size_brush = 5;
            if(size_brush > 20) size_brush = 20;
            cairo_set_line_width (ci, 0.);
         } else {
            size_brush = mouse.bold / 10;
            if(size_brush > 5) size_brush = 5;
            if(size_brush < 1) size_brush = 1;
         }

        // printf("brush %d \n", size_brush); 

         int step = int (test_t/size_brush);
         int rate_rand = 10;
         //printf("%d %d\n",size_brush, mouse->bold);
         //délka jednoho tahu
         double step_x = (mouse.x - mouse.prev_x)/(double) step;
         double step_y = (mouse.y - mouse.prev_y)/(double) step;

         float aplha = 1.;

         if (brush_type == 3) aplha = 0.3;
      
         if(brush_type == 2) {
            aplha = 0.2;
//            size_brush = 5;
         }
        // printf("color: %f %f %f\n",color.r, color.g, color.b);
      
        /* proložení ploch */
       if(brush_type == 0){
        for(int i=0; i < step+1; i++){
            if(brush_type == 0){
                cairo_set_source_rgba (ci, color.r, color.g, color.b, 1.);
                cairo_arc (ci, mouse.prev_x+step_x*i,mouse.prev_y+step_y*i,  size_brush, 0, 2 * M_PI);
                cairo_fill_preserve (ci);
                cairo_stroke (ci);
            } else {
                cairo_set_source_rgba (ci, color.r, color.g, color.b, aplha);
                for(int j=0; j < 5; j++){
               //		printf("%f ",10*(drand48()*2.-1.));
                  cairo_arc (ci, (mouse.prev_x+step_x*i)+rate_rand*(drand48()*2.-1.), (mouse.prev_y+step_y*i)+rate_rand*(drand48()*2.-1.),  size_brush, 0, 2 * M_PI);
                  cairo_fill_preserve (ci);
                  cairo_stroke (ci);
               }
            }
        }
}
        //vykreslení plochy
       if(brush_type == 0){
          cairo_set_source_rgba (ci, color.r, color.g, color.b, 1.);
          cairo_arc (ci, mouse.x, mouse.y,  size_brush, 0, 2 * M_PI);
          cairo_fill_preserve (ci);
          cairo_stroke (ci);
       } else {
          cairo_set_source_rgba (ci, color.r, color.g, color.b, aplha);
          for(int j=0; j < 8; j++){
      //		printf("%f ",10*(drand48()*2.-1.));
            cairo_arc (ci, mouse.x+rate_rand*(drand48()*2.5-1.), mouse.y+rate_rand*(drand48()*2.5-1.),  ((int) size_brush), 0, 2 * M_PI);
            cairo_fill_preserve (ci);
            cairo_stroke (ci);
          }
       }
   }
}

   //	cairo_restore (ci);
   if(image!=NULL){
      int _w = cairo_image_surface_get_width (image);
      int _h = cairo_image_surface_get_height (image);
      //cairo_surface_t* test;
      //cairo_t *cb;
      //test = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, _w, _h );
       //printf("%d %d\n",_w,_h);
      //cb = cairo_create(test);
       cairo_scale  (ci, w/(double)_w, h/(double)_h);
       cairo_set_source_surface (ci, image, 0, 0);
       cairo_paint(ci);
   }
      cairo_restore (ci);


        timer[1] =  microtime() - t;
}
int main(int argc, char** argv) {

  int c;
  float col_r, col_g, col_b = -1.0f;
  Options opt;

  while ((c = getopt(argc, argv, "a:x:y:f:s:t:n:w:r:g:b:c:")) != -1) {
    switch(c) {

      /* color */
      /* ------------------------------------------------------- */
      case 'r': {
        col_r = convert_type<float>(optarg);
        break;
      }
      case 'g': {
        col_g = convert_type<float>(optarg);
        break;
      }
      case 'b': {
        col_b = convert_type<float>(optarg);
        break;
      }
      
      /* ------------------------------------------------------- */
      /* foreground */
      case 'c': {
        opt.foreground_file = convert_type<std::string>(optarg);
        break;
      }
      /* ------------------------------------------------------- */
      /* background */
      case 'x': {
        opt.background_x = convert_type<int>(optarg);
        break;
      }
      case 'y': {
        opt.background_y = convert_type<int>(optarg);
        break;
      }
      case 'f': {
        //printf("Got: %s", optarg);
        opt.background_file = convert_type<std::string>(optarg);
        break;
      }

      /* ------------------------------------------------------- */
      /* visible size */
      case 'a': {
        opt.visible_size = convert_type<float>(optarg);
        break;
      }

      /* ------------------------------------------------------- */
      /* name */
      case 'n': {
        opt.name = convert_type<std::string>(optarg);

        /* we expect that r,g,b has been set */
        if (0 > col_r) {
          printf("Error: you haven't set -r -g -b for the name.\n");
          exit(EXIT_FAILURE);
        }
        opt.name_r = col_r;
        opt.name_g = col_g;
        opt.name_b = col_b;
        break;
      }
      /* name x position */
      case 's': {
        opt.name_x = convert_type<int>(optarg);
        break;
      }
      /* name y position */
      case 't': {
        opt.name_y = convert_type<int>(optarg);
        break;
      }
      /* name font size */
      case 'w': {
        opt.name_font_size = convert_type<float>(optarg);
        break;
      }
      default: {
        printf("Unkown option\n");
        break;
      }
    }
  }
  
  if (false == opt.validate()) {
    printf("+ error: cannot validate the given options.\n");
    exit(EXIT_FAILURE);
  }

  opt.print();

  /* ------------------------------------------------------------------------------------ */

  Image img;
  std::string path;
  std::string ext;
  cairo_surface_t* surf_bg = NULL;
  cairo_format_t img_format = CAIRO_FORMAT_INVALID;

  path = opt.foreground_file;
  if (false == rx_file_exists(path)) {
    printf("+ error: cannot find the file: %s\n", path.c_str());
    exit(EXIT_FAILURE);
  }

  cairo_surface_t* surf_overlay = cairo_image_surface_create_from_png(path.c_str());
  if (NULL == surf_overlay) {
    printf("Error: cannot create s1\n");
    exit(EXIT_FAILURE);
  }

  path = opt.background_file;
  if (false == rx_file_exists(path)) {
    printf("Error: file doesn't exist: %s\n", path.c_str());
    exit(EXIT_FAILURE);
  }
  
  /* check what file type was given. */
  ext = rx_get_file_ext(path);
  if (ext == "jpg") {

    printf("+ warning: jpg as input doesn't seem to work\n");

    /* cairo doesn't have support for PNG? */
    if (0 > rx_load_jpg(path, &img.pixels, img.width, img.height, img.channels)) {
      printf("Error: failed to load: %s\n", path.c_str());
      exit(EXIT_FAILURE);
    }
    if (0 == img.width || 0 == img.height || 0 == img.channels) {
      printf("Error: image has invalid flags: %d x %d, channels: %d\n", img.width, img.height, img.channels);
      exit(EXIT_FAILURE);
    }

    if (3 == img.channels) {
      img_format = CAIRO_FORMAT_RGB24;
      printf("+ Using RGB24\n");
    }  
    else if(4 == img.channels) {
      img_format = CAIRO_FORMAT_ARGB32;
      printf("+ Using ARGB32\n");
    }
    else {
      printf("Error: unsupported number of channels: %d.\n", img.channels);
      exit(EXIT_FAILURE);
    }

    if (NULL != img.pixels && NULL == surf_bg) {

        printf("Stride: %d\n", cairo_format_stride_for_width(img_format, img.width));
        printf("Info: creating %d x %d, channels: %d\n", img.width, img.height, img.channels);

        surf_bg = cairo_image_surface_create_for_data(img.pixels, 
                                                      img_format, 
                                                      img.width, 
                                                      img.height, 
                                                      cairo_format_stride_for_width(img_format, img.width));

#if 0
      /* TESTING */
      cairo_t* cr = cairo_create(surf_bg);
      if (NULL == cr) { 
        printf("Error: cannot create the cairo");
        exit(EXIT_FAILURE);
      }
      path = rx_get_exe_path() +"/generated_polaroid.png";
      cairo_surface_write_to_png(surf_bg, path.c_str());
      printf("Created\n");
      exit(0);
      /* END TESTING */
#endif
    }
  }
  else if (ext == "png") {

    /* use cairo png load feature. */
    surf_bg = cairo_image_surface_create_from_png(path.c_str());
    if (NULL == surf_bg) {
      printf("Error: cannot create s2\n");
      exit(EXIT_FAILURE);
    }

  }
  else {
    printf("Error: unsupported file format: %s\n", ext.c_str());
    exit(EXIT_FAILURE);
  }


  /* make sure the background is loaded correctly (aka the photo) */
  if (NULL == surf_bg) {
    printf("Error: cannot create background surface.\n");
    exit(EXIT_FAILURE);
  }

  if (CAIRO_STATUS_SUCCESS != cairo_surface_status(surf_bg)) {
    printf("Error: something went wrong: %d\n", cairo_surface_status(surf_bg));
    exit(EXIT_FAILURE);
  }

  float source_width = cairo_image_surface_get_width(surf_bg);
  float source_height = cairo_image_surface_get_height(surf_bg);

  /* create output */
  int dest_width = cairo_image_surface_get_width(surf_overlay);
  int dest_height = cairo_image_surface_get_height(surf_overlay);

  printf("+ Output size: %d x %d\n", dest_width, dest_height);

  cairo_surface_t* surf_out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dest_width, dest_height);
  if (NULL == surf_out) {
    printf("Error: cannot create cairo_surface_t\n");
    exit(EXIT_FAILURE);
  }

  printf("+ Info: creating output surface: %d x %d\n", dest_width, dest_height);

  cairo_t* cr = cairo_create(surf_out);
  if (NULL == cr) { 
    printf("Error: cannot create the cairo");
    exit(EXIT_FAILURE);
  }


  /* fill background. */
  cairo_set_source_rgba(cr, 1, 1, 1, 1);
  cairo_paint(cr);

  float scale_factor = opt.visible_size / source_width;
  printf("+ Scale factor: %f\n", scale_factor);

  /* paint background */  
  cairo_save(cr);
  cairo_scale(cr, scale_factor, scale_factor);
  cairo_set_source_surface(cr, surf_bg, opt.background_x, opt.background_y);
  cairo_rectangle(cr, 0, 0, img.width, img.height);
  cairo_paint(cr);
  cairo_restore(cr);

  /* paint overlay */
  cairo_set_source_surface(cr, surf_overlay, 0, 0);
  cairo_paint(cr);
  cairo_surface_flush(surf_out);

  /* font */
  cairo_select_font_face(cr, "Open Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_source_rgba(cr, opt.name_r, opt.name_g, opt.name_b, 1.0); 
  cairo_move_to(cr, opt.name_x, opt.name_y);
  cairo_set_font_size(cr, opt.name_font_size);
  cairo_show_text(cr, opt.name.c_str());

  cairo_stroke(cr);
  cairo_fill(cr);
  cairo_surface_flush(surf_out);

  /* write out */
  path = rx_get_exe_path() +"/generated_polaroid.png";
  cairo_surface_write_to_png(surf_out, path.c_str());

  /* cleanup */
  cairo_surface_destroy(surf_out);
  cairo_surface_destroy(surf_bg);
  cairo_surface_destroy(surf_overlay);
  cairo_destroy(cr);

  printf("\n");
  return 0;
}
Beispiel #26
0
static cairo_status_t
png_diff (const char *filename_a,
	  const char *filename_b,
	  const char *filename_diff,
	  int		ax,
	  int		ay,
	  int		bx,
	  int		by,
	  buffer_diff_result_t *result)
{
    cairo_surface_t *surface_a;
    cairo_surface_t *surface_b;
    cairo_surface_t *surface_diff;
    cairo_status_t status;

    surface_a = cairo_image_surface_create_from_png (filename_a);
    status = cairo_surface_status (surface_a);
    if (status) {
	fprintf (stderr, "Error: Failed to create surface from %s: %s\n",
		 filename_a, cairo_status_to_string (status));
	return status;
    }

    surface_b = cairo_image_surface_create_from_png (filename_b);
    status = cairo_surface_status (surface_b);
    if (status) {
	fprintf (stderr, "Error: Failed to create surface from %s: %s\n",
		 filename_b, cairo_status_to_string (status));
	cairo_surface_destroy (surface_a);
	return status;
    }

    if (ax || ay) {
	extract_sub_surface (&surface_a, ax, ay);
	ax = ay = 0;
    }

    if (bx || by) {
	extract_sub_surface (&surface_b, bx, by);
	bx = by = 0;
    }

    status = cairo_surface_status (surface_a);
    if (status) {
	fprintf (stderr, "Error: Failed to extract surface from %s: %s\n",
		 filename_a, cairo_status_to_string (status));
	cairo_surface_destroy (surface_a);
	cairo_surface_destroy (surface_b);
	return status;
    }
    status = cairo_surface_status (surface_b);
    if (status) {
	fprintf (stderr, "Error: Failed to extract surface from %s: %s\n",
		 filename_b, cairo_status_to_string (status));
	cairo_surface_destroy (surface_a);
	cairo_surface_destroy (surface_b);
	return status;
    }

    surface_diff = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
					       cairo_image_surface_get_width (surface_a),
					       cairo_image_surface_get_height (surface_a));
    status = cairo_surface_status (surface_diff);
    if (status) {
	fprintf (stderr,
		 "Error: Failed to allocate surface to hold differences\n");
	cairo_surface_destroy (surface_a);
	cairo_surface_destroy (surface_b);
	return CAIRO_STATUS_NO_MEMORY;
    }

    status = image_diff (NULL,
			 surface_a, surface_b, surface_diff,
			 result);

    cairo_surface_destroy (surface_a);
    cairo_surface_destroy (surface_b);
    cairo_surface_destroy (surface_diff);

    _xunlink (filename_diff);
    if (status == CAIRO_STATUS_SUCCESS &&
	result->pixels_changed)
    {
	status = write_png (surface_diff, filename_diff);
    }


    return status;
}
static gpointer
grayscale_exec (GthAsyncTask *task,
	        gpointer      user_data)
{
	GrayscaleData   *grayscale_data = user_data;
	cairo_surface_t *source;
	cairo_format_t   format;
	int              width;
	int              height;
	int              source_stride;
	cairo_surface_t *destination;
	int              destination_stride;
	unsigned char   *p_source_line;
	unsigned char   *p_destination_line;
	unsigned char   *p_source;
	unsigned char   *p_destination;
	gboolean         cancelled;
	double           progress;
	int              x, y;
	unsigned char    red, green, blue, alpha;
	unsigned char    min, max, value;

	source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task));
	format = cairo_image_surface_get_format (source);
	width = cairo_image_surface_get_width (source);
	height = cairo_image_surface_get_height (source);
	source_stride = cairo_image_surface_get_stride (source);

	destination = cairo_image_surface_create (format, width, height);
	destination_stride = cairo_image_surface_get_stride (destination);
	p_source_line = _cairo_image_surface_flush_and_get_data (source);
	p_destination_line = _cairo_image_surface_flush_and_get_data (destination);
	for (y = 0; y < height; y++) {
		gth_async_task_get_data (task, NULL, &cancelled, NULL);
		if (cancelled)
			return NULL;

		progress = (double) y / height;
		gth_async_task_set_data (task, NULL, NULL, &progress);

		p_source = p_source_line;
		p_destination = p_destination_line;
		for (x = 0; x < width; x++) {
			CAIRO_GET_RGBA (p_source, red, green, blue, alpha);

			switch (grayscale_data->method) {
			case METHOD_BRIGHTNESS:
				value = (0.2125 * red + 0.7154 * green + 0.072 * blue);
				break;

			case METHOD_SATURATION:
				max = MAX (MAX (red, green), blue);
				min = MIN (MIN (red, green), blue);
				value = (max + min) / 2;
				break;

			case METHOD_AVARAGE:
				value = (0.3333 * red + 0.3333 * green + 0.3333 * blue);
				break;

			default:
				g_assert_not_reached ();
			}

			CAIRO_SET_RGBA (p_destination,
					value,
					value,
					value,
					alpha);

			p_source += 4;
			p_destination += 4;
		}
		p_source_line += source_stride;
		p_destination_line += destination_stride;
	}

	cairo_surface_mark_dirty (destination);
	gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination);

	cairo_surface_destroy (destination);
	cairo_surface_destroy (source);

	return NULL;
}
BufferData *
_create_buffer_similar (BufferData *buffer)
{
  return _create_buffer (cairo_image_surface_get_width (buffer->surface),
                         cairo_image_surface_get_height (buffer->surface));
}
Beispiel #29
0
static const char *
write_ppm (cairo_surface_t *surface, int fd)
{
    char buf[4096];
    cairo_format_t format;
    const char *format_str;
    const unsigned char *data;
    int len;
    int width, height, stride;
    int i, j;

    data = cairo_image_surface_get_data (surface);
    height = cairo_image_surface_get_height (surface);
    width = cairo_image_surface_get_width (surface);
    stride = cairo_image_surface_get_stride (surface);
    format = cairo_image_surface_get_format (surface);
    if (format == CAIRO_FORMAT_ARGB32) {
	/* see if we can convert to a standard ppm type and trim a few bytes */
	const unsigned char *alpha = data;
	for (j = height; j--; alpha += stride) {
	    for (i = 0; i < width; i++) {
		if ((*(unsigned int *) (alpha+4*i) & 0xff000000) != 0xff000000)
		    goto done;
	    }
	}
	format = CAIRO_FORMAT_RGB24;
 done: ;
    }

    switch (format) {
    case CAIRO_FORMAT_ARGB32:
	/* XXX need true alpha for svg */
	format_str = "P7";
	break;
    case CAIRO_FORMAT_RGB24:
	format_str = "P6";
	break;
    case CAIRO_FORMAT_A8:
	format_str = "P5";
	break;
    case CAIRO_FORMAT_A1:
    case CAIRO_FORMAT_RGB16_565:
    case CAIRO_FORMAT_RGB30:
    case CAIRO_FORMAT_INVALID:
    default:
	return "unhandled image format";
    }

    len = sprintf (buf, "%s %d %d 255\n", format_str, width, height);
    for (j = 0; j < height; j++) {
	const unsigned int *row = (unsigned int *) (data + stride * j);

	switch ((int) format) {
	case CAIRO_FORMAT_ARGB32:
	    len = _cairo_write (fd,
			  buf, sizeof (buf), len,
			  (unsigned char *) row, 4 * width);
	    break;
	case CAIRO_FORMAT_RGB24:
	    for (i = 0; i < width; i++) {
		unsigned char rgb[3];
		unsigned int p = *row++;
		rgb[0] = (p & 0xff0000) >> 16;
		rgb[1] = (p & 0x00ff00) >> 8;
		rgb[2] = (p & 0x0000ff) >> 0;
		len = _cairo_write (fd,
			      buf, sizeof (buf), len,
			      rgb, 3);
	    }
	    break;
	case CAIRO_FORMAT_A8:
	    len = _cairo_write (fd,
			  buf, sizeof (buf), len,
			  (unsigned char *) row, width);
	    break;
	}
	if (len < 0)
	    return "write failed";
    }

    if (len && ! _cairo_writen (fd, buf, len))
	return "write failed";

    return NULL;
}
static VALUE
cr_image_surface_get_height (VALUE self)
{
  return INT2NUM (cairo_image_surface_get_height (_SELF));
}