Beispiel #1
0
void
wnck_draw_workspace (GtkWidget                   *widget,
                     #if GTK_CHECK_VERSION(3, 0, 0)
                     cairo_t                     *cr,
                     #else
                     GdkDrawable                 *drawable,
                     #endif
                     int                          x,
                     int                          y,
                     int                          width,
                     int                          height,
                     int                          screen_width,
                     int                          screen_height,
                     GdkPixbuf                   *workspace_background,
                     gboolean                     is_active,
                     const WnckWindowDisplayInfo *windows,
                     int                          n_windows)
{
  int i;
  GdkRectangle workspace_rect;
  GtkStateType state;
  #if !GTK_CHECK_VERSION(3, 0, 0)
  cairo_t *cr;
  #endif

  workspace_rect.x = x;
  workspace_rect.y = y;
  workspace_rect.width = width;
  workspace_rect.height = height;

  if (is_active)
    state = GTK_STATE_SELECTED;
  else if (workspace_background)
    state = GTK_STATE_PRELIGHT;
  else
    state = GTK_STATE_NORMAL;

  #if GTK_CHECK_VERSION(3, 0, 0)
  cairo_save(cr);
  #else
  cr = gdk_cairo_create (drawable);
  #endif

  if (workspace_background)
    {
      gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y);
      cairo_paint (cr);
    }
  else
    {
      gdk_cairo_set_source_color (cr, &gtk_widget_get_style (widget)->dark[state]);
      cairo_rectangle (cr, x, y, width, height);
      cairo_fill (cr);
    }

  #if !GTK_CHECK_VERSION(3, 0, 0)
  cairo_destroy (cr);
  #endif

  i = 0;
  while (i < n_windows)
    {
      const WnckWindowDisplayInfo *win = &windows[i];
      GdkRectangle winrect;

      get_window_rect (win, screen_width,
                       screen_height, &workspace_rect, &winrect);

      draw_window (widget,
                   #if GTK_CHECK_VERSION(3, 0, 0)
                   cr,
                   #else
                   drawable,
                   #endif
                   win,
                   &winrect,
                   state);

      ++i;
    }

  #if GTK_CHECK_VERSION(3, 0, 0)
  cairo_restore(cr);
  #endif
}
void cd_switcher_draw_main_icon_compact_mode (void)
{
	if (myData.switcher.iNbColumns == 0 || myData.switcher.iNbLines == 0)  // may happen in desklet mode with a cube desktop, when the desklet is still 0x0.
		return;
	CD_APPLET_START_DRAWING_MY_ICON_OR_RETURN_CAIRO ();
	///g_return_if_fail (myDrawContext != NULL);
	//g_print ("%s (%d;%d)\n", __func__, myData.switcher.iCurrentLine, myData.switcher.iCurrentColumn);
	// On efface l'icone.
	///cairo_dock_erase_cairo_context (myDrawContext);
	
	// definition des parametres de dessin.
	int iWidth, iHeight;
	CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
	
	myData.switcher.fOneViewportHeight = (double) (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
	myData.switcher.fOneViewportWidth = (double) (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
	double dx=0, dy=0;
	double w = iWidth, h = iHeight;
	if (myConfig.bPreserveScreenRatio)
	{
		double r = (double) g_desktopGeometry.Xscreen.width / g_desktopGeometry.Xscreen.height;
		double r_ = myData.switcher.fOneViewportWidth / myData.switcher.fOneViewportHeight;
		if (r_ > r)  // on etire trop en largeur.
		{
			myData.switcher.fOneViewportWidth /= r_ / r;
			w = myData.switcher.fOneViewportWidth * myData.switcher.iNbColumns + 2 * myConfig.iLineSize + (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize;
			dx = (double) (iWidth - w) / 2;
		}
		else
		{
			myData.switcher.fOneViewportHeight /= r / r_;
			h = myData.switcher.fOneViewportHeight * myData.switcher.iNbLines + 2 * myConfig.iLineSize + (myData.switcher.iNbLines - 1) * myConfig.iInLineSize;
			dy = (iHeight - h) / 2;
		}
	}
	myData.switcher.fOffsetX = dx;
	myData.switcher.fOffsetY = dy;
	
	cairo_save (myDrawContext);
	cairo_translate (myDrawContext, dx, dy);
	
	cairo_surface_t *pSurface = NULL;
	double fZoomX, fZoomY;
	if (myConfig.iIconDrawing == SWICTHER_MAP_WALLPAPER)
	{
		pSurface = myData.pDesktopBgMapSurface;
	}
	if (pSurface == NULL)
	{
		pSurface = myData.pDefaultMapSurface;
	}
	fZoomX = (double) myData.switcher.fOneViewportWidth / myData.iSurfaceWidth;  // both surfaces are loaded at the same size.
	fZoomY= (double) myData.switcher.fOneViewportHeight / myData.iSurfaceHeight;
	
	// cadre exterieur.
	cairo_set_line_width (myDrawContext,myConfig.iLineSize);
	if (myConfig.bUseDefaultColors)
		gldi_style_colors_set_line_color (myDrawContext);
	else
		cairo_set_source_rgba(myDrawContext,myConfig.RGBLineColors[0],myConfig.RGBLineColors[1],myConfig.RGBLineColors[2],myConfig.RGBLineColors[3]);
	cairo_rectangle(myDrawContext,
		.5*myConfig.iLineSize,
		.5*myConfig.iLineSize,
		w - myConfig.iLineSize,
		h - myConfig.iLineSize);

	cairo_stroke (myDrawContext);
	
	// lignes interieures.
	cairo_set_line_width (myDrawContext,myConfig.iInLineSize);
	if (myConfig.bUseDefaultColors)
		gldi_style_colors_set_line_color (myDrawContext);
	else
		cairo_set_source_rgba (myDrawContext,myConfig.RGBInLineColors[0],myConfig.RGBInLineColors[1],myConfig.RGBInLineColors[2],myConfig.RGBInLineColors[3]);
	double xi, yj;
	int i, j;
	for (i = 1; i < myData.switcher.iNbColumns; i ++)  // lignes verticales.
	{
		xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
		cairo_move_to (myDrawContext, xi, myConfig.iLineSize);
		cairo_rel_line_to (myDrawContext, 0, h - 2*myConfig.iLineSize);
		cairo_stroke (myDrawContext);
	}
	for (j = 1; j < myData.switcher.iNbLines; j ++)  // lignes horizontales.
	{
		yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
		cairo_move_to (myDrawContext, myConfig.iLineSize, yj);
		cairo_rel_line_to (myDrawContext, w - 2*myConfig.iLineSize, 0);
		cairo_stroke (myDrawContext);
	}
	
	GList *pWindowList = NULL;
	if (myConfig.bDrawWindows)
	{
		pWindowList = cairo_dock_get_current_applis_list ();
		pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
	}
	
	// chaque bureau/viewport.
	int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
	int k = 0, N = g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY;
	for (j = 0; j < myData.switcher.iNbLines && k < N; j ++)
	{
		for (i = 0; i < myData.switcher.iNbColumns && k < N; i ++)
		{
			cairo_save (myDrawContext);

			xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
			yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);

			cairo_translate (myDrawContext,
				xi,
				yj);

			cairo_scale (myDrawContext,
				fZoomX,
				fZoomY);
			cairo_set_source_surface (myDrawContext,
				pSurface,
				0.,
				0.);
			cairo_paint(myDrawContext);
			
			cairo_restore (myDrawContext);
			
			if ((myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL_INVERTED && (i != myData.switcher.iCurrentColumn || j != myData.switcher.iCurrentLine))
			|| (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL && (i == myData.switcher.iCurrentColumn && j == myData.switcher.iCurrentLine)))
			{
				cairo_save (myDrawContext);
				
				if (myConfig.bUseDefaultColors)
					gldi_style_colors_set_selected_bg_color (myDrawContext);
				else
					cairo_set_source_rgba (myDrawContext, myConfig.RGBIndColors[0], myConfig.RGBIndColors[1], myConfig.RGBIndColors[2], myConfig.RGBIndColors[3]);
				cairo_rectangle(myDrawContext,
					xi - .5*myConfig.iLineSize,
					yj - .5*myConfig.iLineSize,
					myData.switcher.fOneViewportWidth + myConfig.iLineSize,
					myData.switcher.fOneViewportHeight + myConfig.iLineSize);
				cairo_fill (myDrawContext);
				
				cairo_restore (myDrawContext);
			}
			
			if (myConfig.bDrawWindows)
			{
				cairo_save (myDrawContext);
				
				cairo_translate (myDrawContext,
					xi,
					yj);
				cairo_set_line_width (myDrawContext, 1.);
				cairo_rectangle (myDrawContext,
					0.,
					0.,
					myData.switcher.fOneViewportWidth,
					myData.switcher.fOneViewportHeight);
				cairo_clip (myDrawContext);
				
				//g_print (" dessin des fenetres du bureau (%d;%d;%d) ...\n", iNumDesktop, iNumViewportX, iNumViewportY);
				CDSwitcherDesktop data = {iNumDesktop, iNumViewportX, iNumViewportY, (int) myData.switcher.fOneViewportWidth, (int) myData.switcher.fOneViewportHeight, myDrawContext};
				g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, &data);
				
				cairo_restore (myDrawContext);
			}
			
			iNumViewportX ++;
			if (iNumViewportX == g_desktopGeometry.iNbViewportX)
			{
				iNumViewportX = 0;
				iNumViewportY ++;
				if (iNumViewportY == g_desktopGeometry.iNbViewportY)
				{
					iNumViewportY = 0;
					iNumDesktop ++;
				}
			}
			k ++;
		}
	}
	
	// dessin de l'indicateur sur le bureau courant (on le fait maintenant car dans le cas ou la ligne interieure est plus petite que la ligne de l'indicateur, les surfaces suivantes recouvreraient en partie la ligne.
	if (myConfig.iDrawCurrentDesktopMode == SWICTHER_DRAW_FRAME)
	{
		i = myData.switcher.iCurrentColumn;
		j = myData.switcher.iCurrentLine;
		xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
		yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
		
		cairo_set_line_width (myDrawContext,myConfig.iLineSize);
		if (myConfig.bUseDefaultColors)
			gldi_style_colors_set_selected_bg_color (myDrawContext);
		else
			cairo_set_source_rgba (myDrawContext,myConfig.RGBIndColors[0],myConfig.RGBIndColors[1],myConfig.RGBIndColors[2],myConfig.RGBIndColors[3]);
		cairo_rectangle(myDrawContext,
			xi - .5*myConfig.iLineSize,
			yj - .5*myConfig.iLineSize,
			myData.switcher.fOneViewportWidth + myConfig.iLineSize,
			myData.switcher.fOneViewportHeight + myConfig.iLineSize);
		
		if (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL)
			cairo_fill (myDrawContext);  // maybe we need to fill it with an alpha pattern in case we use the global style color ?...
		else
		{
			cairo_set_line_width (myDrawContext, MIN (4, 2*myConfig.iLineSize));
			cairo_stroke(myDrawContext);
		}
	}
	
	cairo_restore (myDrawContext);
	g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
	
	CD_APPLET_FINISH_DRAWING_MY_ICON_CAIRO;
}
static void _cd_switcher_draw_windows_on_viewport (Icon *pIcon, CDSwitcherDesktop *data)
{
	if (pIcon == NULL || pIcon->fInsertRemoveFactor > 0)
		return ;
	GldiWindowActor *actor = pIcon->pAppli;
	if (actor->bIsHidden && ! myConfig.bDisplayHiddenWindows)
		return ;
	int iNumDesktop = data->iNumDesktop;
	int iNumViewportX = data->iNumViewportX;
	int iNumViewportY = data->iNumViewportY;
	int iOneViewportWidth = data->iOneViewportWidth;
	int iOneViewportHeight = data->iOneViewportHeight;
	cairo_t *pCairoContext = data->pCairoContext;
	
	// On calcule les coordonnees en repere absolu.
	int x = actor->windowGeometry.x;  // par rapport au viewport courant.
	x += myData.switcher.iCurrentViewportX * g_desktopGeometry.Xscreen.width;  // repere absolu
	if (x < 0)
		x += g_desktopGeometry.iNbViewportX * g_desktopGeometry.Xscreen.width;
	int y = actor->windowGeometry.y;
	y += myData.switcher.iCurrentViewportY * g_desktopGeometry.Xscreen.height;
	if (y < 0)
		y += g_desktopGeometry.iNbViewportY * g_desktopGeometry.Xscreen.height;
	int w = actor->windowGeometry.width, h = actor->windowGeometry.height;
	
	// test d'intersection avec le viewport donne.
	//g_print (" %s : (%d;%d) %dx%d\n", pIcon->cName, x, y, w, h);
	if ((actor->iNumDesktop != -1 && actor->iNumDesktop != iNumDesktop) ||
		x + w <= iNumViewportX * g_desktopGeometry.Xscreen.width ||
		x >= (iNumViewportX + 1) * g_desktopGeometry.Xscreen.width ||
		y + h <= iNumViewportY * g_desktopGeometry.Xscreen.height ||
		y >= (iNumViewportY + 1) * g_desktopGeometry.Xscreen.height)
		return ;
	
	// on dessine ses traits.
	cairo_save (pCairoContext);

	GldiWindowActor *pActiveWindow = gldi_windows_get_active ();
	
	if (myConfig.bFillAllWindows && actor != pActiveWindow)
		cairo_set_source_rgba (pCairoContext, myConfig.RGBWFillColors[0], myConfig.RGBWFillColors[1], myConfig.RGBWFillColors[2], myConfig.RGBWFillColors[3]);
	else
	{
		if (myConfig.bUseDefaultColors)
			gldi_style_colors_set_line_color (myDrawContext);
		else
			cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
	}
	cairo_rectangle (pCairoContext,
		(1.*x/g_desktopGeometry.Xscreen.width - iNumViewportX)*iOneViewportWidth,
		(1.*y/g_desktopGeometry.Xscreen.height - iNumViewportY)*iOneViewportHeight,
		1.*w/g_desktopGeometry.Xscreen.width*iOneViewportWidth,
		1.*h/g_desktopGeometry.Xscreen.height*iOneViewportHeight);

	if (myConfig.bFillAllWindows || actor == pActiveWindow)
	{
		//g_print (" %s est la fenetre active\n", pIcon->cName);
		cairo_fill (pCairoContext);
	}
	else
	{
		cairo_stroke (pCairoContext);
	}
	
	if (myConfig.bDrawIcons)
	{
		const CairoDockImageBuffer *pImage = gldi_appli_icon_get_image_buffer (pIcon);
		if (pImage && pImage->pSurface)
		{
			double fZoomX = (double) w/g_desktopGeometry.Xscreen.width*iOneViewportWidth / pImage->iWidth;
			double fZoomY = (double) h/g_desktopGeometry.Xscreen.height*iOneViewportHeight / pImage->iHeight;
			double fZoom = MIN (fZoomX, fZoomY);  // on garde le ratio.
			
			cairo_translate (pCairoContext,
				(1.*x/g_desktopGeometry.Xscreen.width - iNumViewportX)*iOneViewportWidth + (fZoomX - fZoom) * pImage->iWidth/2,
				(1.*y/g_desktopGeometry.Xscreen.height - iNumViewportY)*iOneViewportHeight + (fZoomY - fZoom) * pImage->iHeight/2);
			cairo_scale (pCairoContext,
				fZoom,
				fZoom);
			cairo_set_source_surface (pCairoContext,
				pImage->pSurface,
				0.,
				0.);
			cairo_paint (pCairoContext);
		}
	}
	
	cairo_restore (pCairoContext);
}
void
html_engine_draw_cursor_in_area (HTMLEngine *engine,
                                 gint x,
                                 gint y,
                                 gint width,
                                 gint height)
{
	HTMLObject *obj;
	guint offset;
	gint x1, y1, x2, y2, sc_x, sc_y;
	GdkRectangle pos;
	GtkAdjustment *hadj, *vadj;

	if ((engine->editable || engine->caret_mode) && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) {
		html_engine_draw_table_cursor (engine);
		html_engine_draw_cell_cursor (engine);
		html_engine_draw_image_cursor (engine);
	}

	if (!cursor_enabled || engine->cursor_hide_count > 0 || !(engine->editable || engine->caret_mode) || engine->thaw_idle_id)
		return;

	obj = engine->cursor->object;
	if (obj == NULL || engine->window == NULL)
		return;

	offset = engine->cursor->offset;

	if (width < 0 || height < 0) {
		width = html_engine_get_doc_width (engine);
		height = html_engine_get_doc_height (engine);
		x = 0;
		y = 0;
	}

	html_object_get_cursor (obj, engine->painter, offset, &x1, &y1, &x2, &y2);
	while (obj) {
		if (html_object_is_frame (obj)) {
			x1 -= HTML_EMBEDDED (obj)->abs_x;
			x2 -= HTML_EMBEDDED (obj)->abs_x;
			y1 -= HTML_EMBEDDED (obj)->abs_y;
			y2 -= HTML_EMBEDDED (obj)->abs_y;
			break;
		}
		obj = obj->parent;
	}

	/* get scroll offset */
	hadj = gtk_layout_get_hadjustment (GTK_LAYOUT (engine->widget));
	vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (engine->widget));
	sc_x = (gint) gtk_adjustment_get_value (hadj);
	sc_y = (gint) gtk_adjustment_get_value (vadj);

	pos.x = x1 - sc_x;
	pos.y = y1 - sc_y;
	pos.width = x2 - x1;
	pos.height = y2 - y1;

	gtk_im_context_set_cursor_location (GTK_HTML (engine->widget)->priv->im_context, &pos);

	if (clip_cursor (engine, x, y, width, height, &x1, &y1, &x2, &y2)) {
		cairo_t *cr;
		gboolean using_painter_cr;

		using_painter_cr = engine->painter &&
		    HTML_IS_GDK_PAINTER (engine->painter) &&
		    HTML_GDK_PAINTER (engine->painter)->cr != NULL;

		if (using_painter_cr) {
			HTMLGdkPainter *gdk_painter = HTML_GDK_PAINTER (engine->painter);

			cr = gdk_painter->cr;
			cairo_save (cr);

			x1 -= gdk_painter->x1;
			y1 -= gdk_painter->y1;
			x2 -= gdk_painter->x1;
			y2 -= gdk_painter->y1;
		} else {
			cr = gdk_cairo_create (engine->window);
		}

		cairo_set_source_rgb (cr, 1, 1, 1);
		cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
		cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
		cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
		cairo_line_to (cr, x2 + 0.5, y2 - 0.5);
		cairo_set_line_width (cr, 1);
		cairo_stroke (cr);

		if (using_painter_cr)
			cairo_restore (cr);
		else
			cairo_destroy (cr);
	}
}
/* TODO: Split each ppi case out to its own CAIRO_TEST() test case */
static cairo_test_status_t
preamble (cairo_test_context_t *ctx)
{
    cairo_t *cr;
    cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
    struct {
	double x, y;
    } ppi[] = {
	{ 576, 576 },
	{ 576, 72 },

	{ 288, 288 },
	{ 288, 72 },

	{ 144, 144 },
	{ 144, 72 },

	{ 72, 576 },
	{ 72, 288 },
	{ 72, 144 },
	{ 72, 72 },
    };
    unsigned int i;
    int n, num_ppi;
    const char *path = cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";

    num_ppi = ARRAY_LENGTH (ppi);

#if GENERATE_REFERENCE
    for (n = 0; n < num_ppi; n++) {
	char *ref_name;
	xasprintf (&ref_name, "reference/fallback-resolution.ppi%gx%g.ref.png",
		   ppi[n].x, ppi[n].y);
	generate_reference (ppi[n].x, ppi[n].y, ref_name);
	free (ref_name);
    }
#endif

    for (i = 0; i < ctx->num_targets; i++) {
	const cairo_boilerplate_target_t *target = ctx->targets_to_test[i];
	cairo_surface_t *surface = NULL;
	char *base_name;
	void *closure;
	const char *format;
	cairo_status_t status;

	if (! target->is_vector)
	    continue;

	if (! cairo_test_is_target_enabled (ctx, target->name))
	    continue;

	format = cairo_boilerplate_content_name (target->content);
	xasprintf (&base_name, "%s/fallback-resolution.%s.%s",
		   path, target->name,
		   format);

	surface = (target->create_surface) (base_name,
					    target->content,
					    SIZE, SIZE,
					    SIZE, SIZE,
					    CAIRO_BOILERPLATE_MODE_TEST,
					    &closure);

	if (surface == NULL) {
	    free (base_name);
	    continue;
	}

	if (ret == CAIRO_TEST_UNTESTED)
	    ret = CAIRO_TEST_SUCCESS;

	cairo_surface_destroy (surface);
	if (target->cleanup)
	    target->cleanup (closure);
	free (base_name);

	/* we need to recreate the surface for each resolution as we include
	 * SVG in testing which does not support the paginated interface.
	 */
	for (n = 0; n < num_ppi; n++) {
	    char *test_name;
	    cairo_bool_t pass;

	    xasprintf (&test_name, "fallback-resolution.ppi%gx%g",
		       ppi[n].x, ppi[n].y);
	    xasprintf (&base_name, "%s/%s.%s.%s",
		       path, test_name,
		       target->name,
		       format);

	    surface = (target->create_surface) (base_name,
						target->content,
						SIZE + 25, SIZE + 25,
						SIZE + 25, SIZE + 25,
						CAIRO_BOILERPLATE_MODE_TEST,
						&closure);
	    if (surface == NULL || cairo_surface_status (surface)) {
		cairo_test_log (ctx, "Failed to generate surface: %s.%s\n",
				target->name,
				format);
		free (base_name);
		free (test_name);
		ret = CAIRO_TEST_FAILURE;
		continue;
	    }

	    cairo_test_log (ctx,
			    "Testing fallback-resolution %gx%g with %s target\n",
			    ppi[n].x, ppi[n].y, target->name);
	    printf ("%s:\t", base_name);
	    fflush (stdout);

	    if (target->force_fallbacks != NULL)
		target->force_fallbacks (surface, ppi[n].x, ppi[n].y);
	    cr = cairo_create (surface);
#if SET_TOLERANCE
	    cairo_set_tolerance (cr, 3.0);
#endif

	    cairo_surface_set_device_offset (surface, 25, 25);

	    cairo_save (cr); {
		cairo_set_source_rgb (cr, 1, 1, 1);
		cairo_paint (cr);
	    } cairo_restore (cr);

	    /* First draw the top half in a conventional way. */
	    cairo_save (cr); {
		cairo_rectangle (cr, 0, 0, SIZE, SIZE / 2.0);
		cairo_clip (cr);

		draw (cr, SIZE, SIZE);
	    } cairo_restore (cr);

	    /* Then draw the bottom half in a separate group,
	     * (exposing a bug in 1.6.4 with the group not being
	     * rendered with the correct fallback resolution). */
	    cairo_save (cr); {
		cairo_rectangle (cr, 0, SIZE / 2.0, SIZE, SIZE / 2.0);
		cairo_clip (cr);

		cairo_push_group (cr); {
		    draw (cr, SIZE, SIZE);
		} cairo_pop_group_to_source (cr);

		cairo_paint (cr);
	    } cairo_restore (cr);

	    status = cairo_status (cr);
	    cairo_destroy (cr);

	    pass = FALSE;
	    if (status) {
		cairo_test_log (ctx, "Error: Failed to create target surface: %s\n",
				cairo_status_to_string (status));
		ret = CAIRO_TEST_FAILURE;
	    } else {
		/* extract the image and compare it to our reference */
		if (! check_result (ctx, target, test_name, base_name, surface))
		    ret = CAIRO_TEST_FAILURE;
		else
		    pass = TRUE;
	    }
	    cairo_surface_destroy (surface);
	    if (target->cleanup)
		target->cleanup (closure);

	    free (base_name);
	    free (test_name);

	    if (pass) {
		printf ("PASS\n");
	    } else {
		printf ("FAIL\n");
	    }
	    fflush (stdout);
	}
    }

    return ret;
}
Beispiel #6
0
void expose(dt_view_t *self, cairo_t *cri, int32_t width_i, int32_t height_i, int32_t pointerx, int32_t pointery)
{
  // startup-time conf parameter:
  const int32_t capwd = darktable.thumbnail_width;
  const int32_t capht = darktable.thumbnail_height;
  // if width or height > max pipeline pixels: center the view and clamp.
  int32_t width  = MIN(width_i,  capwd);
  int32_t height = MIN(height_i, capht);

  cairo_set_source_rgb (cri, .2, .2, .2);
  cairo_save(cri);
  cairo_set_fill_rule(cri, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_rectangle(cri, 0, 0, width_i, height_i);
  cairo_rectangle(cri,
                  MAX(1.0, width_i -capwd) *.5f,
                  MAX(1.0, height_i-capht) *.5f,
                  MIN(width, width_i-1), MIN(height, height_i-1));
  cairo_fill (cri);
  cairo_restore(cri);

  if(width_i  > capwd) cairo_translate(cri, -(capwd-width_i) *.5f, 0.0f);
  if(height_i > capht) cairo_translate(cri, 0.0f, -(capht-height_i)*.5f);
  cairo_save(cri);

  dt_develop_t *dev = (dt_develop_t *)self->data;

  if(dev->gui_synch && !dev->image_loading)
  {
    // synch module guis from gtk thread:
    darktable.gui->reset = 1;
    GList *modules = dev->iop;
    while(modules)
    {
      dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
      dt_iop_gui_update(module);
      modules = g_list_next(modules);
    }
    darktable.gui->reset = 0;
    dev->gui_synch = 0;
  }

  if(dev->image_dirty || dev->pipe->input_timestamp < dev->preview_pipe->input_timestamp) dt_dev_process_image(dev);
  if(dev->preview_dirty || dev->pipe->input_timestamp > dev->preview_pipe->input_timestamp) dt_dev_process_preview(dev);

  dt_pthread_mutex_t *mutex = NULL;
  int wd, ht, stride, closeup;
  int32_t zoom;
  float zoom_x, zoom_y;
  DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y);
  DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x);
  DT_CTL_GET_GLOBAL(zoom, dev_zoom);
  DT_CTL_GET_GLOBAL(closeup, dev_closeup);
  static cairo_surface_t *image_surface = NULL;
  static int image_surface_width = 0, image_surface_height = 0, image_surface_imgid = -1;

  if(image_surface_width != width || image_surface_height != height || image_surface == NULL)
  {
    // create double-buffered image to draw on, to make modules draw more fluently.
    image_surface_width = width;
    image_surface_height = height;
    if(image_surface) cairo_surface_destroy(image_surface);
    image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
    image_surface_imgid = -1; // invalidate old stuff
  }
  cairo_surface_t *surface;
  cairo_t *cr = cairo_create(image_surface);

  // adjust scroll bars
  {
    float zx = zoom_x, zy = zoom_y, boxw = 1., boxh = 1.;
    dt_dev_check_zoom_bounds(dev, &zx, &zy, zoom, closeup, &boxw, &boxh);
    dt_view_set_scrollbar(self, zx+.5-boxw*.5, 1.0, boxw, zy+.5-boxh*.5, 1.0, boxh);
  }

  if(!dev->image_dirty && dev->pipe->input_timestamp >= dev->preview_pipe->input_timestamp)
  {
    // draw image
    mutex = &dev->pipe->backbuf_mutex;
    dt_pthread_mutex_lock(mutex);
    wd = dev->pipe->backbuf_width;
    ht = dev->pipe->backbuf_height;
    stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd);
    surface = cairo_image_surface_create_for_data (dev->pipe->backbuf, CAIRO_FORMAT_RGB24, wd, ht, stride);
    cairo_set_source_rgb (cr, .2, .2, .2);
    cairo_paint(cr);
    cairo_translate(cr, .5f*(width-wd), .5f*(height-ht));
    if(closeup)
    {
      const float closeup_scale = 2.0;
      cairo_scale(cr, closeup_scale, closeup_scale);
      float boxw = 1, boxh = 1, zx0 = zoom_x, zy0 = zoom_y, zx1 = zoom_x, zy1 = zoom_y, zxm = -1.0, zym = -1.0;
      dt_dev_check_zoom_bounds(dev, &zx0, &zy0, zoom, 0, &boxw, &boxh);
      dt_dev_check_zoom_bounds(dev, &zx1, &zy1, zoom, 1, &boxw, &boxh);
      dt_dev_check_zoom_bounds(dev, &zxm, &zym, zoom, 1, &boxw, &boxh);
      const float fx = 1.0 - fmaxf(0.0, (zx0 - zx1)/(zx0 - zxm)), fy = 1.0 - fmaxf(0.0, (zy0 - zy1)/(zy0 - zym));
      cairo_translate(cr, -wd/(2.0*closeup_scale) * fx, -ht/(2.0*closeup_scale) * fy);
    }
    cairo_rectangle(cr, 0, 0, wd, ht);
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST);
    cairo_fill_preserve(cr);
    cairo_set_line_width(cr, 1.0);
    cairo_set_source_rgb (cr, .3, .3, .3);
    cairo_stroke(cr);
    cairo_surface_destroy (surface);
    dt_pthread_mutex_unlock(mutex);
    image_surface_imgid = dev->image_storage.id;
  }
  else if(!dev->preview_dirty)
  {
    // draw preview
    mutex = &dev->preview_pipe->backbuf_mutex;
    dt_pthread_mutex_lock(mutex);

    wd = dev->preview_pipe->backbuf_width;
    ht = dev->preview_pipe->backbuf_height;
    float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1);
    cairo_set_source_rgb (cr, .2, .2, .2);
    cairo_paint(cr);
    cairo_rectangle(cr, 0, 0, width, height);
    cairo_clip(cr);
    stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd);
    surface = cairo_image_surface_create_for_data (dev->preview_pipe->backbuf, CAIRO_FORMAT_RGB24, wd, ht, stride);
    cairo_translate(cr, width/2.0, height/2.0f);
    cairo_scale(cr, zoom_scale, zoom_scale);
    cairo_translate(cr, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht);
    // avoid to draw the 1px garbage that sometimes shows up in the preview :(
    cairo_rectangle(cr, 0, 0, wd-1, ht-1);
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST);
    cairo_fill(cr);
    cairo_surface_destroy (surface);
    dt_pthread_mutex_unlock(mutex);
    image_surface_imgid = dev->image_storage.id;
  }
  cairo_restore(cri);

  if(image_surface_imgid == dev->image_storage.id)
  {
    cairo_destroy(cr);
    cairo_set_source_surface(cri, image_surface, 0, 0);
    cairo_paint(cri);
  }

  /* check if we should create a snapshot of view */
  if(darktable.develop->proxy.snapshot.request)
  {
    /* reset the request */
    darktable.develop->proxy.snapshot.request = FALSE;

    /* validation of snapshot filename */
    g_assert(darktable.develop->proxy.snapshot.filename != NULL);

    /* Store current image surface to snapshot file.
       FIXME: add checks so that we dont make snapshots of preview pipe image surface.
    */
    cairo_surface_write_to_png(image_surface, darktable.develop->proxy.snapshot.filename);
  }

  // Displaying sample areas if enabled
  if(darktable.lib->proxy.colorpicker.live_samples &&
      darktable.lib->proxy.colorpicker.display_samples)
  {
    GSList *samples = darktable.lib->proxy.colorpicker.live_samples;
    dt_colorpicker_sample_t *sample = NULL;

    cairo_save(cri);

    int32_t zoom, closeup;
    float zoom_x, zoom_y;
    float wd = dev->preview_pipe->backbuf_width;
    float ht = dev->preview_pipe->backbuf_height;
    DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y);
    DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x);
    DT_CTL_GET_GLOBAL(zoom, dev_zoom);
    DT_CTL_GET_GLOBAL(closeup, dev_closeup);
    float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1);

    cairo_translate(cri, width/2.0, height/2.0f);
    cairo_scale(cri, zoom_scale, zoom_scale);
    cairo_translate(cri, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht);

    while(samples)
    {
      sample = samples->data;

      cairo_set_line_width(cri, 1.0/zoom_scale);
      if(sample == darktable.lib->proxy.colorpicker.selected_sample)
        cairo_set_source_rgb(cri, .2, 0, 0);
      else
        cairo_set_source_rgb(cri, 0, 0, .2);

      float *box = sample->box;
      float *point = sample->point;
      if(sample->size == DT_COLORPICKER_SIZE_BOX)
      {
        cairo_rectangle(cri, box[0]*wd, box[1]*ht,
                        (box[2] - box[0])*wd, (box[3] - box[1])*ht);
        cairo_stroke(cri);
        cairo_translate(cri, 1.0/zoom_scale, 1.0/zoom_scale);
        if(sample == darktable.lib->proxy.colorpicker.selected_sample)
          cairo_set_source_rgb(cri, .8, 0, 0);
        else
          cairo_set_source_rgb(cri, 0, 0, .8);
        cairo_rectangle(cri, box[0]*wd + 1.0/zoom_scale, box[1]*ht,
                        (box[2] - box[0])*wd - 3./zoom_scale,
                        (box[3] - box[1])*ht - 2./zoom_scale);
        cairo_stroke(cri);
      }
      else
      {
        cairo_rectangle(cri, point[0] * wd - .01 * wd, point[1] * ht - .01 * wd,
                        .02 * wd, .02 * wd);
        cairo_stroke(cri);

        if(sample == darktable.lib->proxy.colorpicker.selected_sample)
          cairo_set_source_rgb(cri, .8, 0, 0);
        else
          cairo_set_source_rgb(cri, 0, 0, .8);
        cairo_rectangle(cri, (point[0] - 0.01) * wd + 1.0/zoom_scale,
                        point[1] * ht - 0.01 * wd + 1.0/zoom_scale,
                        .02 * wd - 2./zoom_scale, .02 * wd - 2./zoom_scale);
        cairo_move_to(cri, point[0] * wd,
                      point[1] * ht - .01 * wd + 1./zoom_scale);
        cairo_line_to(cri, point[0] * wd,
                      point[1] * ht + .01 * wd - 1./zoom_scale);
        cairo_move_to(cri, point[0] * wd - .01 * wd + 1./zoom_scale,
                      point[1] * ht);
        cairo_line_to(cri, point[0] * wd + .01 * wd - 1./zoom_scale,
                      point[1] * ht);
        cairo_stroke(cri);
      }

      samples = g_slist_next(samples);
    }

    cairo_restore(cri);
  }

  // execute module callback hook.
  if(dev->gui_module && dev->gui_module->request_color_pick)
  {
    int32_t zoom, closeup;
    float zoom_x, zoom_y;
    float wd = dev->preview_pipe->backbuf_width;
    float ht = dev->preview_pipe->backbuf_height;
    DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y);
    DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x);
    DT_CTL_GET_GLOBAL(zoom, dev_zoom);
    DT_CTL_GET_GLOBAL(closeup, dev_closeup);
    float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1);

    cairo_translate(cri, width/2.0, height/2.0f);
    cairo_scale(cri, zoom_scale, zoom_scale);
    cairo_translate(cri, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht);

    // cairo_set_operator(cri, CAIRO_OPERATOR_XOR);
    cairo_set_line_width(cri, 1.0/zoom_scale);
    cairo_set_source_rgb(cri, .2, .2, .2);

    float *box = dev->gui_module->color_picker_box;
    float *point = dev->gui_module->color_picker_point;
    if(darktable.lib->proxy.colorpicker.size)
    {
      cairo_rectangle(cri, box[0]*wd, box[1]*ht,
                      (box[2] - box[0])*wd, (box[3] - box[1])*ht);
      cairo_stroke(cri);
      cairo_translate(cri, 1.0/zoom_scale, 1.0/zoom_scale);
      cairo_set_source_rgb(cri, .8, .8, .8);
      cairo_rectangle(cri, box[0]*wd + 1.0/zoom_scale, box[1]*ht,
                      (box[2] - box[0])*wd - 3./zoom_scale,
                      (box[3] - box[1])*ht - 2./zoom_scale);
      cairo_stroke(cri);
    }
    else
    {
      cairo_rectangle(cri, point[0] * wd - .01 * wd, point[1] * ht - .01 * wd,
                      .02 * wd, .02 * wd);
      cairo_stroke(cri);

      cairo_set_source_rgb(cri, .8, .8, .8);
      cairo_rectangle(cri, (point[0] - 0.01) * wd + 1.0/zoom_scale,
                      point[1] * ht - 0.01 * wd + 1.0/zoom_scale,
                      .02 * wd - 2./zoom_scale, .02 * wd - 2./zoom_scale);
      cairo_move_to(cri, point[0] * wd,
                    point[1] * ht - .01 * wd + 1./zoom_scale);
      cairo_line_to(cri, point[0] * wd,
                    point[1] * ht + .01 * wd - 1./zoom_scale);
      cairo_move_to(cri, point[0] * wd - .01 * wd + 1./zoom_scale,
                    point[1] * ht);
      cairo_line_to(cri, point[0] * wd + .01 * wd - 1./zoom_scale,
                    point[1] * ht);
      cairo_stroke(cri);
    }
  }
  else if(dev->gui_module && dev->gui_module->gui_post_expose)
  {
    if(width_i  > capwd) pointerx += (capwd-width_i) *.5f;
    if(height_i > capht) pointery += (capht-height_i)*.5f;
    dev->gui_module->gui_post_expose(dev->gui_module, cri, width, height, pointerx, pointery);
  }
}
Beispiel #7
0
static PyObject *
pycairo_restore (PycairoContext *o) {
  cairo_restore (o->ctx);
  RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
  Py_RETURN_NONE;
}
Beispiel #8
0
void grava_renderer_draw_node (cairo_t* ctx, GravaNode* node) {
#line 185 "renderer.vala"
	g_return_if_fail (ctx != NULL);
#line 185 "renderer.vala"
	g_return_if_fail (node != NULL);
#line 187 "renderer.vala"
	cairo_save (ctx);
#line 189 "renderer.vala"
	cairo_set_tolerance (ctx, 0.1);
#line 190 "renderer.vala"
	cairo_set_line_join (ctx, CAIRO_LINE_JOIN_ROUND);
#line 191 "renderer.vala"
	cairo_set_line_width (ctx, (double) 1);
#line 192 "renderer.vala"
	cairo_translate (ctx, node->x, node->y);
#line 462 "renderer.c"
	/*ctx.set_source_rgb (1, 1, 1);*/
#line 195 "renderer.vala"
	cairo_set_source_rgb (ctx, 0.8, 0.8, 0.8);
#line 466 "renderer.c"
	/*#if 0
	if (node.calls.length() >0) 
	set_color(ctx, "red");
	else
	set_color(ctx, "blue");
	#endif
	*/
#line 203 "renderer.vala"
	grava_renderer_set_color (ctx, node->data);
#line 204 "renderer.vala"
	grava_renderer_set_color_str (ctx, (const char*) g_hash_table_lookup (node->data, "bgcolor"));
#line 206 "renderer.vala"
	if (node->has_body) {
#line 207 "renderer.vala"
		switch (node->shape) {
#line 482 "renderer.c"
			case GRAVA_SHAPE_CIRCLE:
			{
#line 209 "renderer.vala"
				grava_renderer_circle (ctx, node->w, node->h);
#line 210 "renderer.vala"
				cairo_fill (ctx);
#line 211 "renderer.vala"
				break;
#line 491 "renderer.c"
			}
			default:
			{
#line 214 "renderer.vala"
				grava_renderer_square (ctx, node->w, node->h);
#line 215 "renderer.vala"
				cairo_fill (ctx);
#line 216 "renderer.vala"
				break;
#line 501 "renderer.c"
			}
		}
	}
	/* title rectangle */
#line 221 "renderer.vala"
	if (((const char*) g_hash_table_lookup (node->data, "color")) != NULL) {
#line 222 "renderer.vala"
		grava_renderer_set_color_str (ctx, (const char*) g_hash_table_lookup (node->data, "color"));
#line 510 "renderer.c"
	} else {
#line 224 "renderer.vala"
		if (g_slist_length (node->calls) == 1) {
#line 225 "renderer.vala"
			cairo_set_source_rgba (ctx, 0.2, 0.2, 0.4, 0.7);
#line 516 "renderer.c"
		} else {
#line 227 "renderer.vala"
			if (g_slist_length (node->calls) > 0) {
#line 228 "renderer.vala"
				cairo_set_source_rgba (ctx, 0.3, 0.3, (double) 1, 0.7);
#line 522 "renderer.c"
			} else {
#line 230 "renderer.vala"
				cairo_set_source_rgba (ctx, 0.8, 0.8, 0.8, 0.8);
#line 526 "renderer.c"
			}
		}
	}
#line 231 "renderer.vala"
	grava_renderer_square (ctx, node->w, (double) 15);
#line 232 "renderer.vala"
	cairo_fill (ctx);
#line 233 "renderer.vala"
	grava_renderer_line (ctx, (double) 0, (double) 15, node->w, (double) 0);
#line 536 "renderer.c"
	/* draw minimize button */
#line 236 "renderer.vala"
	cairo_save (ctx);
#line 540 "renderer.c"
	/*ctx.set_source_rgba (0.7, 0.0, 0.0, 1);*/
#line 238 "renderer.vala"
	cairo_set_source_rgba (ctx, 0.6, 0.6, 0.6, 0.8);
#line 239 "renderer.vala"
	cairo_translate (ctx, node->w - 13, (double) 3);
#line 240 "renderer.vala"
	grava_renderer_square (ctx, (double) 10, (double) 10);
#line 241 "renderer.vala"
	cairo_fill (ctx);
#line 242 "renderer.vala"
	cairo_restore (ctx);
#line 244 "renderer.vala"
	cairo_select_font_face (ctx, "Sans Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
#line 554 "renderer.c"
	/*Courier", */
#line 247 "renderer.vala"
	cairo_set_font_size (ctx, (double) 10);
#line 558 "renderer.c"
	/* set label */
#line 250 "renderer.vala"
	cairo_set_source_rgb (ctx, 0.1, 0.1, 0.1);
#line 251 "renderer.vala"
	cairo_move_to (ctx, (double) 5, (double) 10);
#line 252 "renderer.vala"
	cairo_show_text (ctx, (const char*) g_hash_table_lookup (node->data, "label"));
#line 566 "renderer.c"
	/* set body */
#line 255 "renderer.vala"
	if (node->has_body) {
#line 570 "renderer.c"
		gint y;
		const char* _tmp0_;
		char* body;
		y = 25;
#line 257 "renderer.vala"
		_tmp0_ = NULL;
#line 577 "renderer.c"
		body = (_tmp0_ = (const char*) g_hash_table_lookup (node->data, "body"), (_tmp0_ == NULL) ? NULL : g_strdup (_tmp0_));
#line 258 "renderer.vala"
		if (body != NULL) {
#line 581 "renderer.c"
			{
				char** _tmp1_;
				char** str_collection;
				int str_collection_length1;
				int str_it;
				_tmp1_ = NULL;
#line 259 "renderer.vala"
				str_collection = _tmp1_ = g_strsplit (body, "\n", 0);
#line 590 "renderer.c"
				str_collection_length1 = _vala_array_length (_tmp1_);
				for (str_it = 0; str_it < _vala_array_length (_tmp1_); str_it = str_it + 1) {
					const char* _tmp3_;
					char* str;
#line 822 "glib-2.0.vapi"
					_tmp3_ = NULL;
#line 597 "renderer.c"
					str = (_tmp3_ = str_collection[str_it], (_tmp3_ == NULL) ? NULL : g_strdup (_tmp3_));
					{
						gboolean _tmp2_ = {0};
#line 260 "renderer.vala"
						y = y + 10;
#line 261 "renderer.vala"
						cairo_move_to (ctx, (double) 5, (double) y);
#line 262 "renderer.vala"
						if (strstr (str, "call ") != NULL) {
#line 262 "renderer.vala"
							_tmp2_ = TRUE;
#line 609 "renderer.c"
						} else {
#line 263 "renderer.vala"
							_tmp2_ = strstr (str, "bl ") != NULL;
#line 613 "renderer.c"
						}
#line 262 "renderer.vala"
						if (_tmp2_) {
#line 264 "renderer.vala"
							grava_renderer_set_color_str (ctx, "blue");
#line 619 "renderer.c"
						} else {
#line 266 "renderer.vala"
							if (strstr (str, "goto") != NULL) {
#line 267 "renderer.vala"
								grava_renderer_set_color_str (ctx, "green");
#line 625 "renderer.c"
							} else {
#line 269 "renderer.vala"
								if (strstr (str, " j") != NULL) {
#line 270 "renderer.vala"
									grava_renderer_set_color_str (ctx, "green");
#line 631 "renderer.c"
								} else {
#line 272 "renderer.vala"
									if (g_str_has_suffix (str, ":")) {
#line 273 "renderer.vala"
										grava_renderer_set_color_str (ctx, "red");
#line 637 "renderer.c"
									} else {
#line 275 "renderer.vala"
										grava_renderer_set_color_str (ctx, "black");
#line 641 "renderer.c"
									}
								}
							}
						}
#line 276 "renderer.vala"
						cairo_show_text (ctx, str);
#line 648 "renderer.c"
						str = (g_free (str), NULL);
					}
				}
#line 259 "renderer.vala"
				str_collection = (_vala_array_free (str_collection, str_collection_length1, (GDestroyNotify) g_free), NULL);
#line 654 "renderer.c"
			}
		}
		/*set_color(ctx, node.data);
		 box square */
#line 281 "renderer.vala"
		if (grava_graph_selected == node) {
#line 661 "renderer.c"
			/*ctx.set_source_rgba (1, 0.8, 0.0, 0.9);*/
#line 283 "renderer.vala"
			cairo_set_source_rgba (ctx, (double) 0, 0.0, 0.0, 1.0);
#line 284 "renderer.vala"
			cairo_set_line_width (ctx, (double) 2);
#line 667 "renderer.c"
		} else {
#line 286 "renderer.vala"
			cairo_set_source_rgba (ctx, 0.2, 0.2, 0.2, 0.4);
#line 287 "renderer.vala"
			cairo_set_line_width (ctx, (double) 1);
#line 673 "renderer.c"
		}
#line 290 "renderer.vala"
		if (node->shape == GRAVA_SHAPE_CIRCLE) {
#line 291 "renderer.vala"
			grava_renderer_circle (ctx, node->w, node->h);
#line 679 "renderer.c"
		} else {
#line 292 "renderer.vala"
			grava_renderer_square (ctx, node->w, node->h);
#line 683 "renderer.c"
		}
		body = (g_free (body), NULL);
	}
#line 295 "renderer.vala"
	cairo_stroke (ctx);
#line 297 "renderer.vala"
	cairo_restore (ctx);
#line 691 "renderer.c"
}
void spectool_channel_draw(GtkWidget *widget, cairo_t *cr, SpectoolWidget *wwidget) {
	SpectoolChannel *channel;
	cairo_text_extents_t extents;
	int x, chpix;
	char mtext[128];

	g_return_if_fail(widget != NULL);

	channel = SPECTOOL_CHANNEL(wwidget);

	cairo_save(cr);

	channel->chan_h = extents.height + ((double) extents.height * 0.1) + 5;

	/* Try to figure out the channels we use for this spectrum */
	for (x = 0; wwidget->chanopts != NULL &&
		 channel_list[x].name != NULL && wwidget->chanopts->chanset == NULL; x++) {
		if (channel_list[x].startkhz >= 
			wwidget->sweepcache->latest->start_khz &&
			channel_list[x].endkhz <= wwidget->sweepcache->latest->end_khz) {
			int cpos;
			double r, g, b;

			wwidget->chanopts->chanset = &(channel_list[x]);

			/* Allocate the channels that are 'hit' or highlighted */
			if (wwidget->chanopts->chanhit)
				free(wwidget->chanopts->chanhit);
			wwidget->chanopts->chanhit = 
				malloc(sizeof(int) * wwidget->chanopts->chanset->chan_num);
			memset(wwidget->chanopts->chanhit, 0, 
				   sizeof(int) * wwidget->chanopts->chanset->chan_num);

			/* Allocate color sweep */
			if (wwidget->chanopts->chancolors)
				free(wwidget->chanopts->chancolors);
			wwidget->chanopts->chancolors = malloc(sizeof(double) *
										 wwidget->chanopts->chanset->chan_num * 3);

			for (cpos = 0; cpos < wwidget->chanopts->chanset->chan_num; cpos++) {
				/* Get the RGB values of a full-intensity color somewhere
				 * along the H slider derived from the channel position */
				hsv_to_rgb(&r, &g, &b, 
						   (360 / wwidget->chanopts->chanset->chan_num) * cpos, 1, 1);
				/* Convert the hex colors to cairo colors */
				wwidget->chanopts->chancolors[(3 * cpos) + 0] = HC2CC(r);
				wwidget->chanopts->chancolors[(3 * cpos) + 1] = HC2CC(g);
				wwidget->chanopts->chancolors[(3 * cpos) + 2] = HC2CC(b);
			}

			break;
		}
	}

	/* Plot the channels if we know how */
	if (wwidget->chanopts != NULL && wwidget->chanopts->chanset != NULL && 
		wwidget->show_channels) {
		/* Allocate the channel point array if we haven't yet, so the mouse
		 * handlers know where we've clicked.  Points allocated inside the
		 * channel widget itself. */
		if (channel->chan_points == NULL) {
			channel->chan_points =
				(GdkPoint *) malloc(sizeof(GdkPoint) *
									wwidget->chanopts->chanset->chan_num * 2);
		}

		/* Draw the channel text along the bottom */
		cairo_save(cr);
		for (x = 0; x < wwidget->chanopts->chanset->chan_num; x++) {
			chpix = ((float) wwidget->g_len_x /
					 (wwidget->sweepcache->latest->end_khz -
					  wwidget->sweepcache->latest->start_khz)) *
				(wwidget->chanopts->chanset->chan_freqs[x] - 
				 wwidget->sweepcache->latest->start_khz);

			if (x == wwidget->chanopts->hi_chan) {
				cairo_set_source_rgb(cr, HC2CC(0xFF), HC2CC(0xF6), HC2CC(0x00));
				snprintf(mtext, 128, "%s", 
						 wwidget->chanopts->chanset->chan_text[x]);
			} else {
				cairo_set_source_rgb(cr, 1, 1, 1);
				snprintf(mtext, 128, "%s", 
						 wwidget->chanopts->chanset->chan_text[x]);
			}

			cairo_move_to(cr, wwidget->g_start_x + chpix, 
						  wwidget->g_start_y);
			cairo_line_to(cr, wwidget->g_start_x + chpix, wwidget->g_start_y + 5);
			cairo_stroke(cr);

			cairo_select_font_face(cr, "Helvetica", 
								   CAIRO_FONT_SLANT_NORMAL, 
								   CAIRO_FONT_WEIGHT_BOLD);
			cairo_set_font_size(cr, 14);
			cairo_text_extents(cr, mtext, &extents);
			cairo_move_to(cr, 
						  wwidget->g_start_x + chpix - (extents.width / 2),
						  wwidget->g_start_y + 10 + extents.height);
			cairo_show_text(cr, mtext);

			channel->chan_points[x].x = 
				wwidget->g_start_x + chpix - (extents.width / 2) - 4;
			channel->chan_points[x].y = wwidget->g_start_y + 10 - 4;
			channel->chan_points[x + wwidget->chanopts->chanset->chan_num].x =
				channel->chan_points[x].x + extents.width + 8;
			channel->chan_points[x + wwidget->chanopts->chanset->chan_num].y =
				channel->chan_points[x].y + extents.height + 10;

			if (wwidget->chanopts->chanhit[x]) {
				cairo_save(cr);
				cairo_set_source_rgba(cr,
								wwidget->chanopts->chancolors[(3 * x) + 0],
								wwidget->chanopts->chancolors[(3 * x) + 1],
								wwidget->chanopts->chancolors[(3 * x) + 2], 0.60);
				cairo_rectangle(cr,
						wwidget->g_start_x + chpix - (extents.width / 2) - 3.5,
						wwidget->g_start_y + 10 - 3.5,
								extents.width + 8,
								extents.height + 10);
				cairo_fill(cr);
				/* cairo_stroke(cr); */
				cairo_restore(cr);
			}
		}

		channel->chan_start_x = channel->chan_points[0].x - 1;
		channel->chan_end_x = 
			channel->chan_points[(wwidget->chanopts->chanset->chan_num * 2) - 1].x + 1;
		channel->chan_start_y = channel->chan_points[0].y - 1;
		channel->chan_end_y = 
			channel->chan_points[(wwidget->chanopts->chanset->chan_num * 2) - 1].y + 1;

		cairo_restore(cr);

	}
}
Beispiel #10
0
void *dt_control_expose(void *voidptr)
{
  int width, height, pointerx, pointery;
  if(!darktable.gui->surface) return NULL;
  width = dt_cairo_image_surface_get_width(darktable.gui->surface);
  height = dt_cairo_image_surface_get_height(darktable.gui->surface);
  GtkWidget *widget = dt_ui_center(darktable.gui->ui);
  gtk_widget_get_pointer(widget, &pointerx, &pointery);

  // create a gtk-independent surface to draw on
  cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);

  // TODO: control_expose: only redraw the part not overlapped by temporary control panel show!
  //
  float tb = 8; // fmaxf(10, width/100.0);
  darktable.control->tabborder = tb;
  darktable.control->width = width;
  darktable.control->height = height;

  GtkStyle *style = gtk_widget_get_style(widget);
  cairo_set_source_rgb(cr, style->bg[GTK_STATE_NORMAL].red / 65535.0,
                       style->bg[GTK_STATE_NORMAL].green / 65535.0,
                       style->bg[GTK_STATE_NORMAL].blue / 65535.0);

  cairo_set_line_width(cr, tb);
  cairo_rectangle(cr, tb / 2., tb / 2., width - tb, height - tb);
  cairo_stroke(cr);
  cairo_set_line_width(cr, 1.5);
  cairo_set_source_rgb(cr, .1, .1, .1);
  cairo_rectangle(cr, tb, tb, width - 2 * tb, height - 2 * tb);
  cairo_stroke(cr);

  cairo_save(cr);
  cairo_translate(cr, tb, tb);
  cairo_rectangle(cr, 0, 0, width - 2 * tb, height - 2 * tb);
  cairo_clip(cr);
  cairo_new_path(cr);
  // draw view
  dt_view_manager_expose(darktable.view_manager, cr, width - 2 * tb, height - 2 * tb, pointerx - tb,
                         pointery - tb);
  cairo_restore(cr);

  // draw status bar, if any
  if(darktable.control->progress < 100.0)
  {
    tb = fmaxf(20, width / 40.0);
    char num[10];
    cairo_rectangle(cr, width * 0.4, height * 0.85, width * 0.2 * darktable.control->progress / 100.0f, tb);
    cairo_fill(cr);
    cairo_set_source_rgb(cr, 0., 0., 0.);
    cairo_rectangle(cr, width * 0.4, height * 0.85, width * 0.2, tb);
    cairo_stroke(cr);
    cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
    cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size(cr, tb / 3);
    cairo_move_to(cr, width / 2.0 - 10, height * 0.85 + 2. * tb / 3.);
    snprintf(num, sizeof(num), "%d%%", (int)darktable.control->progress);
    cairo_show_text(cr, num);
  }
  // draw log message, if any
  dt_pthread_mutex_lock(&darktable.control->log_mutex);
  if(darktable.control->log_ack != darktable.control->log_pos)
  {
    cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    const float fontsize = 14;
    cairo_set_font_size(cr, fontsize);
    cairo_text_extents_t ext;
    cairo_text_extents(cr, darktable.control->log_message[darktable.control->log_ack], &ext);
    const float pad = 20.0f, xc = width / 2.0;
    const float yc = height * 0.85 + 10, wd = pad + ext.width * .5f;
    float rad = 14;
    cairo_set_line_width(cr, 1.);
    cairo_move_to(cr, xc - wd, yc + rad);
    for(int k = 0; k < 5; k++)
    {
      cairo_arc(cr, xc - wd, yc, rad, M_PI / 2.0, 3.0 / 2.0 * M_PI);
      cairo_line_to(cr, xc + wd, yc - rad);
      cairo_arc(cr, xc + wd, yc, rad, 3.0 * M_PI / 2.0, M_PI / 2.0);
      cairo_line_to(cr, xc - wd, yc + rad);
      if(k == 0)
      {
        cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
        cairo_fill_preserve(cr);
      }
      cairo_set_source_rgba(cr, 0., 0., 0., 1.0 / (1 + k));
      cairo_stroke(cr);
      rad += .5f;
    }
    cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
    cairo_move_to(cr, xc - wd + .5f * pad, yc + 1. / 3. * fontsize);
    cairo_show_text(cr, darktable.control->log_message[darktable.control->log_ack]);
  }
  // draw busy indicator
  if(darktable.control->log_busy > 0)
  {
    cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    const float fontsize = 14;
    cairo_set_font_size(cr, fontsize);
    cairo_text_extents_t ext;
    cairo_text_extents(cr, _("working.."), &ext);
    const float xc = width / 2.0, yc = height * 0.85 - 30, wd = ext.width * .5f;
    cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize);
    cairo_text_path(cr, _("working.."));
    cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
    cairo_fill_preserve(cr);
    cairo_set_line_width(cr, 0.7);
    cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
    cairo_stroke(cr);
  }
  dt_pthread_mutex_unlock(&darktable.control->log_mutex);

  cairo_destroy(cr);

  cairo_t *cr_pixmap = cairo_create(darktable.gui->surface);
  cairo_set_source_surface(cr_pixmap, cst, 0, 0);
  cairo_paint(cr_pixmap);
  cairo_destroy(cr_pixmap);

  cairo_surface_destroy(cst);
  return NULL;
}
Beispiel #11
0
void grava_renderer_draw_edge (cairo_t* ctx, GravaEdge* edge) {
#line 158 "renderer.c"
	double dx;
	double dy;
	double oh;
#line 25 "renderer.vala"
	g_return_if_fail (ctx != NULL);
#line 25 "renderer.vala"
	g_return_if_fail (edge != NULL);
#line 166 "renderer.c"
	dx = (double) 0;
	dy = (double) 0;
	oh = edge->orig->h;
#line 31 "renderer.vala"
	if (edge->orig->has_body == FALSE) {
#line 32 "renderer.vala"
		oh = (double) 16;
#line 174 "renderer.c"
	}
#line 34 "renderer.vala"
	cairo_save (ctx);
#line 178 "renderer.c"
	/* triangle dest*/
#line 37 "renderer.vala"
	if (grava_graph_selected == edge->orig) {
#line 38 "renderer.vala"
		cairo_set_line_width (ctx, (double) 6);
#line 184 "renderer.c"
	} else {
#line 39 "renderer.vala"
		cairo_set_line_width (ctx, (double) 1);
#line 188 "renderer.c"
	}
#line 40 "renderer.vala"
	grava_renderer_set_color (ctx, edge->data);
#line 41 "renderer.vala"
	cairo_translate (ctx, edge->orig->x + (edge->orig->w / 2), edge->orig->y + oh);
#line 42 "renderer.vala"
	cairo_translate (ctx, dx - 4, dy);
#line 43 "renderer.vala"
	grava_renderer_triangle (ctx, (double) 8, (double) 8, TRUE);
#line 44 "renderer.vala"
	cairo_stroke (ctx);
#line 46 "renderer.vala"
	cairo_restore (ctx);
#line 47 "renderer.vala"
	cairo_save (ctx);
#line 49 "renderer.vala"
	grava_renderer_set_color (ctx, edge->data);
#line 51 "renderer.vala"
	cairo_set_line_width (ctx, (double) 2);
#line 208 "renderer.c"
	/* oxymoroon! */
#line 53 "renderer.vala"
	if (edge->orig == edge->dest) {
#line 212 "renderer.c"
		double ox;
		/* bottom to up */
#line 55 "renderer.vala"
		cairo_translate (ctx, edge->orig->x + (edge->orig->w / 2), edge->orig->y + oh);
#line 56 "renderer.vala"
		cairo_move_to (ctx, (double) 0, (double) 0);
#line 219 "renderer.c"
		/*dx = edge.dest.x-edge.orig.x;*/
#line 58 "renderer.vala"
		dx = ((edge->dest->x - edge->orig->x) - (edge->orig->w / 1.3)) + (edge->dest->w / 1.3);
#line 223 "renderer.c"
		/*-edge.orig.x;*/
#line 59 "renderer.vala"
		dy = (edge->dest->y - edge->orig->y) - oh;
#line 227 "renderer.c"
		/* or 80 or so depending if > or < ???*/
		ox = dx;
		/*if (ox == 0){ ox = 150; }
		arrow*/
#line 63 "renderer.vala"
		if (grava_graph_selected == edge->orig) {
#line 64 "renderer.vala"
			cairo_set_line_width (ctx, (double) 6);
#line 236 "renderer.c"
		}
#line 66 "renderer.vala"
		dx = edge->dest->w;
#line 240 "renderer.c"
		/*dy += edge.dest.h/2;
		////ctx.curve_to(0, 0, 200, 100, dx-edge.orig.w/2, dy);*/
#line 69 "renderer.vala"
		cairo_curve_to (ctx, (double) 0, (double) 0, (edge->dest->x - edge->orig->x) / 2, (edge->dest->y - edge->orig->y) / 2, (edge->dest->x - edge->orig->x) / 2, (edge->dest->y - edge->orig->y) / 2);
#line 245 "renderer.c"
	} else {
#line 93 "renderer.vala"
		if ((edge->orig->y + oh) < edge->dest->y) {
#line 249 "renderer.c"
			/*-edge.dest.h)) {
			 up to bottom 
			ctx.translate (edge.orig.x+(edge.orig.w/1.3),edge.orig.y+oh);*/
#line 96 "renderer.vala"
			cairo_translate (ctx, edge->orig->x + (edge->orig->w / 2), edge->orig->y + oh);
#line 97 "renderer.vala"
			cairo_move_to (ctx, (double) 0, (double) 0);
#line 257 "renderer.c"
			/*dx = edge.dest.x-edge.orig.x-(edge.orig.w/1.3) + edge.dest.w/1.3; //-edge.orig.x;*/
#line 99 "renderer.vala"
			dx = ((edge->dest->x - edge->orig->x) + (edge->dest->w / 2)) - (edge->orig->w / 2);
#line 100 "renderer.vala"
			dy = (edge->dest->y - edge->orig->y) - oh;
#line 263 "renderer.c"
			/*ctx.move_to(30,30);
			ctx.set_source_rgb (0.0, 0.0, 0.0);*/
#line 103 "renderer.vala"
			if (grava_graph_selected == edge->orig) {
#line 104 "renderer.vala"
				cairo_set_line_width (ctx, (double) 6);
#line 270 "renderer.c"
			}
#line 105 "renderer.vala"
			grava_renderer_line (ctx, (double) 0, (double) 0, dx, dy);
#line 274 "renderer.c"
		} else {
			double ox;
			double _x;
			double _y;
			/* bottom to up */
#line 108 "renderer.vala"
			cairo_translate (ctx, edge->orig->x + (edge->orig->w / 2), edge->orig->y + oh);
#line 109 "renderer.vala"
			cairo_move_to (ctx, (double) 0, (double) 0);
#line 284 "renderer.c"
			/*dx = edge.dest.x-edge.orig.x;*/
#line 111 "renderer.vala"
			dx = ((edge->dest->x - edge->orig->x) + (edge->dest->w / 2)) - (edge->orig->w / 2);
#line 112 "renderer.vala"
			dy = (edge->dest->y - edge->orig->y) - oh;
#line 290 "renderer.c"
			/* or 80 or so depending if > or < ???*/
			ox = dx;
			/*if (ox == 0){ ox = 150; }
			arrow*/
#line 116 "renderer.vala"
			if (grava_graph_selected == edge->orig) {
#line 117 "renderer.vala"
				cairo_set_line_width (ctx, (double) 6);
#line 299 "renderer.c"
			}
			_x = (-(edge->orig->x - edge->dest->x)) / 1.5;
			_y = (-(edge->orig->y - edge->dest->y)) / 3;
#line 120 "renderer.vala"
			cairo_curve_to (ctx, _x, _y, _x, _y, dx, dy);
#line 305 "renderer.c"
		}
	}
	/*ctx.stroke();*/
#line 124 "renderer.vala"
	cairo_stroke (ctx);
#line 125 "renderer.vala"
	if (grava_graph_selected == edge->orig) {
#line 126 "renderer.vala"
		cairo_set_line_width (ctx, (double) 6);
#line 315 "renderer.c"
	} else {
#line 127 "renderer.vala"
		cairo_set_line_width (ctx, (double) 1);
#line 319 "renderer.c"
	}
	/* triangle dest*/
#line 130 "renderer.vala"
	cairo_translate (ctx, dx - 4, dy - 8);
#line 131 "renderer.vala"
	grava_renderer_triangle (ctx, (double) 8, (double) 8, TRUE);
#line 132 "renderer.vala"
	cairo_stroke (ctx);
#line 134 "renderer.vala"
	cairo_restore (ctx);
#line 135 "renderer.vala"
	cairo_set_source_rgba (ctx, 0.6, 0.6, 0.6, (double) 1);
#line 332 "renderer.c"
}
Beispiel #12
0
static void
e_contact_print_contact (EContact *contact,
                         EContactPrintContext *ctxt)
{
	GtkPageSetup *setup;
	gchar *file_as;
	cairo_t *cr;
	gdouble page_height;
	gint field;

	setup = gtk_print_context_get_page_setup (ctxt->context);
	page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);

	cr = gtk_print_context_get_cairo_context (ctxt->context);
	cairo_save (cr);
	ctxt->y += get_font_height (ctxt->style->headings_font) * .2;

	file_as = e_contact_get (contact, E_CONTACT_FILE_AS);

	if (ctxt->style->print_using_grey && ctxt->pages == ctxt->page_nr) {
		cairo_save (cr);
		cairo_set_source_rgb (cr, .85, .85, .85);
		cairo_rectangle (cr, ctxt->x, ctxt->y, ctxt->column_width,
			e_contact_text_height (ctxt->context,
				ctxt->style->headings_font, file_as));
		cairo_fill (cr);
		cairo_restore (cr);
	}

	if (ctxt->pages == ctxt->page_nr)
		e_contact_output (
			ctxt->context, ctxt->style->headings_font,
			ctxt->x, ctxt->y, ctxt->column_width + 4, file_as);
	ctxt->y += e_contact_text_height (
		ctxt->context, ctxt->style->headings_font, file_as);

	g_free (file_as);

	ctxt->y += get_font_height (ctxt->style->headings_font) * .2;

	for (field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++)
	{
		const gchar *value;
		gchar *text;
		gint wrapped_lines = 0;

		if (ctxt->y > page_height)
			e_contact_start_new_column (ctxt);

		value = e_contact_get_const (contact, field);
		if (value == NULL || *value == '\0')
			continue;

		text = g_strdup_printf ("%s:  %s",
			e_contact_pretty_name (field), value);

		if (ctxt->pages == ctxt->page_nr)
			e_contact_output (
				ctxt->context, ctxt->style->body_font,
				ctxt->x, ctxt->y, ctxt->column_width + 4, text);

		if (get_font_width (ctxt->context,
			ctxt->style->body_font, text) > ctxt->column_width)
			wrapped_lines =
				(get_font_width (ctxt->context,
				ctxt->style->body_font, text) /
				(ctxt->column_width + 4)) + 1;
		ctxt->y =
			ctxt->y + ((wrapped_lines + 1) *
			e_contact_text_height (ctxt->context,
			ctxt->style->body_font, text));

		ctxt->y += .2 * get_font_height (ctxt->style->body_font);

		g_free (text);
	}

	ctxt->y += get_font_height (ctxt->style->headings_font) * .4 + 8;

	cairo_restore (cr);
}
Beispiel #13
0
void
hippo_canvas_item_pop_cairo (HippoCanvasItem *item,
                             cairo_t         *cr)
{
    cairo_restore(cr);
}
Beispiel #14
0
static void
draw_window (GtkWidget                   *widget,
             #if GTK_CHECK_VERSION(3, 0, 0)
             cairo_t                     *cr,
             #else
             GdkDrawable                 *drawable,
             #endif
             const WnckWindowDisplayInfo *win,
             const GdkRectangle          *winrect,
             GtkStateType                state)
{
  #if !GTK_CHECK_VERSION(3, 0, 0)
  cairo_t *cr;
  #endif

  GdkPixbuf *icon;
  int icon_x, icon_y, icon_w, icon_h;
  gboolean is_active;
  GdkColor *color;
  GtkStyle *style;

  is_active = win->is_active;

  #if GTK_CHECK_VERSION(3, 0, 0)
  cairo_save(cr);
  #else
  cr = gdk_cairo_create (drawable);
  #endif

  cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
  cairo_clip (cr);

  style = gtk_widget_get_style (widget);
  if (is_active)
    color = &style->light[state];
  else
    color = &style->bg[state];
  cairo_set_source_rgb (cr,
                        color->red / 65535.,
                        color->green / 65535.,
                        color->blue / 65535.);

  cairo_rectangle (cr,
                   winrect->x + 1, winrect->y + 1,
                   MAX (0, winrect->width - 2), MAX (0, winrect->height - 2));
  cairo_fill (cr);


  icon = win->icon;

  icon_w = icon_h = 0;

  if (icon)
    {
      icon_w = gdk_pixbuf_get_width (icon);
      icon_h = gdk_pixbuf_get_height (icon);

      /* If the icon is too big, fall back to mini icon.
       * We don't arbitrarily scale the icon, because it's
       * just too slow on my Athlon 850.
       */
      if (icon_w > (winrect->width - 2) ||
          icon_h > (winrect->height - 2))
        {
          icon = win->mini_icon;
          if (icon)
            {
              icon_w = gdk_pixbuf_get_width (icon);
              icon_h = gdk_pixbuf_get_height (icon);

              /* Give up. */
              if (icon_w > (winrect->width - 2) ||
                  icon_h > (winrect->height - 2))
                icon = NULL;
            }
        }
    }

  if (icon)
    {
      icon_x = winrect->x + (winrect->width - icon_w) / 2;
      icon_y = winrect->y + (winrect->height - icon_h) / 2;

      cairo_save (cr);
      gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y);
      cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
      cairo_clip (cr);
      cairo_paint (cr);
      cairo_restore (cr);
    }

  if (is_active)
    color = &style->fg[state];
  else
    color = &style->fg[state];

  cairo_set_source_rgb (cr,
                        color->red / 65535.,
                        color->green / 65535.,
                        color->blue / 65535.);
  cairo_set_line_width (cr, 1.0);
  cairo_rectangle (cr,
                   winrect->x + 0.5, winrect->y + 0.5,
                   MAX (0, winrect->width - 1), MAX (0, winrect->height - 1));
  cairo_stroke (cr);

  #if GTK_CHECK_VERSION(3, 0, 0)
  cairo_restore(cr);
  #else
  cairo_destroy (cr);
  #endif
}
Beispiel #15
0
static gboolean _lib_filmstrip_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data;

  int32_t width = widget->allocation.width;
  int32_t height = widget->allocation.height;

  gdouble pointerx = strip->pointerx;
  gdouble pointery = strip->pointery;

  if(darktable.gui->center_tooltip == 1)
    darktable.gui->center_tooltip++;

  strip->image_over = DT_VIEW_DESERT;
  DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, -1);

  /* create cairo surface */
  cairo_t *cr = gdk_cairo_create(widget->window);

  /* fill background */
  cairo_set_source_rgb (cr, .2, .2, .2);
  cairo_paint(cr);

  int offset = strip->offset;

  const float wd = height;
  const float ht = height;

  int max_cols = (int)(width/(float)wd) + 2;
  if (max_cols%2 == 0)
    max_cols += 1;

  const int col_start = max_cols/2 - strip->offset;
  const int empty_edge = (width - (max_cols * wd))/2;
  int step_res = SQLITE_ROW;

  sqlite3_stmt *stmt = NULL;

  /* mouse over image position in filmstrip */
  pointerx -= empty_edge;
  const int seli = (pointery > 0 && pointery <= ht) ? pointerx / (float)wd : -1;
  const int img_pointerx = (int)fmodf(pointerx, wd);
  const int img_pointery = (int)pointery;


  /* get the count of current collection */
  strip->collection_count = dt_collection_get_count (darktable.collection);

  /* get the collection query */
  const gchar *query=dt_collection_get_query (darktable.collection);
  if(!query)
    return FALSE;

  if(offset < 0)
    strip->offset = offset = 0;
  if(offset > strip->collection_count-1)
    strip->offset = offset = strip->collection_count-1;

  // dt_view_set_scrollbar(self, offset, count, max_cols, 0, 1, 1);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, offset - max_cols/2);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, max_cols);


  cairo_save(cr);
  cairo_translate(cr, empty_edge, 0.0f);
  for(int col = 0; col < max_cols; col++)
  {
    if(col < col_start)
    {
      cairo_translate(cr, wd, 0.0f);
      continue;
    }

    if(step_res != SQLITE_DONE)
    {
      step_res = sqlite3_step(stmt);
    }

    if(step_res == SQLITE_ROW)
    {
      int id = sqlite3_column_int(stmt, 0);
      // set mouse over id
      if(seli == col)
      {
        strip->mouse_over_id = id;
        DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, strip->mouse_over_id);
      }
      cairo_save(cr);
      // FIXME find out where the y translation is done, how big the value is and use it directly instead of getting it from the matrix ...
      cairo_matrix_t m;
      cairo_get_matrix(cr, &m);
      dt_view_image_expose(&(strip->image_over), id, cr, wd, ht, max_cols, img_pointerx, img_pointery, FALSE);
      cairo_restore(cr);
    }
    else if (step_res == SQLITE_DONE)
    {
      /* do nothing, just add some empty thumb frames */
    }
    else goto failure;
    cairo_translate(cr, wd, 0.0f);
  }
