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, >k_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; }
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); } }
static PyObject * pycairo_restore (PycairoContext *o) { cairo_restore (o->ctx); RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); Py_RETURN_NONE; }
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); } }
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; }
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" }
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); }
void hippo_canvas_item_pop_cairo (HippoCanvasItem *item, cairo_t *cr) { cairo_restore(cr); }
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 }
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; }
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; }
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); }
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); }
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; }
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; }
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; }
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. } }
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); }
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(); } } }