failure:
  cairo_restore(cr);
  sqlite3_finalize(stmt);

  if(darktable.gui->center_tooltip == 1) // set in this round
  {
    char* tooltip = dt_history_get_items_as_string(strip->mouse_over_id);
    if(tooltip != NULL)
    {
      g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", tooltip, (char *)NULL);
      g_free(tooltip);
    }
  }
  else if(darktable.gui->center_tooltip == 2)   // not set in this round
  {
    darktable.gui->center_tooltip = 0;
    g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", "", (char *)NULL);
  }

#ifdef _DEBUG
  if(darktable.unmuted & DT_DEBUG_CACHE)
    dt_mipmap_cache_print(darktable.mipmap_cache);
#endif

  /* cleanup */
  cairo_destroy(cr);

  return TRUE;
}
Beispiel #16
0
static bool
render(zathura_t* zathura, zathura_page_t* page)
{
  if (zathura == NULL || page == NULL || zathura->sync.render_thread->about_to_close == true) {
    return false;
  }

  /* create cairo surface */
  unsigned int page_width  = 0;
  unsigned int page_height = 0;
  page_calc_height_width(page, &page_height, &page_width, false);

  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);

  if (surface == NULL) {
    return false;
  }

  cairo_t* cairo = cairo_create(surface);

  if (cairo == NULL) {
    cairo_surface_destroy(surface);
    return false;
  }

  cairo_save(cairo);
  cairo_set_source_rgb(cairo, 1, 1, 1);
  cairo_rectangle(cairo, 0, 0, page_width, page_height);
  cairo_fill(cairo);
  cairo_restore(cairo);
  cairo_save(cairo);

  double scale = zathura_document_get_scale(zathura->document);
  if (fabs(scale - 1.0f) > FLT_EPSILON) {
    cairo_scale(cairo, scale, scale);
  }

  render_lock(zathura->sync.render_thread);
  if (zathura_page_render(page, cairo, false) != ZATHURA_ERROR_OK) {
    render_unlock(zathura->sync.render_thread);
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);
    return false;
  }

  render_unlock(zathura->sync.render_thread);
  cairo_restore(cairo);
  cairo_destroy(cairo);

  const int rowstride  = cairo_image_surface_get_stride(surface);
  unsigned char* image = cairo_image_surface_get_data(surface);

  /* recolor */
  /* uses a representation of a rgb color as follows:
     - a lightness scalar (between 0,1), which is a weighted average of r, g, b,
     - a hue vector, which indicates a radian direction from the grey axis, inside the equal lightness plane.
     - a saturation scalar between 0,1. It is 0 when grey, 1 when the color is in the boundary of the rgb cube.
  */
  if (zathura->global.recolor == true) {
    /* RGB weights for computing lightness. Must sum to one */
    double a[] = {0.30, 0.59, 0.11};

    double l1, l2, l, s, u, t;
    double h[3];
    double rgb1[3], rgb2[3], rgb[3];

    color2double(&zathura->ui.colors.recolor_dark_color, rgb1);
    color2double(&zathura->ui.colors.recolor_light_color, rgb2);

    l1 = (a[0]*rgb1[0] + a[1]*rgb1[1] + a[2]*rgb1[2]);
    l2 = (a[0]*rgb2[0] + a[1]*rgb2[1] + a[2]*rgb2[2]);

    for (unsigned int y = 0; y < page_height; y++) {
      unsigned char* data = image + y * rowstride;

      for (unsigned int x = 0; x < page_width; x++) {
        /* Careful. data color components blue, green, red. */
        rgb[0] = (double) data[2] / 256.;
        rgb[1] = (double) data[1] / 256.;
        rgb[2] = (double) data[0] / 256.;

        /* compute h, s, l data   */
        l = a[0]*rgb[0] + a[1]*rgb[1] + a[2]*rgb[2];

        h[0] = rgb[0] - l;
        h[1] = rgb[1] - l;
        h[2] = rgb[2] - l;

        /* u is the maximum possible saturation for given h and l. s is a rescaled saturation between 0 and 1 */
        u = colorumax(h, l, 0, 1);
        if (u == 0) {
          s = 0;
        } else {
          s = 1/u;
        }

        /* Interpolates lightness between light and dark colors. white goes to light, and black goes to dark. */
        t = l;
        l = t * (l2 - l1) + l1;

        if (zathura->global.recolor_keep_hue == true) {
          /* adjusting lightness keeping hue of current color. white and black go to grays of same ligtness
             as light and dark colors. */
          u = colorumax(h, l, l1, l2);
          data[2] = (unsigned char)round(255.*(l + s*u * h[0]));
          data[1] = (unsigned char)round(255.*(l + s*u * h[1]));
          data[0] = (unsigned char)round(255.*(l + s*u * h[2]));
        } else {
          /* Linear interpolation between dark and light with color ligtness as a parameter */
          data[2] = (unsigned char)round(255.*(t * (rgb2[0] - rgb1[0]) + rgb1[0]));
          data[1] = (unsigned char)round(255.*(t * (rgb2[1] - rgb1[1]) + rgb1[1]));
          data[0] = (unsigned char)round(255.*(t * (rgb2[2] - rgb1[2]) + rgb1[2]));
        }

        data += 4;
      }
    }
  }

  if (zathura->sync.render_thread->about_to_close == false) {
    /* update the widget */
    gdk_threads_enter();
    GtkWidget* widget = zathura_page_get_widget(zathura, page);
    zathura_page_widget_update_surface(ZATHURA_PAGE(widget), surface);
    gdk_threads_leave();
  } else {
    cairo_surface_destroy(surface);
  }

  return true;
}
Beispiel #17
0
static void
cb_print_draw_page(GtkPrintOperation* print_operation, GtkPrintContext*
                   context, gint page_number, zathura_t* zathura)
{
  if (context == NULL || zathura == NULL || zathura->document == NULL ||
      zathura->ui.session == NULL || zathura->ui.statusbar.file == NULL) {
    gtk_print_operation_cancel(print_operation);
    return;
  }

  /* Update statusbar. */
  char* tmp = g_strdup_printf("Printing %d...", page_number);
  girara_statusbar_item_set_text(zathura->ui.session,
                                 zathura->ui.statusbar.file, tmp);
  g_free(tmp);

  /* Get the page and cairo handle.  */
  cairo_t* cairo       = gtk_print_context_get_cairo_context(context);
  zathura_page_t* page = zathura_document_get_page(zathura->document, page_number);
  if (cairo == NULL || page == NULL) {
    gtk_print_operation_cancel(print_operation);
    return;
  }

  /* Try to render the page without a temporary surface. This only works with
   * plugins that support rendering to any surface.  */
  girara_debug("printing page %d ...", page_number);
  zathura_renderer_lock(zathura->sync.render_thread);
  int err = zathura_page_render(page, cairo, true);
  zathura_renderer_unlock(zathura->sync.render_thread);
  if (err == ZATHURA_ERROR_OK) {
    return;
  }

  /* Try to render the page on a temporary image surface. */
  const gdouble width = gtk_print_context_get_width(context);
  const gdouble height = gtk_print_context_get_height(context);

  /* Render to a surface that is 5 times larger to workaround quality issues. */
  const double page_height = zathura_page_get_height(page) * 5;
  const double page_width  = zathura_page_get_width(page) * 5;
  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);
  if (surface == NULL) {
    gtk_print_operation_cancel(print_operation);
    return;
  }

  cairo_t* temp_cairo = cairo_create(surface);
  if (cairo == NULL) {
    gtk_print_operation_cancel(print_operation);
    cairo_surface_destroy(surface);
    return;
  }

  /* Draw a white background. */
  cairo_save(temp_cairo);
  cairo_set_source_rgb(temp_cairo, 1, 1, 1);
  cairo_rectangle(temp_cairo, 0, 0, page_width, page_height);
  cairo_fill(temp_cairo);
  cairo_restore(temp_cairo);

  /* Render the page to the temporary surface */
  girara_debug("printing page %d (fallback) ...", page_number);
  zathura_renderer_lock(zathura->sync.render_thread);
  err = zathura_page_render(page, temp_cairo, true);
  zathura_renderer_unlock(zathura->sync.render_thread);
  if (err != ZATHURA_ERROR_OK) {
    cairo_destroy(temp_cairo);
    cairo_surface_destroy(surface);
    gtk_print_operation_cancel(print_operation);
    return;
  }

  /* Rescale the page and keep the aspect ratio */
  const gdouble scale = MIN(width / page_width, height / page_height);
  cairo_scale(cairo, scale, scale);

  /* Blit temporary surface to original cairo object. */
  cairo_set_source_surface(cairo, surface, 0.0, 0.0);
  cairo_paint(cairo);
  cairo_destroy(temp_cairo);
  cairo_surface_destroy(surface);
}
Beispiel #18
0
void
dt_view_image_expose(
    dt_view_image_over_t *image_over,
    uint32_t imgid,
    cairo_t *cr,
    int32_t width,
    int32_t height,
    int32_t zoom,
    int32_t px,
    int32_t py)
{
    const double start = dt_get_wtime();
    // some performance tuning stuff, for your pleasure.
    // on my machine with 7 image per row it seems grouping has the largest
    // impact from around 400ms -> 55ms per redraw.
#define DRAW_THUMB 1
#define DRAW_COLORLABELS 1
#define DRAW_GROUPING 1
#define DRAW_SELECTED 1
#define DRAW_HISTORY 1

#if DRAW_THUMB == 1
    // this function is not thread-safe (gui-thread only), so we
    // can safely allocate this leaking bit of memory to decompress thumbnails:
    static int first_time = 1;
    static uint8_t *scratchmem = NULL;
    if(first_time)
    {
        // scratchmem might still be NULL after this, if compression is off.
        scratchmem = dt_mipmap_cache_alloc_scratchmem(darktable.mipmap_cache);
        first_time = 0;
    }
#endif

    cairo_save (cr);
    float bgcol = 0.4, fontcol = 0.425, bordercol = 0.1, outlinecol = 0.2;
    int selected = 0, altered = 0, imgsel = -1, is_grouped = 0;
    // this is a gui thread only thing. no mutex required:
    imgsel = darktable.control->global_settings.lib_image_mouse_over_id;

#if DRAW_SELECTED == 1
    /* clear and reset statements */
    DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.is_selected);
    DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.is_selected);
    /* bind imgid to prepared statments */
    DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.is_selected, 1, imgid);
    /* lets check if imgid is selected */
    if(sqlite3_step(darktable.view_manager->statements.is_selected) == SQLITE_ROW)
        selected = 1;
#endif

#if DRAW_HISTORY == 1
    DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.have_history);
    DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.have_history);
    DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.have_history, 1, imgid);

    /* lets check if imgid has history */
    if(sqlite3_step(darktable.view_manager->statements.have_history) == SQLITE_ROW)
        altered = 1;
#endif

    const dt_image_t *img = dt_image_cache_read_testget(darktable.image_cache, imgid);

#if DRAW_GROUPING == 1
    DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.get_grouped);
    DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.get_grouped);
    DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_grouped, 1, imgid);
    DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_grouped, 2, imgid);

    /* lets check if imgid is in a group */
    if(sqlite3_step(darktable.view_manager->statements.get_grouped) == SQLITE_ROW)
        is_grouped = 1;
    else if(img && darktable.gui->expanded_group_id == img->group_id)
        darktable.gui->expanded_group_id = -1;
#endif

    if(selected == 1)
    {
        outlinecol = 0.4;
        bgcol = 0.6;
        fontcol = 0.5;
    }
    if(imgsel == imgid)
    {
        bgcol = 0.8;  // mouse over
        fontcol = 0.7;
        outlinecol = 0.6;
        // if the user points at this image, we really want it:
        if(!img)
            img = dt_image_cache_read_get(darktable.image_cache, imgid);
    }
    float imgwd = 0.90f;
    if(zoom == 1)
    {
        imgwd = .97f;
        // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
    }
    else
    {
        double x0 = 1, y0 = 1, rect_width = width-2, rect_height = height-2, radius = 5;
        double x1, y1, off, off1;

        x1=x0+rect_width;
        y1=y0+rect_height;
        off=radius*0.666;
        off1 = radius-off;
        cairo_move_to  (cr, x0, y0 + radius);
        cairo_curve_to (cr, x0, y0+off1, x0+off1 , y0, x0 + radius, y0);
        cairo_line_to (cr, x1 - radius, y0);
        cairo_curve_to (cr, x1-off1, y0, x1, y0+off1, x1, y0 + radius);
        cairo_line_to (cr, x1 , y1 - radius);
        cairo_curve_to (cr, x1, y1-off1, x1-off1, y1, x1 - radius, y1);
        cairo_line_to (cr, x0 + radius, y1);
        cairo_curve_to (cr, x0+off1, y1, x0, y1-off1, x0, y1- radius);
        cairo_close_path (cr);
        cairo_set_source_rgb(cr, bgcol, bgcol, bgcol);
        cairo_fill_preserve(cr);
        cairo_set_line_width(cr, 0.005*width);
        cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol);
        cairo_stroke(cr);

        if(img)
        {
            const char *ext = img->filename + strlen(img->filename);
            while(ext > img->filename && *ext != '.') ext--;
            ext++;
            cairo_set_source_rgb(cr, fontcol, fontcol, fontcol);
            cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
            cairo_set_font_size (cr, .25*width);
            cairo_text_extents_t text_extends;
            cairo_text_extents (cr, ext, &text_extends);
            cairo_move_to (cr, .025*width - text_extends.x_bearing, .24*height);
            cairo_show_text (cr, ext);
        }
    }

    dt_mipmap_buffer_t buf;
    dt_mipmap_size_t mip =
        dt_mipmap_cache_get_matching_size(
            darktable.mipmap_cache,
            imgwd*width, imgwd*height);
    dt_mipmap_cache_read_get(
        darktable.mipmap_cache,
        &buf,
        imgid,
        mip,
        0);
#if DRAW_THUMB == 1
    float scale = 1.0;
    // decompress image, if necessary. if compression is off, scratchmem will be == NULL,
    // so get the real pointer back:
    uint8_t *buf_decompressed = dt_mipmap_cache_decompress(&buf, scratchmem);

    cairo_surface_t *surface = NULL;
    if(buf.buf)
    {
        const int32_t stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, buf.width);
        surface = cairo_image_surface_create_for_data (buf_decompressed, CAIRO_FORMAT_RGB24, buf.width, buf.height, stride);
        if(zoom == 1)
        {
            scale = fminf(
                        fminf(darktable.thumbnail_width, width) / (float)buf.width,
                        fminf(darktable.thumbnail_height, height) / (float)buf.height
                    );
        }
        else scale = fminf(width*imgwd/(float)buf.width, height*imgwd/(float)buf.height);
    }

    // draw centered and fitted:
    cairo_save(cr);
    cairo_translate(cr, width/2.0, height/2.0f);
    cairo_scale(cr, scale, scale);

    if(buf.buf)
    {
        cairo_translate(cr, -.5f*buf.width, -.5f*buf.height);
        cairo_set_source_surface (cr, surface, 0, 0);
        // set filter no nearest:
        // in skull mode, we want to see big pixels.
        // in 1 iir mode for the right mip, we want to see exactly what the pipe gave us, 1:1 pixel for pixel.
        // in between, filtering just makes stuff go unsharp.
        if((buf.width <= 8 && buf.height <= 8) || fabsf(scale - 1.0f) < 0.01f)
            cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
        cairo_rectangle(cr, 0, 0, buf.width, buf.height);
        cairo_fill(cr);
        cairo_surface_destroy (surface);

        cairo_rectangle(cr, 0, 0, buf.width, buf.height);
    }

    // border around image
    const float border = zoom == 1 ? 16/scale : 2/scale;
    cairo_set_source_rgb(cr, bordercol, bordercol, bordercol);
    if(buf.buf && selected)
    {
        cairo_set_line_width(cr, 1./scale);
        if(zoom == 1)
        {
            // draw shadow around border
            cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
            cairo_stroke(cr);
            // cairo_new_path(cr);
            cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
            float alpha = 1.0f;
            for(int k=0; k<16; k++)
            {
                cairo_rectangle(cr, 0, 0, buf.width, buf.height);
                cairo_new_sub_path(cr);
                cairo_rectangle(cr, -k/scale, -k/scale, buf.width+2.*k/scale, buf.height+2.*k/scale);
                cairo_set_source_rgba(cr, 0, 0, 0, alpha);
                alpha *= 0.6f;
                cairo_fill(cr);
            }
        }
        else
        {
            cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
            cairo_new_sub_path(cr);
            cairo_rectangle(cr, -border, -border, buf.width+2.*border, buf.height+2.*border);
            cairo_stroke_preserve(cr);
            cairo_set_source_rgb(cr, 1.0-bordercol, 1.0-bordercol, 1.0-bordercol);
            cairo_fill(cr);
        }
    }
    else if(buf.buf)
    {
        cairo_set_line_width(cr, 1);
        cairo_stroke(cr);
    }
    cairo_restore(cr);
#endif
    if(buf.buf)
        dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf);

    const float fscale = fminf(width, height);
    if(imgsel == imgid)
    {
        // draw mouseover hover effects, set event hook for mouse button down!
        *image_over = DT_VIEW_DESERT;
        cairo_set_line_width(cr, 1.5);
        cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol);
        cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
        float r1, r2;
        if(zoom != 1)
        {
            r1 = 0.05*width;
            r2 = 0.022*width;
        }
        else
        {
            r1 = 0.015*fscale;
            r2 = 0.007*fscale;
        }

        float x, y;
        if(zoom != 1) y = 0.90*height;
        else y = .12*fscale;
        gboolean image_is_rejected = (img && ((img->flags & 0x7) == 6));

        if(img) for(int k=0; k<5; k++)
            {
                if(zoom != 1) x = (0.41+k*0.12)*width;
                else x = (.08+k*0.04)*fscale;

                if(!image_is_rejected) //if rejected: draw no stars
                {
                    dt_view_star(cr, x, y, r1, r2);
                    if((px - x)*(px - x) + (py - y)*(py - y) < r1*r1)
                    {
                        *image_over = DT_VIEW_STAR_1 + k;
                        cairo_fill(cr);
                    }
                    else if((img->flags & 0x7) > k)
                    {
                        cairo_fill_preserve(cr);
                        cairo_set_source_rgb(cr, 1.0-bordercol, 1.0-bordercol, 1.0-bordercol);
                        cairo_stroke(cr);
                        cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol);
                    }
                    else cairo_stroke(cr);
                }
            }

        //Image rejected?
        if(zoom !=1) x = 0.11*width;
        else x = .04*fscale;

        if (image_is_rejected)
            cairo_set_source_rgb(cr, 1., 0., 0.);

        if((px - x)*(px - x) + (py - y)*(py - y) < r1*r1)
        {
            *image_over = DT_VIEW_REJECT; //mouse sensitive
            cairo_new_sub_path(cr);
            cairo_arc(cr, x, y, (r1+r2)*.5, 0, 2.0f*M_PI);
            cairo_stroke(cr);
        }

        if (image_is_rejected)
            cairo_set_line_width(cr, 2.5);

        //reject cross:
        cairo_move_to(cr, x-r2, y-r2);
        cairo_line_to(cr, x+r2, y+r2);
        cairo_move_to(cr, x+r2, y-r2);
        cairo_line_to(cr, x-r2, y+r2);
        cairo_close_path(cr);
        cairo_stroke(cr);
        cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol);
        cairo_set_line_width(cr, 1.5);


        // image part of a group?
        if(is_grouped && darktable.gui && darktable.gui->grouping)
        {
            // draw grouping icon and border if the current group is expanded
            // align to the right, left of altered
            float s = (r1+r2)*.75;
            float _x, _y;
            if(zoom != 1)
            {
                _x = width*0.9 - s*2.5;
                _y = height*0.1 - s*.4;
            }
            else
            {
                _x = (.04+7*0.04-1.1*.04)*fscale;
                _y = y - (.17*.04)*fscale;
            }
            cairo_save(cr);
            if(img && (imgid != img->group_id))
                cairo_set_source_rgb(cr, fontcol, fontcol, fontcol);
            dtgtk_cairo_paint_grouping(cr, _x, _y, s, s, 23);
            cairo_restore(cr);
            // mouse is over the grouping icon
            if(img && abs(px-_x-.5*s) <= .8*s && abs(py-_y-.5*s) <= .8*s)
                *image_over = DT_VIEW_GROUP;
        }

        // image altered?
        if(altered)
        {
            // align to right
            float s = (r1+r2)*.5;
            if(zoom != 1)
            {
                x = width*0.9;
                y = height*0.1;
            }
            else x = (.04+7*0.04)*fscale;
            dt_view_draw_altered(cr, x, y, s);
            //g_print("px = %d, x = %.4f, py = %d, y = %.4f\n", px, x, py, y);
            if(img && abs(px-x) <= 1.2*s && abs(py-y) <= 1.2*s) // mouse hovers over the altered-icon -> history tooltip!
            {
                darktable.gui->center_tooltip = 1;
            }
        }
    }

    // kill all paths, in case img was not loaded yet, or is blocked:
    cairo_new_path(cr);

#if DRAW_COLORLABELS == 1
    // TODO: make mouse sensitive, just as stars!
    // TODO: cache in image struct!
    {
        // color labels:
        const float x = zoom == 1 ? (0.07)*fscale : .21*width;
        const float y = zoom == 1 ? 0.17*fscale: 0.1*height;
        const float r = zoom == 1 ? 0.01*fscale : 0.03*width;

        /* clear and reset prepared statement */
        DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.get_color);
        DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.get_color);

        /* setup statement and iterate rows */
        DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_color, 1, imgid);
        while(sqlite3_step(darktable.view_manager->statements.get_color) == SQLITE_ROW)
        {
            cairo_save(cr);
            int col = sqlite3_column_int(darktable.view_manager->statements.get_color, 0);
            // see src/dtgtk/paint.c
            dtgtk_cairo_paint_label(cr, x+(3*r*col)-5*r, y-r, r*2, r*2, col);
            cairo_restore(cr);
        }
    }
#endif

    if(img && (zoom == 1))
    {
        // some exif data
        cairo_set_source_rgb(cr, .7, .7, .7);
        cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size (cr, .025*fscale);

        cairo_move_to (cr, .02*fscale, .04*fscale);
        // cairo_show_text(cr, img->filename);
        cairo_text_path(cr, img->filename);
        char exifline[50];
        cairo_move_to (cr, .02*fscale, .08*fscale);
        dt_image_print_exif(img, exifline, 50);
        cairo_text_path(cr, exifline);
        cairo_fill_preserve(cr);
        cairo_set_line_width(cr, 1.0);
        cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
        cairo_stroke(cr);
    }

    if(img) dt_image_cache_read_release(darktable.image_cache, img);
    cairo_restore(cr);
    // if(zoom == 1) cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT);

    const double end = dt_get_wtime();
    dt_print(DT_DEBUG_PERF, "[lighttable] image expose took %0.04f sec\n", end-start);
}
Beispiel #19
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_surface_t        *surface;
    cairo_t                *cr2;
    cairo_rectangle_list_t *rectangle_list;
    const char             *phase;
    cairo_bool_t            uses_clip_rects;
    
    surface = cairo_surface_create_similar (cairo_get_target (cr),
                                            CAIRO_CONTENT_COLOR, 100, 100);
    /* don't use cr accidentally */
    cr = NULL;
    cr2 = cairo_create (surface);
    cairo_surface_destroy (surface);

    /* Check the surface type so we ignore cairo_copy_clip_rectangle_list failures
     * on surface types that don't use rectangle lists for clipping.
     * Default to FALSE for the internal surface types, (meta, test-fallback, etc.)
     */
    switch (cairo_surface_get_type (surface)) {
    case CAIRO_SURFACE_TYPE_IMAGE:
    case CAIRO_SURFACE_TYPE_XLIB:
    case CAIRO_SURFACE_TYPE_XCB:
    case CAIRO_SURFACE_TYPE_GLITZ:
    case CAIRO_SURFACE_TYPE_WIN32:
    case CAIRO_SURFACE_TYPE_BEOS:
    case CAIRO_SURFACE_TYPE_DIRECTFB:
        uses_clip_rects = TRUE;
	break;
    case CAIRO_SURFACE_TYPE_QUARTZ:
    case CAIRO_SURFACE_TYPE_PDF:
    case CAIRO_SURFACE_TYPE_PS:
    case CAIRO_SURFACE_TYPE_SVG:
    case CAIRO_SURFACE_TYPE_OS2:
    default:
        uses_clip_rects = FALSE;
        break;
    }

    /* first, test basic stuff. This should not be clipped, it should
       return the surface rectangle. */
    phase = "No clip set";
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
        !check_clip_extents (phase, cr2, 0, 0, 100, 100) ||
        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 0, 0, 100, 100)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);

    /* Test simple clip rect. */
    phase = "Simple clip rect";
    cairo_save (cr2);
    cairo_rectangle (cr2, 10, 10, 80, 80);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
        !check_clip_extents (phase, cr2, 10, 10, 80, 80) ||
        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);

    /* Test everything clipped out. */
    phase = "All clipped out";
    cairo_save (cr2);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_count (phase, uses_clip_rects, rectangle_list, 0)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);
    
    /* test two clip rects */
    phase = "Two clip rects";
    cairo_save (cr2);
    cairo_rectangle (cr2, 10, 10, 10, 10);
    cairo_rectangle (cr2, 20, 20, 10, 10);
    cairo_clip (cr2);
    cairo_rectangle (cr2, 15, 15, 10, 10);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_count (phase, uses_clip_rects, rectangle_list, 2) ||
        !check_clip_extents (phase, cr2, 15, 15, 10, 10) ||
        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 15, 15, 5, 5) ||
        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 20, 20, 5, 5)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);

    /* test non-rectangular clip */
    phase = "Nonrectangular clip";
    cairo_save (cr2);
    cairo_move_to (cr2, 0, 0);
    cairo_line_to (cr2, 100, 100);
    cairo_line_to (cr2, 100, 0);
    cairo_close_path (cr2);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
     /* can't get this in one tight user-space rectangle */
    if (!check_unrepresentable (phase, rectangle_list) ||
        !check_clip_extents (phase, cr2, 0, 0, 100, 100)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);
    
    phase = "User space, simple scale, getting clip with same transform";
    cairo_save (cr2);
    cairo_scale (cr2, 2, 2);
    cairo_rectangle (cr2, 5, 5, 40, 40);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
        !check_clip_extents (phase, cr2, 5, 5, 40, 40) ||
        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 5, 5, 40, 40)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);

    phase = "User space, simple scale, getting clip with no transform";
    cairo_save (cr2);
    cairo_save (cr2);
    cairo_scale (cr2, 2, 2);
    cairo_rectangle (cr2, 5, 5, 40, 40);
    cairo_restore (cr2);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_count (phase, uses_clip_rects, rectangle_list, 1) ||
        !check_clip_extents (phase, cr2, 10, 10, 80, 80) ||
        !check_rectangles_contain(phase, uses_clip_rects, rectangle_list, 10, 10, 80, 80)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);

    phase = "User space, rotation, getting clip with no transform";
    cairo_save (cr2);
    cairo_save (cr2);
    cairo_rotate (cr2, 12);
    cairo_rectangle (cr2, 5, 5, 40, 40);
    cairo_restore (cr2);
    cairo_clip (cr2);
    rectangle_list = cairo_copy_clip_rectangle_list (cr2);
    if (!check_unrepresentable (phase, rectangle_list)) {
        cairo_rectangle_list_destroy (rectangle_list);
	return CAIRO_TEST_FAILURE;
    }
    cairo_rectangle_list_destroy (rectangle_list);
    cairo_restore (cr2);

    cairo_destroy (cr2);
    return CAIRO_TEST_SUCCESS;
}
Beispiel #20
0
static gboolean
swatch_draw (GtkWidget *widget,
             cairo_t   *cr)
{
  GtkColorSwatch *swatch = (GtkColorSwatch*)widget;
  GtkThemingBackground background;
  gdouble width, height;
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkIconTheme *theme;
  GtkIconInfo *icon_info = NULL;

  theme = gtk_icon_theme_get_default ();
  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  cairo_save (cr);

  gtk_style_context_save (context);
  gtk_style_context_set_state (context, state);

  _gtk_theming_background_init_from_context (&background, context,
                                             0, 0, width, height,
                                             GTK_JUNCTION_NONE);

  if (swatch->priv->has_color)
    {
      cairo_pattern_t *pattern;
      cairo_matrix_t matrix;

      if (swatch->priv->use_alpha)
        {
          cairo_save (cr);

          _gtk_rounded_box_path (&background.padding_box, cr);
          cairo_clip_preserve (cr);

          cairo_set_source_rgb (cr, 0.33, 0.33, 0.33);
          cairo_fill_preserve (cr);

          pattern = _gtk_color_chooser_get_checkered_pattern ();
          cairo_matrix_init_scale (&matrix, 0.125, 0.125);
          cairo_pattern_set_matrix (pattern, &matrix);

          cairo_set_source_rgb (cr, 0.66, 0.66, 0.66);
          cairo_mask (cr, pattern);
          cairo_pattern_destroy (pattern);

          cairo_restore (cr);

          background.bg_color = swatch->priv->color;
        }
      else
        {
          background.bg_color = swatch->priv->color;
          background.bg_color.alpha = 1.0;
        }

      _gtk_theming_background_render (&background, cr);
    }
  else
    _gtk_theming_background_render (&background, cr);

  gtk_render_frame (context, cr,
                    0, 0, width, height);

  if (gtk_widget_has_visible_focus (widget))
    {
      cairo_set_line_width (cr, 2);
      if (swatch->priv->has_color && INTENSITY (swatch->priv->color.red, swatch->priv->color.green, swatch->priv->color.blue) < 0.5)
        cairo_set_source_rgba (cr, 1., 1., 1., 0.4);
      else
        cairo_set_source_rgba (cr, 0., 0., 0., 0.4);
        _gtk_rounded_box_shrink (&background.padding_box, 3, 3, 3, 3);
        _gtk_rounded_box_path (&background.padding_box, cr);
        cairo_stroke (cr);
    }

  if (swatch->priv->icon)
    {
      icon_info = gtk_icon_theme_lookup_icon (theme, swatch->priv->icon, 16,
                                              GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                              | GTK_ICON_LOOKUP_USE_BUILTIN);
    }
  else if ((state & GTK_STATE_FLAG_SELECTED) != 0)
    {
      GdkRGBA bg, border;
      GtkBorder border_width;
      GIcon *gicon;

      gtk_style_context_add_class (context, "color-active-badge");
      _gtk_theming_background_init_from_context (&background, context,
                                                 (width - 2 * ACTIVE_BADGE_RADIUS) / 2, (height - 2 * ACTIVE_BADGE_RADIUS) / 2,
                                                 2 * ACTIVE_BADGE_RADIUS, 2* ACTIVE_BADGE_RADIUS,
                                                 GTK_JUNCTION_NONE);

      if (_gtk_theming_background_has_background_image (&background))
        {
          _gtk_theming_background_render (&background, cr);
        }
      else
        {
          gtk_style_context_get_background_color (context, state, &bg);
          gtk_style_context_get_border_color (context, state, &border);
          gtk_style_context_get_border (context, state, &border_width);

          cairo_new_sub_path (cr);
          cairo_arc (cr, width / 2, height / 2, ACTIVE_BADGE_RADIUS, 0, 2 * G_PI);
          cairo_close_path (cr);
          gdk_cairo_set_source_rgba (cr, &bg);
          cairo_fill_preserve (cr);

          gdk_cairo_set_source_rgba (cr, &border);
          cairo_set_line_width (cr, border_width.left);
          cairo_stroke (cr);

          gicon = g_themed_icon_new ("object-select-symbolic");
          /* fallback for themes that don't have object-select-symbolic */
          g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply");

          icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, 16,
                                                      GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                                      | GTK_ICON_LOOKUP_USE_BUILTIN);
          g_object_unref (gicon);
        }
    }

  if (icon_info != NULL)
    {
      GdkPixbuf *pixbuf;

      pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context,
                                                        NULL, NULL);

      if (pixbuf != NULL)
        {
          gtk_render_icon (context, cr, pixbuf,
                           (width - gdk_pixbuf_get_width (pixbuf)) / 2,
                           (height - gdk_pixbuf_get_height (pixbuf)) / 2);
          g_object_unref (pixbuf);
        }

      g_object_unref (icon_info);
    }

  cairo_restore (cr);
  gtk_style_context_restore (context);

  return FALSE;
}
Beispiel #21
0
cairo_surface_t *
gb_widget_snapshot (GtkWidget *widget,
                    gint       width,
                    gint       height,
                    gdouble    alpha,
                    gboolean   draw_border)
{
  cairo_surface_t *surface;
  GtkAllocation alloc;
  gdouble x_ratio = 1.0;
  gdouble y_ratio = 1.0;
  cairo_t *cr;

  /*
   * XXX: This function conflates the drawing of borders and snapshoting.
   *      Totally not ideal, but we can clean that up later.
   */

  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
  cr = cairo_create (surface);

  gtk_widget_get_allocation (widget, &alloc);

  if ((width != alloc.width) || (height != alloc.height))
    {
      if (alloc.width > alloc.height)
        {
          x_ratio = (gdouble) width / (gdouble) alloc.width;
          y_ratio = (gdouble) width / (gdouble) alloc.width;
        }
      else
        {
          x_ratio = (gdouble) height / (gdouble) alloc.height;
          y_ratio = (gdouble) height / (gdouble) alloc.height;
        }
      cairo_scale (cr, x_ratio, y_ratio);
    }

  gtk_widget_draw (widget, cr);

  cairo_destroy (cr);

  {
    cairo_surface_t *other;
    GdkRectangle rect = {
      3,
      3,
      ceil (alloc.width * x_ratio) - 6,
      ceil (alloc.height * y_ratio) - 6
    };

    other = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
    cr = cairo_create (other);

    cairo_save (cr);

    if (draw_border)
      {
        gdk_cairo_rectangle (cr, &rect);
        cairo_clip (cr);
      }

    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_paint_with_alpha (cr, alpha);

    cairo_restore (cr);

    if (draw_border)
      {
        GdkRGBA rgba;

        gb_cairo_rounded_rectangle (cr, &rect, 3, 3);

        gdk_rgba_parse (&rgba, "#729fcf");
        gb_rgba_shade (&rgba, &rgba, 0.8);
        gdk_cairo_set_source_rgba (cr, &rgba);
        cairo_set_line_width (cr, 3.0);

        cairo_stroke (cr);

        gb_cairo_rounded_rectangle (cr, &rect, 1, 1);

        gdk_rgba_parse (&rgba, "#729fcf");
        gb_rgba_shade (&rgba, &rgba, 1.2);
        gdk_cairo_set_source_rgba (cr, &rgba);

        cairo_set_line_width (cr, 1.0);
        cairo_stroke (cr);
      }

    cairo_surface_destroy (surface);
    surface = other;
  }

  return surface;
}
static gboolean dt_iop_tonecurve_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_tonecurve_gui_data_t *c = (dt_iop_tonecurve_gui_data_t *)self->gui_data;
  dt_iop_tonecurve_params_t *p = (dt_iop_tonecurve_params_t *)self->params;
  dt_develop_t *dev = darktable.develop;

  const float color_labels_left[3][3] = { { 0.3f, 0.3f,  0.3f  },
    { 0.0f, 0.34f, 0.27f },
    { 0.0f, 0.27f, 0.58f }
  };

  const float color_labels_right[3][3] = {{ 0.3f, 0.3f, 0.3f   },
    { 0.53f, 0.08f, 0.28f},
    { 0.81f, 0.66f, 0.0f }
  };

  int ch = c->channel;
  int nodes = p->tonecurve_nodes[ch];
  dt_iop_tonecurve_node_t *tonecurve = p->tonecurve[ch];
  int autoscale_ab = p->tonecurve_autoscale_ab;
  if(c->minmax_curve_type[ch] != p->tonecurve_type[ch] || c->minmax_curve_nodes[ch] != p->tonecurve_nodes[ch])
  {
    dt_draw_curve_destroy(c->minmax_curve[ch]);
    c->minmax_curve[ch] = dt_draw_curve_new(0.0, 1.0, p->tonecurve_type[ch]);
    c->minmax_curve_nodes[ch] = p->tonecurve_nodes[ch];
    c->minmax_curve_type[ch] = p->tonecurve_type[ch];
    for(int k=0; k<p->tonecurve_nodes[ch]; k++)
      (void)dt_draw_curve_add_point(c->minmax_curve[ch], p->tonecurve[ch][k].x, p->tonecurve[ch][k].y);
  }
  else
  {
    for(int k=0; k<p->tonecurve_nodes[ch]; k++)
      dt_draw_curve_set_point(c->minmax_curve[ch], k, p->tonecurve[ch][k].x, p->tonecurve[ch][k].y);
  }
  dt_draw_curve_t *minmax_curve = c->minmax_curve[ch];
  dt_draw_curve_calc_values(minmax_curve, 0.0, 1.0, DT_IOP_TONECURVE_RES, c->draw_xs, c->draw_ys);

  const float xm = tonecurve[nodes-1].x;
  const float x[4] = {0.7f*xm, 0.8f*xm, 0.9f*xm, 1.0f*xm};
  const float y[4] = {c->draw_ys[CLAMP((int)(x[0]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)],
                      c->draw_ys[CLAMP((int)(x[1]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)],
                      c->draw_ys[CLAMP((int)(x[2]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)],
                      c->draw_ys[CLAMP((int)(x[3]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)]
                     };
  float unbounded_coeffs[3];
  dt_iop_estimate_exp(x, y, 4, unbounded_coeffs);

  const int inset = DT_GUI_CURVE_EDITOR_INSET;
  int width = widget->allocation.width, height = widget->allocation.height;
  cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *cr = cairo_create(cst);
  // clear bg
  cairo_set_source_rgb (cr, .2, .2, .2);
  cairo_paint(cr);

  cairo_translate(cr, inset, inset);
  width -= 2*inset;
  height -= 2*inset;

#if 0
  // draw shadow around
  float alpha = 1.0f;
  for(int k=0; k<inset; k++)
  {
    cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k);
    cairo_set_source_rgba(cr, 0, 0, 0, alpha);
    alpha *= 0.6f;
    cairo_fill(cr);
  }
#else
  cairo_set_line_width(cr, 1.0);
  cairo_set_source_rgb (cr, .1, .1, .1);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_stroke(cr);
#endif

  cairo_set_source_rgb (cr, .3, .3, .3);
  cairo_rectangle(cr, 0, 0, width, height);
  cairo_fill(cr);

  // draw color labels
  const int cells = 8;
  for(int j=0; j<cells; j++)
  {
    for(int i=0; i<cells; i++)
    {
      const float f = (cells-1-j+i)/(2.0f*cells-2.0f);
      cairo_set_source_rgba (cr,
                             (1.0f-f)*color_labels_left[ch][0] + f*color_labels_right[ch][0],
                             (1.0f-f)*color_labels_left[ch][1] + f*color_labels_right[ch][1],
                             (1.0f-f)*color_labels_left[ch][2] + f*color_labels_right[ch][2],
                             .5f); // blend over to make colors darker, so the overlay is more visible
      cairo_rectangle(cr, width*i/(float)cells, height*j/(float)cells, width/(float)cells, height/(float)cells);
      cairo_fill(cr);
    }
  }

  // draw grid
  cairo_set_line_width(cr, .4);
  cairo_set_source_rgb (cr, .1, .1, .1);
  if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM)
    dt_draw_waveform_lines(cr, 0, 0, width, height);
  else
  dt_draw_grid(cr, 4, 0, 0, width, height);

  // if autoscale_ab is on: do not display a and b curves
  if (autoscale_ab && ch != ch_L) goto finally;

  // draw nodes positions
  cairo_set_line_width(cr, 1.);
  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
  cairo_translate(cr, 0, height);

  for(int k=0; k<nodes; k++)
  {
    cairo_arc(cr, tonecurve[k].x*width, -tonecurve[k].y*height, 3, 0, 2.*M_PI);
    cairo_stroke(cr);
  }

  // draw selected cursor
  cairo_set_line_width(cr, 1.);

  // draw histogram in background
  // only if module is enabled
  if (self->enabled)
  {
    float *hist, hist_max;
    float *raw_mean, *raw_min, *raw_max;
    float *raw_mean_output;
    float picker_mean[3], picker_min[3], picker_max[3];
    char text[256];

    raw_mean = self->picked_color;
    raw_min = self->picked_color_min;
    raw_max = self->picked_color_max;
    raw_mean_output = self->picked_output_color;

    hist = self->histogram;
    hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR?self->histogram_max[ch]:logf(1.0 + self->histogram_max[ch]);
    if(hist && hist_max > 0)
    {
      cairo_save(cr);
      cairo_scale(cr, width/63.0, -(height-5)/(float)hist_max);
      cairo_set_source_rgba(cr, .2, .2, .2, 0.5);
      dt_draw_histogram_8(cr, hist, ch, dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM?DT_DEV_HISTOGRAM_LOGARITHMIC:dev->histogram_type); // TODO: make draw handle waveform histograms
      cairo_restore(cr);
    }

    if(self->request_color_pick)
    {
      // the global live samples ...
      GSList *samples = darktable.lib->proxy.colorpicker.live_samples;
      dt_colorpicker_sample_t *sample = NULL;
      while(samples)
      {
        sample = samples->data;

        picker_scale(sample->picked_color_lab_mean, picker_mean);
        picker_scale(sample->picked_color_lab_min, picker_min);
        picker_scale(sample->picked_color_lab_max, picker_max);

        cairo_set_source_rgba(cr, 0.5, 0.7, 0.5, 0.15);
        cairo_rectangle(cr, width*picker_min[ch], 0, width*fmax(picker_max[ch]-picker_min[ch], 0.0f), -height);
        cairo_fill(cr);
        cairo_set_source_rgba(cr, 0.5, 0.7, 0.5, 0.5);
        cairo_move_to(cr, width*picker_mean[ch], 0);
        cairo_line_to(cr, width*picker_mean[ch], -height);
        cairo_stroke(cr);

        samples = g_slist_next(samples);
      }

      // ... and the local sample
      if(raw_max[0] >= 0.0f)
      {
        picker_scale(raw_mean, picker_mean);
        picker_scale(raw_min, picker_min);
        picker_scale(raw_max, picker_max);

        cairo_set_source_rgba(cr, 0.7, 0.5, 0.5, 0.33);
        cairo_rectangle(cr, width*picker_min[ch], 0, width*fmax(picker_max[ch]-picker_min[ch], 0.0f), -height);
        cairo_fill(cr);
        cairo_set_source_rgba(cr, 0.9, 0.7, 0.7, 0.5);
        cairo_move_to(cr, width*picker_mean[ch], 0);
        cairo_line_to(cr, width*picker_mean[ch], -height);
        cairo_stroke(cr);

        snprintf(text, 256, "%.1f → %.1f", raw_mean[ch], raw_mean_output[ch]);

        cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
        cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size (cr, 0.06*height);
        cairo_move_to (cr, 0.02f*width, -0.94*height);
        cairo_show_text(cr, text);
        cairo_stroke(cr);
      }
    }
  }

  if(c->selected >= 0)
  {
    cairo_set_source_rgb(cr, .9, .9, .9);
    cairo_arc(cr, tonecurve[c->selected].x*width, -tonecurve[c->selected].y*height, 4, 0, 2.*M_PI);
    cairo_stroke(cr);
  }

  // draw curve
  cairo_set_line_width(cr, 2.);
  cairo_set_source_rgb(cr, .9, .9, .9);
  // cairo_set_line_cap  (cr, CAIRO_LINE_CAP_SQUARE);
  cairo_move_to(cr, 0, -height*c->draw_ys[0]);
  for(int k=1; k<DT_IOP_TONECURVE_RES; k++)
  {
    const float xx = k/(DT_IOP_TONECURVE_RES-1.0);
    if(xx > xm)
    {
      const float yy = dt_iop_eval_exp(unbounded_coeffs, xx);
      cairo_line_to(cr, xx*width, - height*yy);
    }
    else
    {
      cairo_line_to(cr, xx*width, - height*c->draw_ys[k]);
    }
  }
  cairo_stroke(cr);

finally:
  cairo_destroy(cr);
  cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget));
  cairo_set_source_surface (cr_pixmap, cst, 0, 0);
  cairo_paint(cr_pixmap);
  cairo_destroy(cr_pixmap);
  cairo_surface_destroy(cst);
  return TRUE;
}
Beispiel #23
0
void gui_screen_t::paint() {

	g_create_thread((void*) blinkCursorThread);

	int padding = 5;
	while (true) {
		auto windowBounds = window->getBounds();
		canvas->setBounds(g_rectangle(0, 0, windowBounds.width, windowBounds.height));

		auto cr = getGraphics();
		if (cr == 0) {
			g_sleep(100);
			continue;
		}

		// clear
		cairo_save(cr);
		cairo_set_source_rgba(cr, 0, 0, 0, 1);
		cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
		cairo_paint(cr);
		cairo_restore(cr);

		// relayout text
		g_text_layouter::getInstance()->layout(cr, output.c_str(), font, 14,
				g_rectangle(padding, padding, windowBounds.width - 2 * padding - 20, windowBounds.height - 2 * padding), g_text_alignment::LEFT, viewModel,
				true);

		// check which is the lowest-down-the-screen character
		int highesty = 0;
		for (g_positioned_glyph& g : viewModel->positions) {
			int ypos = g.position.y - g.glyph->y;
			if (ypos > highesty) {
				highesty = ypos;
			}
		}

		// calculate limit
		int yLimit = windowBounds.height - 60;
		int yOffset = 0;
		if (highesty > yLimit) {
			yOffset = yLimit - highesty;
		}

		// paint characters
		g_point last;
		cairo_set_source_rgba(cr, 1, 1, 1, 1);
		for (g_positioned_glyph& g : viewModel->positions) {
			last = g.position;

			cairo_save(cr);
			cairo_translate(cr, g.position.x - g.glyph->x, yOffset + g.position.y - g.glyph->y);
			cairo_glyph_path(cr, g.glyph, g.glyph_count);
			cairo_fill(cr);
			cairo_restore(cr);
		}

		// paint cursor
		if (focused) {
			if ((g_millis() - lastInput < 300) || cursorBlink) {
				cairo_save(cr);
				cairo_set_source_rgba(cr, 1, 1, 1, 1);
				cairo_rectangle(cr, last.x + 10, yOffset + last.y - 12, 8, 14);
				cairo_fill(cr);
				cairo_restore(cr);
			}
		}

		canvas->blit(g_rectangle(0, 0, bufferSize.width, bufferSize.height));

		paint_uptodate = true;
		g_atomic_block(&paint_uptodate);
	}
}
static void
draw_shadow_box (cairo_t *cr, GdkRectangle rect, int left_border, int right_border,
                 int bottom_border, double inner_alpha)
{
  cairo_pattern_t *pattern;
  cairo_matrix_t matrix;
  double x0, x1, x2, x3;
  double y0, y2, y3;

  cairo_save (cr);

  x0 = rect.x;
  x1 = rect.x + left_border;
  x2 = rect.x + rect.width - right_border;
  x3 = rect.x + rect.width;

  y0 = rect.y;
  y2 = rect.y + rect.height - bottom_border;
  y3 = rect.y + rect.height;

  /* Bottom border */

  pattern = cairo_pattern_create_linear(0, y2, 0, y3);

  cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, inner_alpha);
  cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, 0.0);

  cairo_set_source(cr, pattern);
  cairo_pattern_destroy(pattern);

  cairo_rectangle(cr, x1, y2, x2 - x1, y3 - y2);
  cairo_fill(cr);

  /* Left border */

  pattern = cairo_pattern_create_linear(x0, 0, x1, 0);

  cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, 0.0);
  cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, inner_alpha);

  cairo_set_source(cr, pattern);
  cairo_pattern_destroy(pattern);

  cairo_rectangle(cr, x0, y0, x1 - x0, y2 - y0);
  cairo_fill(cr);

  /* Right border */

  pattern = cairo_pattern_create_linear(x2, 0, x3, 0);

  cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, inner_alpha);
  cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, 0.0);

  cairo_set_source(cr, pattern);
  cairo_pattern_destroy(pattern);

  cairo_rectangle(cr, x2, y0, x3 - x2, y2 - y0);
  cairo_fill(cr);

  /* SW corner */

  pattern = cairo_pattern_create_radial(0, 0, 0, 0.0, 0, 1.0);
  cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0, 0, 0, inner_alpha);
  cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0, 0, 0, 0.0);

  cairo_matrix_init_scale (&matrix, 1.0 / left_border, 1.0 / bottom_border);
  cairo_matrix_translate (&matrix, - x1, -y2);
  cairo_pattern_set_matrix (pattern, &matrix);

  cairo_set_source(cr, pattern);
  cairo_pattern_destroy(pattern);

  cairo_rectangle(cr, x0, y2, x1 - x0, y3 - y2);
  cairo_fill(cr);

  /* SE corner */

  pattern = cairo_pattern_create_radial(0, 0, 0, 0, 0, 1.0);
  cairo_pattern_add_color_stop_rgba(pattern, 0.0, 0.0, 0, 0, inner_alpha);
  cairo_pattern_add_color_stop_rgba(pattern, 1.0, 0.0, 0, 0, 0.0);

  cairo_matrix_init_scale (&matrix, 1.0 / left_border, 1.0 / bottom_border);
  cairo_matrix_translate (&matrix, - x2, -y2);
  cairo_pattern_set_matrix (pattern, &matrix);

  cairo_set_source(cr, pattern);
  cairo_pattern_destroy(pattern);

  cairo_rectangle(cr, x2, y2, x3 - x2, y3 - y2);
  cairo_fill(cr);

  cairo_restore (cr);
}
static void
draw (cairo_t *cr, double width, double height)
{
    const char *text = "cairo";
    cairo_text_extents_t extents;
    const double dash[2] = { 8, 16 };
    cairo_pattern_t *pattern;

    cairo_save (cr);

    cairo_new_path (cr);

    cairo_set_line_width (cr, .05 * SIZE / 2.0);

    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.875 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_stroke (cr);

    /* use dashes to demonstrate bugs:
     *  https://bugs.freedesktop.org/show_bug.cgi?id=9189
     *  https://bugs.freedesktop.org/show_bug.cgi?id=17223
     */
    cairo_save (cr);
    cairo_set_dash (cr, dash, 2, 0);
    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.75 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_stroke (cr);
    cairo_restore (cr);

    cairo_save (cr);
    cairo_rectangle (cr, 0, 0, SIZE/2, SIZE);
    cairo_clip (cr);
    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.6 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_fill (cr);
    cairo_restore (cr);

    /* use a pattern to exercise bug:
     *   https://bugs.launchpad.net/inkscape/+bug/234546
     */
    cairo_save (cr);
    cairo_rectangle (cr, SIZE/2, 0, SIZE/2, SIZE);
    cairo_clip (cr);
    pattern = cairo_pattern_create_linear (SIZE/2, 0, SIZE, 0);
    cairo_pattern_add_color_stop_rgba (pattern, 0, 0, 0, 0, 1.);
    cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0, 0.);
    cairo_set_source (cr, pattern);
    cairo_pattern_destroy (pattern);
    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.6 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_fill (cr);
    cairo_restore (cr);

    cairo_set_source_rgb (cr, 1, 1, 1); /* white */
    cairo_set_font_size (cr, .25 * SIZE / 2.0);
    cairo_text_extents (cr, text, &extents);
    cairo_move_to (cr, (SIZE-extents.width)/2.0-extents.x_bearing,
		       (SIZE-extents.height)/2.0-extents.y_bearing);
    cairo_show_text (cr, text);

    cairo_restore (cr);
}
static void
gimp_display_shell_canvas_draw_image (GimpDisplayShell *shell,
                                      cairo_t          *cr)
{
  cairo_rectangle_list_t *clip_rectangles;
  cairo_rectangle_int_t   image_rect;

  image_rect.x = - shell->offset_x;
  image_rect.y = - shell->offset_y;
  gimp_display_shell_scale_get_image_size (shell,
                                           &image_rect.width,
                                           &image_rect.height);


  /*  first, clear the exposed part of the region that is outside the
   *  image, which is the exposed region minus the image rectangle
   */

  cairo_save (cr);

  if (shell->rotate_transform)
    cairo_transform (cr, shell->rotate_transform);

  cairo_rectangle (cr,
                   image_rect.x,
                   image_rect.y,
                   image_rect.width,
                   image_rect.height);

  cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_clip (cr);

  if (gdk_cairo_get_clip_rectangle (cr, NULL))
    gimp_display_shell_draw_background (shell, cr);

  cairo_restore (cr);


  /*  then, draw the exposed part of the region that is inside the
   *  image
   */

  cairo_save (cr);
  clip_rectangles = cairo_copy_clip_rectangle_list (cr);

  if (shell->rotate_transform)
    cairo_transform (cr, shell->rotate_transform);

  cairo_rectangle (cr,
                   image_rect.x,
                   image_rect.y,
                   image_rect.width,
                   image_rect.height);
  cairo_clip (cr);

  if (gdk_cairo_get_clip_rectangle (cr, NULL))
    {
      gint i;

      cairo_save (cr);
      gimp_display_shell_draw_checkerboard (shell, cr);
      cairo_restore (cr);

      for (i = 0; i < clip_rectangles->num_rectangles; i++)
        {
          cairo_rectangle_t rect = clip_rectangles->rectangles[i];

          gimp_display_shell_draw_image (shell, cr,
                                         floor (rect.x),
                                         floor (rect.y),
                                         ceil (rect.width),
                                         ceil (rect.height));
        }
    }

  cairo_rectangle_list_destroy (clip_rectangles);
  cairo_restore (cr);


  /*  finally, draw all the remaining image window stuff on top
   */

  /* draw canvas items */
  cairo_save (cr);

  if (shell->rotate_transform)
    cairo_transform (cr, shell->rotate_transform);

  gimp_canvas_item_draw (shell->canvas_item, cr);

  cairo_restore (cr);

  gimp_canvas_item_draw (shell->unrotated_item, cr);

  /* restart (and recalculate) the selection boundaries */
  gimp_display_shell_selection_restart (shell);
}
void cd_switcher_draw_main_icon_expanded_mode (void)
{
	// apply the desktop bg or the user image on the main icon, in dock mode
	int iWidth, iHeight;
	
	if (myDock)
	{
		CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
		myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
		myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.

		cairo_surface_t *pSurface = NULL;
		double fZoomX, fZoomY;
		if (myConfig.iIconDrawing == SWICTHER_MAP_WALLPAPER)
		{
			cairo_dock_erase_cairo_context (myDrawContext);

			pSurface = myData.pDesktopBgMapSurface;
			fZoomX = 1. * iWidth / myData.iSurfaceWidth;
			fZoomY= 1. * iHeight / myData.iSurfaceHeight;
			cairo_translate (myDrawContext,
				0.,
				0.);

			cairo_save (myDrawContext);
			cairo_scale (myDrawContext,
				fZoomX ,
				fZoomY );
			cairo_set_source_surface (myDrawContext,
				pSurface,
				0.,
				0.);
			cairo_paint(myDrawContext);
			cairo_restore (myDrawContext);

			if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
				cairo_dock_update_icon_texture (myIcon);
		}
		else
		{
			CD_APPLET_SET_IMAGE_ON_MY_ICON (MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
		}
	}
	
	if (myConfig.bDrawWindows)
	{
		GList *pWindowList = cairo_dock_get_current_applis_list ();
		pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
		
		CDSwitcherDesktop data;
		int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
		cairo_t *pCairoContext;
		Icon *pIcon;
		GList *pIconsList = CD_APPLET_MY_ICONS_LIST;
		GList *ic;
		for (ic = pIconsList; ic != NULL; ic = ic->next)
		{
			pIcon = ic->data;
			cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
			
			pCairoContext = cairo_create (pIcon->image.pSurface);
			cairo_set_line_width (pCairoContext, 1.);
			if (myConfig.bUseDefaultColors)
				gldi_style_colors_set_line_color (myDrawContext);
			else
				cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
			
			data.iNumDesktop = iNumDesktop;
			data.iNumViewportX = iNumViewportX;
			data.iNumViewportY = iNumViewportY;
			data.iOneViewportWidth = iWidth;
			data.iOneViewportHeight = iHeight;
			data.pCairoContext = pCairoContext;
			g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, &data);
			
			iNumViewportX ++;
			if (iNumViewportX == g_desktopGeometry.iNbViewportX)
			{
				iNumViewportY ++;
				if (iNumViewportY == g_desktopGeometry.iNbViewportY)
					iNumDesktop ++;
			}
			cairo_destroy (pCairoContext);
		}
		g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
	}
}
Beispiel #28
0
void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color)
{
    if (paintingDisabled())
        return;

    unsigned rectCount = rects.size();

    cairo_t* cr = platformContext()->cr();
    cairo_save(cr);
    cairo_push_group(cr);
    cairo_new_path(cr);

#if PLATFORM(GTK)
#ifdef GTK_API_VERSION_2
    GdkRegion* reg = gdk_region_new();
#else
    cairo_region_t* reg = cairo_region_create();
#endif

    for (unsigned i = 0; i < rectCount; i++) {
#ifdef GTK_API_VERSION_2
        GdkRectangle rect = rects[i];
        gdk_region_union_with_rect(reg, &rect);
#else
        cairo_rectangle_int_t rect = rects[i];
        cairo_region_union_rectangle(reg, &rect);
#endif
    }
    gdk_cairo_region(cr, reg);
#ifdef GTK_API_VERSION_2
    gdk_region_destroy(reg);
#else
    cairo_region_destroy(reg);
#endif
#else
    int radius = (width - 1) / 2;
    Path path;
    for (unsigned i = 0; i < rectCount; ++i) {
        if (i > 0)
            path.clear();
        path.addRoundedRect(rects[i], FloatSize(radius, radius));
        appendWebCorePathToCairoContext(cr, path);
    }
#endif
    Color ringColor = color;
    adjustFocusRingColor(ringColor);
    adjustFocusRingLineWidth(width);
    setSourceRGBAFromColor(cr, ringColor);
    cairo_set_line_width(cr, width);
    setPlatformStrokeStyle(focusRingStrokeStyle());

    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_stroke_preserve(cr);

    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
    cairo_fill(cr);

    cairo_pop_group_to_source(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_paint(cr);
    cairo_restore(cr);
}
/*
void layout_paint(GtkWidget *widget,
                  cairo_t   *cr,
                  GtkRange  *range)
*/
extern gboolean 
layout_expose(GtkWidget *widget,
              GdkEventExpose *event,
              Score_t *score)
{
        cairo_t *cr = gdk_cairo_create(widget->window);

        GList * listrunner_staff = NULL;
        GList * listrunner_object = NULL;

        gint width, height;
        gint i;


        g_assert( score );

        width  = widget->allocation.width;
        height = widget->allocation.height;

        /*
	 * enclosing the painting function in a save/restore pair is a
         * good idea since we'll return to a sane state then
         */

        cairo_save (cr);

        /* clear background */

        cairo_rectangle (cr, 0, 0, width, height);
        cairo_set_source_rgb (cr, 1,1,1);
        cairo_fill (cr);


        /* enclosing in a save/restore pair since we alter the
         * font size
         */
        cairo_save (cr);


        /***************
         * Draw Staves *
         ***************/
        /* We walk through staves */
        listrunner_staff = g_list_first(score->Staff_list);
        while ( listrunner_staff ) {
                measure_number = 1;

                Staff_t *staff;
                staff = (Staff_t *)listrunner_staff->data;

                object_x = staff->extremity_begin_x + Spacings.Clefs.sb + (score->zoom * TREBLE_CLEF_WIDTH_FACTOR) + Spacings.Clefs.sa + get_key_signature_spacing(score, staff) + Spacings.KeySignatures.saks + Spacings.TimeSignatures.width + Spacings.TimeSignatures.sats;

                draw_staff(score, cr, 
                           staff->nb_lines, staff->space_btw_lines,
                           staff->extremity_begin_x, staff->extremity_begin_y,
                           score->staff_extremity_end_x, staff->is_selected);
                
/*                 if ( display->clefs ) */
                        draw_key(score, staff, cr, FALSE);

/*                 if ( display->key_signature ) */
                        draw_key_signature(score, staff, cr, FALSE);

/*                 if ( display->time_signature ) */
                        draw_time_signature(score, staff, cr, FALSE);

		listrunner_object = g_list_first(staff->Object_list);
 		while ( listrunner_object ) { 
 			Object_t *object = NULL;
 			object = (Object_t *)listrunner_object->data;

/*                         g_print("object->pitch = %d \n", object->pitch); */
/*                         g_print("%s:%d: x = %f\n", __FILE__, __LINE__, object_x); */
			
			if (object) {

                                draw_staff_extension(score, staff, cr, object->pitch, object_x);
/*                                 g_print("layout engine, object_type = %d\n", object->type); */

				switch(object->type) {

				case PITCH_CURSOR:
					object_x = draw_pitch_cursor(score, staff, cr, object_x, object->pitch);
				        break;
                                case BARLINE_SINGLE:
                                        object_x = draw_barline_single(score, staff, object, cr, object_x);
                                        break;
				case DOUBLEWHOLE:
                                case DOUBLEWHOLEREST:
				case WHOLE:
                                case WHOLEREST:
				case HALF:
                                case HALFREST:
				case QUARTER:
                                case QUARTERREST:
				case EIGHTH:
                                case EIGHTHREST:
				case SIXTEENTH:
                                case SIXTEENTHREST:
                                        object_x = draw_note_rest(score, staff, object, cr, object_x);
					break;
                                default:
                                        g_print("Unknown object type: %d\n", object->type);

				}
			}
			
			listrunner_object = g_list_next(listrunner_object);
		}
		
                listrunner_staff = g_list_next(listrunner_staff);
        } /* while ( listrunner_staff ) */


        cairo_set_source_rgb (cr, 0, 0, 0);

        /* Show the quarter note head */
/*         cairo_select_font (cr, "gscore", CAIRO_FONT_SLANT_NORMAL, */
/*                            CAIRO_FONT_WEIGHT_BOLD); */
/*         cairo_save (cr); */
/*         cairo_scale_font (cr, 30); */
/*         cairo_move_to (cr, 100.5, 54); */
/*         cairo_set_rgb_color (cr, 0,0,0); */
/*         cairo_show_text (cr, QUARTER_GLYPH); */

        /* Show the stem */
        /* Line */
/*         cairo_move_to(cr, 100.5, 54); */
/*         cairo_rel_line_to(cr, 0, 30.5); */
/*         cairo_stroke(cr); */
/*         /\* Sixteenth *\/ */
/*         cairo_move_to (cr, 101, 84.5); */
/*         cairo_show_text (cr, SIXTEENTH_STEM_DOWN_GLYPH); */


/*         /\* Add a sharp to the note *\/ */
/*         cairo_move_to (cr, 90, 54); */
/*         cairo_scale_font (cr, 1); */
/*         cairo_set_rgb_color (cr, 0,0,0); */
/*         cairo_show_text (cr, SHARP_GLYPH); */
/*         cairo_stroke(cr); */

/*         /\* Show the key *\/ */
/*         cairo_move_to (cr, 15.5, 75); */
/*         cairo_scale_font (cr, 1); */
/*         cairo_set_rgb_color (cr, 0,0,0); */
/*         cairo_show_text (cr, TREBLE_GLYPH); */
/*         cairo_stroke(cr); */

/*         /\* Add 2/4 *\/ */
/*         cairo_move_to (cr, 40, 66.5); */
/*         cairo_scale_font (cr, 0.5); */
/*         cairo_show_text (cr, "2"); */

/*         cairo_move_to (cr, 40, 82.5); */
/*         cairo_show_text (cr, "4"); */


/*         cairo_restore (cr); */

/*         cairo_set_rgb_color (cr, 1,0,0); */
/*         cairo_scale_font (cr, 15); */
/*         cairo_move_to (cr, 50, 100); */


        cairo_stroke (cr);

        cairo_restore (cr);

        selection_paint(cr, score);
}
Beispiel #30
0
void DatabaseTask::Run()
{
  while (true) {
    mutex.Lock();

    while (newJob==NULL && !finish) {
      condition.Wait(mutex);
    }

    if (finish) {
      mutex.Unlock();
      return;
    }

    if (newJob!=NULL) {
      currentJob=newJob;
      newJob=NULL;
    }

    mutex.Unlock();

    if (currentJob!=NULL) {
      if (currentSurface==NULL ||
          currentWidth!=currentJob->width ||
          currentHeight!=currentJob->height) {
        cairo_destroy(currentCairo);
        cairo_surface_destroy(currentSurface);

        currentWidth=currentJob->width;
        currentHeight=currentJob->height;

        currentSurface=cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                                  currentWidth,currentHeight);
        currentCairo=cairo_create(currentSurface);
      }

      currentLon=currentJob->lon;
      currentLat=currentJob->lat;
      currentMagnification=currentJob->magnification;

      if (database->IsOpen() &&
          styleConfig!=NULL) {
        osmscout::MercatorProjection  projection;
        osmscout::MapParameter        drawParameter;
        osmscout::AreaSearchParameter searchParameter;

        std::list<std::string>        paths;

        paths.push_back("../libosmscout/data/icons/14x14/standard/");

        searchParameter.SetMaximumNodes(maxNodes->Get());
        searchParameter.SetMaximumWays(maxWays->Get());
        searchParameter.SetMaximumAreas(maxAreas->Get());

        searchParameter.SetUseLowZoomOptimization(true);
        searchParameter.SetUseMultithreading(currentMagnification.GetMagnification()<=osmscout::Magnification::magCity);

        drawParameter.SetIconPaths(paths);
        drawParameter.SetPatternPaths(paths);

        drawParameter.SetOptimizeWayNodes(optimizeWays->Get() ? osmscout::TransPolygon::quality : osmscout::TransPolygon::none);
        drawParameter.SetOptimizeAreaNodes(optimizeAreas->Get() ? osmscout::TransPolygon::quality : osmscout::TransPolygon::none);

        drawParameter.SetDrawWaysWithFixedWidth(false);

        drawParameter.SetRenderSeaLand(true);

        drawParameter.SetDebugPerformance(true);

        if (!dpi->IsNull()) {
          drawParameter.SetDPI(dpi->GetDouble());
        }
        else {
          drawParameter.SetDPI(Lum::OS::display->GetDPI());
        }

        std::cout << std::endl;

        osmscout::StopClock overallTimer;

        projection.Set(currentLon,
                       currentLat,
                       currentMagnification,
                       currentWidth,
                       currentHeight);
/*
        double width=10*drawParameter.GetDPI()/25.4;
        std::cout << "10mm => " << width << std::endl;
        double areaMinDegree=width/currentWidth*(projection.GetLonMax()-projection.GetLonMin());

        size_t level=0;
        double levelDegree=360.0;

        std::cout << "Minimum area degree: " << areaMinDegree << std::endl;
        while (areaMinDegree<levelDegree) {
          levelDegree=levelDegree/2;
          level++;
        }

        level=level-1;


        //searchParameter.SetMaximumAreaLevel(level-log2(currentMagnification));

        std::cout << "Resulting max area level: " << level-log2(currentMagnification) << " <=> " << searchParameter.GetMaximumAreaLevel() << std::endl;
*/

        osmscout::TypeSet              nodeTypes;
        std::vector<osmscout::TypeSet> wayTypes;
        osmscout::TypeSet              areaTypes;

        try {
          styleConfig->GetNodeTypesWithMaxMag(projection.GetMagnification(),
                                              nodeTypes);

          styleConfig->GetWayTypesByPrioWithMaxMag(projection.GetMagnification(),
                                                   wayTypes);
        }
        catch (std::exception& e) {
          std::cerr << "Exception while fetching style data: " << e.what() << std::endl;
        }

          styleConfig->GetAreaTypesWithMaxMag(projection.GetMagnification(),
                                              areaTypes);

        osmscout::StopClock dataRetrievalTimer;

        database->GetObjects(nodeTypes,
                             wayTypes,
                             areaTypes,
                             projection.GetLonMin(),
                             projection.GetLatMin(),
                             projection.GetLonMax(),
                             projection.GetLatMax(),
                             projection.GetMagnification(),
                             searchParameter,
                             data.nodes,
                             data.ways,
                             data.areas);

        if (drawParameter.GetRenderSeaLand()) {
          database->GetGroundTiles(projection.GetLonMin(),
                                   projection.GetLatMin(),
                                   projection.GetLonMax(),
                                   projection.GetLatMax(),
                                   projection.GetMagnification(),
                                   data.groundTiles);
        }

        dataRetrievalTimer.Stop();

        osmscout::StopClock drawTimer;

        cairo_set_tolerance(currentCairo,0.7);

        try {
          painter.DrawMap(*styleConfig,
                          projection,
                          drawParameter,
                          data,
                          currentCairo);

          drawTimer.Stop();
          overallTimer.Stop();

          std::cout << "All: " << overallTimer << " Data: " << dataRetrievalTimer << " Draw: " << drawTimer << std::endl;
        }
        catch (std::exception& e) {
          std::cerr << "Exception while rendering: " << e.what() << std::endl;
        }
      }
      else {
        std::cout << "Cannot draw map: " << database->IsOpen() << " " << (styleConfig!=NULL) << std::endl;
        cairo_save(currentCairo);
        cairo_set_source_rgb(currentCairo,0,0,0);
        cairo_paint(currentCairo);
        cairo_restore(currentCairo);
      }

      mutex.Lock();

      if (finishedJob!=NULL) {
        delete finishedJob;
      }

      finishedJob=currentJob;
      currentJob=NULL;

      std::swap(currentSurface,finishedSurface);
      std::swap(currentCairo,finishedCairo);
      std::swap(currentWidth,finishedWidth);
      std::swap(currentHeight,finishedHeight);
      std::swap(currentLon,finishedLon);
      std::swap(currentLat,finishedLat);
      std::swap(currentMagnification,finishedMagnification);

      Lum::OS::display->QueueActionForAsyncNotification(jobFinishedAction);

      mutex.Unlock();
    }
  }
}