static gboolean _button_draw(GtkWidget *widget, cairo_t *cr) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_BUTTON(widget), FALSE); GtkStateFlags state = gtk_widget_get_state_flags(widget); GdkRGBA bg_color, fg_color; GtkStyleContext *context = gtk_widget_get_style_context(widget); gtk_style_context_get_background_color(context, state, &bg_color); gtk_style_context_get_color(context, state, &fg_color); /* update paint flags depending of states */ int flags = DTGTK_BUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* prelight */ if(state & GTK_STATE_FLAG_PRELIGHT) flags |= CPF_PRELIGHT; else flags &= ~CPF_PRELIGHT; /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = gtk_widget_create_pango_layout(widget, NULL); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } /* begin cairo drawing */ GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent */ if((flags & CPF_STYLE_FLAT)) { if(flags & CPF_PRELIGHT) { cairo_rectangle(cr, 0, 0, width, height); gdk_cairo_set_source_rgba(cr, &bg_color); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { /* draw default boxed button */ gtk_render_background(context, cr, 0, 0, width, height); if(!(flags & CPF_DO_NOT_USE_BORDER)) gtk_render_frame(context, cr, 0, 0, width, height); } gdk_cairo_set_source_rgba(cr, &fg_color); /* draw icon */ if(DTGTK_BUTTON(widget)->icon) { int icon_width = text ? height - (border * 2) : width - (border * 2); int icon_height = height - (border * 2); if(icon_width > 0 && icon_height > 0) { if(text) DTGTK_BUTTON(widget) ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags); else DTGTK_BUTTON(widget) ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags); } } /* draw label */ if(text) { int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0)); if(DTGTK_BUTTON(widget)->icon) lx += width; cairo_move_to(cr, lx, ly); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } return FALSE; }
void draw_rectangles(cairo_t *fbcr, struct tsdev *ts, cairo_linuxfb_device_t *device) { int bufid = 1; /* start drawing into second buffer */ float r, g, b; int fbsizex = device->fb_vinfo.xres; int fbsizey = device->fb_vinfo.yres; int startx, starty, sizex, sizey; struct ts_sample sample; cairo_surface_t *surface; cairo_t *cr; float scale = 1.0f; surface = cairo_image_surface_create(CAIRO_FORMAT_RGB16_565, fbsizex, fbsizey); cr = cairo_create(surface); /* * We clear the cairo surface here before drawing * This is required in case something was drawn on this surface * previously, the previous contents would not be cleared without this. */ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); srand(time(NULL)); while (!cancel) { r = (rand() % 100) / 100.0; g = (rand() % 100) / 100.0; b = (rand() % 100) / 100.0; startx = rand() % fbsizex; starty = rand() % fbsizey; sizex = rand() % (fbsizex - startx); sizey = rand() % (fbsizey - starty); cairo_identity_matrix(cr); if (ts) { int pressed = 0; /* Pressure is our identication whether we act on axis... */ while (ts_read(ts, &sample, 1)) { if (sample.pressure > 0) pressed = 1; } if (pressed) { scale *= 1.05f; cairo_translate(cr, sample.x, sample.y); cairo_scale(cr, scale, scale); //r = g = b = 0; startx = -5; starty = -5; sizex = 10; sizey = 10; } else { scale = 1.0f; } } cairo_set_source_rgb(cr, r, g, b); cairo_rectangle(cr, startx, starty, sizex, sizey); cairo_stroke_preserve(cr); cairo_fill(cr); /* Draw to framebuffer at y offset according to current buffer.. */ cairo_set_source_surface(fbcr, surface, 0, bufid * fbsizey); cairo_paint(fbcr); flip_buffer(device, 1, bufid); /* Switch buffer ID for next draw */ bufid = !bufid; usleep(20000); } /* Make sure we leave with buffer 0 enabled */ flip_buffer(device, 1, 0); /* Destroy and release all cairo related contexts */ cairo_destroy(cr); cairo_surface_destroy(surface); }
/** * ppg_ruler_draw_arrow: * @ruler: (in): A #PpgRuler. * * Draw the arrow to a pixmap for rendering on top of the background. * * Returns: None. * Side effects: None. */ static void ppg_ruler_draw_arrow (PpgRuler *ruler) { PpgRulerPrivate *priv; GtkStyle *style; GdkColor base_light; GdkColor base_dark; GdkColor hl_light; cairo_t *cr; gint half; gint line_width; gint center; gint middle; gdouble top; gdouble bottom; gdouble left; gdouble right; g_return_if_fail(PPG_IS_RULER(ruler)); priv = ruler->priv; style = gtk_widget_get_style(GTK_WIDGET(ruler)); cr = cairo_create(priv->arrow); cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr, 0, 0, ARROW_SIZE, ARROW_SIZE); cairo_fill(cr); cairo_restore(cr); center = middle = half = ARROW_SIZE / 2; line_width = half / 6; base_light = style->light[GTK_STATE_SELECTED]; base_dark = style->dark[GTK_STATE_SELECTED]; hl_light = style->light[GTK_STATE_SELECTED]; top = middle - half + line_width + 0.5; bottom = middle + half - line_width + 0.5; left = center - half + line_width + 0.5; right = center +half - line_width - 0.5; cairo_set_line_width(cr, line_width); cairo_move_to(cr, left + line_width, top + line_width); cairo_line_to(cr, right + line_width, top + line_width); cairo_line_to(cr, right + line_width, middle + line_width); cairo_line_to(cr, center + line_width, bottom + line_width); cairo_line_to(cr, left + line_width, middle + line_width); cairo_line_to(cr, left + line_width, top + line_width); cairo_close_path(cr); cairo_set_source_rgba(cr, 0, 0, 0, 0.5); cairo_fill(cr); cairo_move_to(cr, left, top); cairo_line_to(cr, center, top); cairo_line_to(cr, center, bottom); cairo_line_to(cr, left, middle); cairo_line_to(cr, left, top); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &base_light); cairo_fill(cr); cairo_move_to(cr, center, top); cairo_line_to(cr, right, top); cairo_line_to(cr, right, middle); cairo_line_to(cr, center, bottom); cairo_line_to(cr, center, top); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &base_light); cairo_fill_preserve(cr); cairo_set_source_rgba(cr, base_dark.red / 65535.0, base_dark.green / 65535.0, base_dark.blue / 65535.0, 0.5); cairo_fill(cr); cairo_move_to(cr, left + line_width, top + line_width); cairo_line_to(cr, right - line_width, top + line_width); cairo_line_to(cr, right - line_width, middle); cairo_line_to(cr, center, bottom - line_width - 0.5); cairo_line_to(cr, left + line_width, middle); cairo_line_to(cr, left + line_width, top + line_width); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &hl_light); cairo_stroke(cr); cairo_move_to(cr, left, top); cairo_line_to(cr, right, top); cairo_line_to(cr, right, middle); cairo_line_to(cr, center, bottom); cairo_line_to(cr, left, middle); cairo_line_to(cr, left, top); cairo_close_path(cr); gdk_cairo_set_source_color(cr, &base_dark); cairo_stroke(cr); cairo_destroy(cr); }
static void draw (cairo_t *cr, int width, int height) { cairo_surface_t *overlay, *punch, *circles; cairo_t *overlay_cr, *punch_cr, *circles_cr; /* Fill the background */ double radius = 0.5 * (width < height ? width : height) - 10; double xc = width / 2.; double yc = height / 2.; overlay = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (overlay == NULL) return; punch = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_ALPHA, width, height); if (punch == NULL) return; circles = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (circles == NULL) return; fill_checks (cr, 0, 0, width, height); /* Draw a black circle on the overlay */ overlay_cr = cairo_create (overlay); cairo_set_source_rgb (overlay_cr, 0., 0., 0.); oval_path (overlay_cr, xc, yc, radius, radius); cairo_fill (overlay_cr); /* Draw 3 circles to the punch surface, then cut * that out of the main circle in the overlay */ punch_cr = cairo_create (punch); draw_3circles (punch_cr, xc, yc, radius, 1.0); cairo_destroy (punch_cr); cairo_set_operator (overlay_cr, CAIRO_OPERATOR_DEST_OUT); cairo_set_source_surface (overlay_cr, punch, 0, 0); cairo_paint (overlay_cr); /* Now draw the 3 circles in a subgroup again * at half intensity, and use OperatorAdd to join up * without seams. */ circles_cr = cairo_create (circles); cairo_set_operator (circles_cr, CAIRO_OPERATOR_OVER); draw_3circles (circles_cr, xc, yc, radius, 0.5); cairo_destroy (circles_cr); cairo_set_operator (overlay_cr, CAIRO_OPERATOR_ADD); cairo_set_source_surface (overlay_cr, circles, 0, 0); cairo_paint (overlay_cr); cairo_destroy (overlay_cr); cairo_set_source_surface (cr, overlay, 0, 0); cairo_paint (cr); cairo_surface_destroy (overlay); cairo_surface_destroy (punch); cairo_surface_destroy (circles); }
static gboolean _tristatebutton_expose(GtkWidget *widget, GdkEventExpose *event) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_TRISTATEBUTTON(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style = gtk_widget_get_style(widget); int state = gtk_widget_get_state(widget); /* fix text style */ for(int i = 0; i < 5; i++) style->text[i] = style->fg[i]; /* fetch flags */ int flags = DTGTK_TRISTATEBUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* update active state paint flag */ gboolean active = DTGTK_TRISTATEBUTTON(widget)->state > 0; if(active) flags |= CPF_ACTIVE; else flags &= ~(CPF_ACTIVE); /* begin cairo drawing */ cairo_t *cr; cr = gdk_cairo_create(gtk_widget_get_window(widget)); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int x = allocation.x; int y = allocation.y; int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent nor flat styled */ if((flags & CPF_STYLE_FLAT)) { if(state != GTK_STATE_NORMAL) { cairo_rectangle(cr, x, y, width, height); cairo_set_source_rgba(cr, style->bg[state].red / 65535.0, style->bg[state].green / 65535.0, style->bg[state].blue / 65535.0, 0.5); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { cairo_rectangle(cr, x, y, width, height); float rs = 1.0, gs = 1.0, bs = 1.0; if(DTGTK_TRISTATEBUTTON(widget)->state == 1) rs = gs = bs = 3.0; else if(DTGTK_TRISTATEBUTTON(widget)->state == 2) rs = 3.0; cairo_set_source_rgba(cr, (style->bg[state].red / 65535.0) * rs, (style->bg[state].green / 65535.0) * gs, (style->bg[state].blue / 65535.0) * bs, 0.5); cairo_fill(cr); } /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } cairo_set_source_rgb(cr, style->fg[state].red / 65535.0, style->fg[state].green / 65535.0, style->fg[state].blue / 65535.0); /* draw button image if any */ GtkWidget *image = gtk_button_get_image(GTK_BUTTON(widget)); if(image) { GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(image)); if(pixbuf) { /* Draw the pixbuf */ gint pbw = gdk_pixbuf_get_width(pixbuf); gint pbh = gdk_pixbuf_get_height(pixbuf); gdk_cairo_set_source_pixbuf(cr, pixbuf, allocation.x + ((allocation.width / 2) - (pbw / 2)), allocation.y + ((allocation.height / 2) - (pbh / 2))); cairo_paint(cr); } } /* draw icon */ if(DTGTK_TRISTATEBUTTON(widget)->icon) { // if (flags & CPF_IGNORE_FG_STATE) // state = GTK_STATE_NORMAL; if(text) DTGTK_TRISTATEBUTTON(widget) ->icon(cr, x + border, y + border, height - (border * 2), height - (border * 2), flags); else DTGTK_TRISTATEBUTTON(widget) ->icon(cr, x + border, y + border, width - (border * 2), height - (border * 2), flags); } /* draw label */ if(text) { int lx = x + DT_PIXEL_APPLY_DPI(2), ly = y + ((height / 2.0) - (ph / 2.0)); cairo_translate(cr, lx, ly); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } cairo_destroy(cr); return FALSE; }
NS_METHOD compzillaRenderingContext::SetDimensions (PRInt32 width, PRInt32 height) { DEBUG ("SetDimensions (%d,%d)\n", width, height); Destroy(); #if false // Check that the dimensions are sane if (!CheckSaneImageSize(width, height)) return NS_ERROR_FAILURE; #endif mWidth = width; mHeight = height; #ifdef MOZ_CAIRO_GFX DEBUG ("thebes\n"); mThebesSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize (width, height), gfxASurface::ImageFormatARGB32); mThebesContext = new gfxContext(mThebesSurface); mSurface = mThebesSurface->CairoSurface(); cairo_surface_reference(mSurface); mCairo = mThebesContext->GetCairo(); cairo_reference(mCairo); DEBUG ("/thebes\n"); #else // non-cairo gfx // On most current X servers, using the software-only surface // actually provides a much smoother and faster display. // However, we provide MOZ_CANVAS_USE_RENDER for whomever wants to // go that route. //if (getenv("MOZ_CANVAS_USE_RENDER")) { XRenderPictFormat *fmt = XRenderFindStandardFormat (GDK_DISPLAY(), PictStandardARGB32); if (fmt) { int npfmts = 0; XPixmapFormatValues *pfmts = XListPixmapFormats(GDK_DISPLAY(), &npfmts); for (int i = 0; i < npfmts; i++) { if (pfmts[i].depth == 32) { npfmts = -1; break; } } XFree(pfmts); if (npfmts == -1) { mSurfacePixmap = XCreatePixmap (GDK_DISPLAY(), DefaultRootWindow(GDK_DISPLAY()), width, height, 32); mSurface = cairo_xlib_surface_create_with_xrender_format (GDK_DISPLAY(), mSurfacePixmap, DefaultScreenOfDisplay(GDK_DISPLAY()), fmt, mWidth, mHeight); } } //} // fall back to image surface if (!mSurface) { mImageSurfaceData = (PRUint8*) PR_Malloc (mWidth * mHeight * 4); if (!mImageSurfaceData) return NS_ERROR_OUT_OF_MEMORY; mSurface = cairo_image_surface_create_for_data (mImageSurfaceData, CAIRO_FORMAT_ARGB32, mWidth, mHeight, mWidth * 4); } mCairo = cairo_create(mSurface); #endif cairo_set_operator(mCairo, CAIRO_OPERATOR_CLEAR); cairo_new_path(mCairo); cairo_rectangle(mCairo, 0, 0, mWidth, mHeight); cairo_fill(mCairo); cairo_set_line_width(mCairo, 1.0); cairo_set_operator(mCairo, CAIRO_OPERATOR_OVER); cairo_set_miter_limit(mCairo, 10.0); cairo_set_line_cap(mCairo, CAIRO_LINE_CAP_BUTT); cairo_set_line_join(mCairo, CAIRO_LINE_JOIN_MITER); cairo_new_path(mCairo); return NS_OK; }
static void gimp_view_renderer_real_draw (GimpViewRenderer *renderer, GtkWidget *widget, cairo_t *cr, gint available_width, gint available_height) { if (renderer->needs_render) GIMP_VIEW_RENDERER_GET_CLASS (renderer)->render (renderer, widget); if (renderer->pixbuf) { gint width = gdk_pixbuf_get_width (renderer->pixbuf); gint height = gdk_pixbuf_get_height (renderer->pixbuf); gint x, y; if (renderer->bg_icon_name) { if (! renderer->pattern) { renderer->pattern = gimp_view_renderer_create_background (renderer, widget); } cairo_set_source (cr, renderer->pattern); cairo_paint (cr); } x = (available_width - width) / 2; y = (available_height - height) / 2; gdk_cairo_set_source_pixbuf (cr, renderer->pixbuf, x, y); cairo_rectangle (cr, x, y, width, height); cairo_fill (cr); } else if (renderer->surface) { cairo_content_t content = cairo_surface_get_content (renderer->surface); gint width = renderer->width; gint height = renderer->height; gint offset_x = (available_width - width) / 2; gint offset_y = (available_height - height) / 2; cairo_translate (cr, offset_x, offset_y); cairo_rectangle (cr, 0, 0, width, height); if (content == CAIRO_CONTENT_COLOR_ALPHA) { if (! renderer->pattern) renderer->pattern = gimp_cairo_checkerboard_create (cr, GIMP_CHECK_SIZE_SM, gimp_render_light_check_color (), gimp_render_dark_check_color ()); cairo_set_source (cr, renderer->pattern); cairo_fill_preserve (cr); } cairo_set_source_surface (cr, renderer->surface, 0, 0); cairo_fill (cr); cairo_translate (cr, - offset_x, - offset_y); } }
static void cdcreatecanvas(cdCanvas* canvas, void* data) { cdCtxCanvas* ctxcanvas; cairo_surface_t *surface; int w = 0, h = 0, use_alpha = 0; float res = (float)3.78; unsigned char *rgb = NULL; char* str_data = (char*)data; char* res_ptr = NULL; cairo_format_t format = CAIRO_FORMAT_RGB24; /* Starting parameters */ if (str_data == NULL) return; if (strstr(str_data, "-a")) use_alpha = 1; res_ptr = strstr(str_data, "-r"); if (res_ptr) sscanf(res_ptr+2, "%g", &res); /* size and rgb */ #ifdef SunOS_OLD sscanf(str_data, "%dx%d %d", &w, &h, &rgb); #else sscanf(str_data, "%dx%d %p", &w, &h, &rgb); #endif if (w == 0 || h == 0) return; canvas->w = w; canvas->h = h; canvas->yres = res; canvas->xres = res; canvas->w_mm = ((double)w) / res; canvas->h_mm = ((double)h) / res; if (use_alpha) { canvas->bpp = 32; format = CAIRO_FORMAT_ARGB32; } else canvas->bpp = 24; /* fake value, image bpp is always 32 */ if (rgb) surface = cairo_image_surface_create_for_data(rgb, format, w, h, w*32); else surface = cairo_image_surface_create(format, canvas->w, canvas->h); /* Starting Cairo driver */ ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(surface)); cairo_surface_destroy(surface); if (rgb) { ctxcanvas->user_image = 1; ctxcanvas->rgb = rgb; } else { ctxcanvas->user_image = 0; ctxcanvas->rgb = cairo_image_surface_get_data(cairo_get_target(ctxcanvas->cr)); /* fill with white */ /* transparent, this is the normal alpha coding */ cairo_set_source_rgba(ctxcanvas->cr, 1.0, 1.0, 1.0, 0.0); cairo_rectangle(ctxcanvas->cr, 0, 0, canvas->w, canvas->h); cairo_fill(ctxcanvas->cr); } cdRegisterAttribute(canvas, &stride_attrib); cdRegisterAttribute(canvas, &write2png_attrib); cdRegisterAttribute(canvas, &data_attrib); }
static void texbox_update ( textbox *tb ) { if ( tb->update ) { if ( tb->main_surface ) { cairo_destroy ( tb->main_draw ); cairo_surface_destroy ( tb->main_surface ); tb->main_draw = NULL; tb->main_surface = NULL; } tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h ); tb->main_draw = cairo_create ( tb->main_surface ); PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font ); pango_font_description_free ( pfd ); cairo_set_operator ( tb->main_draw, CAIRO_OPERATOR_SOURCE ); pango_cairo_update_layout ( tb->main_draw, tb->layout ); char *text = tb->text ? tb->text : ""; int text_len = strlen ( text ); int font_height = textbox_get_font_height ( tb ); int cursor_x = 0; int cursor_width = MAX ( 2, font_height / 10 ); if ( tb->changed ) { if ( tb->flags & TB_MARKUP ) { pango_layout_set_markup ( tb->layout, text, text_len ); } else{ pango_layout_set_text ( tb->layout, text, text_len ); } } if ( tb->flags & TB_EDITABLE ) { PangoRectangle pos; int cursor_offset = 0; cursor_offset = MIN ( tb->cursor, text_len ); pango_layout_get_cursor_pos ( tb->layout, cursor_offset, &pos, NULL ); // Add a small 4px offset between cursor and last glyph. cursor_x = pos.x / PANGO_SCALE; } // Skip the side MARGIN on the X axis. int x = SIDE_MARGIN; int y = 0; if ( tb->flags & TB_RIGHT ) { int line_width = 0; // Get actual width. pango_layout_get_pixel_size ( tb->layout, &line_width, NULL ); x = ( tb->w - line_width - SIDE_MARGIN ); } else if ( tb->flags & TB_CENTER ) { int tw = textbox_get_font_width ( tb ); x = ( ( tb->w - tw - 2 * SIDE_MARGIN ) ) / 2; } short fh = textbox_get_font_height ( tb ); if ( fh > tb->h ) { y = 0; } else { y = ( ( tb->h - fh ) ) / 2; } // Set ARGB Color col = tb->color_bg; cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha ); cairo_paint ( tb->main_draw ); // Set ARGB col = tb->color_fg; cairo_set_source_rgba ( tb->main_draw, col.red, col.green, col.blue, col.alpha ); cairo_move_to ( tb->main_draw, x, y ); pango_cairo_show_layout ( tb->main_draw, tb->layout ); //cairo_fill(tb->draw); // draw the cursor if ( tb->flags & TB_EDITABLE ) { cairo_rectangle ( tb->main_draw, x + cursor_x, y, cursor_width, font_height ); cairo_fill ( tb->main_draw ); } tb->update = FALSE; } }
gboolean cd_do_render_listing_notification (gpointer pUserData, CDListing *pListing, cairo_t *pCairoContext) { //g_print ("%s ()\n", __func__); int iWidth = pListing->container.iWidth, iHeight = pListing->container.iHeight; int iLeftMargin = myDialogs.dialogTextDescription.iSize + 2, iRightMargin = (myDialogs.dialogTextDescription.iSize + 2) / 2; int iTopMargin = (myDialogs.dialogTextDescription.iSize + 2) + GAP, iBottomMargin = (myDialogs.dialogTextDescription.iSize + 2) * 4 + GAP; CDEntry *pEntry; // on dessine un cadre et un fond double fRadius = MIN (6, myDialogs.dialogTextDescription.iSize/2+1); double fLineWidth = 1.; cairo_set_line_width (pCairoContext, fLineWidth); cairo_save (pCairoContext); cairo_translate (pCairoContext, 0, fLineWidth); cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iTopMargin - GAP); cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.); cairo_stroke_preserve (pCairoContext); cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7); cairo_fill (pCairoContext); cairo_translate (pCairoContext, 0, iTopMargin + fLineWidth); cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iHeight - iTopMargin - iBottomMargin - GAP); cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.); cairo_stroke_preserve (pCairoContext); cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7); cairo_fill (pCairoContext); cairo_translate (pCairoContext, 0, iHeight - iTopMargin - 2*fLineWidth - iBottomMargin + GAP); cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iBottomMargin - GAP - fLineWidth); cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.); cairo_stroke_preserve (pCairoContext); cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7); cairo_fill (pCairoContext); cairo_restore (pCairoContext); PangoLayout *pLayout = pango_cairo_create_layout (pCairoContext); PangoFontDescription *pDesc = pango_font_description_new (); pango_font_description_set_absolute_size (pDesc, myDialogs.dialogTextDescription.iSize * PANGO_SCALE); pango_font_description_set_family_static (pDesc, myDialogs.dialogTextDescription.cFont); pango_font_description_set_weight (pDesc, myDialogs.dialogTextDescription.iWeight); pango_font_description_set_style (pDesc, myLabels.iconTextDescription.iStyle); pango_layout_set_font_description (pLayout, pDesc); pango_font_description_free (pDesc); // on dessine les entrees. if (pListing->pEntries != NULL) { // on dessine chaque entree. int iNbSteps = _listing_compute_nb_steps (pListing); // nb d'etapes pour l'apparition du texte. int iOffsetX = NB_STEPS_FOR_1_ENTRY - (iNbSteps - pListing->iAppearanceAnimationCount) - 1; if (pListing->iNbEntries >= myConfig.iNbLinesInListing) iOffsetX += myConfig.iNbLinesInListing/4*NB_STEPS_LATE; // permet de donner une transparence aux 25% dernieres lignes. double dx, dy, dm = myConfig.iNbLinesInListing * (myDialogs.dialogTextDescription.iSize + 2) / 2; dm = 0; dy = iTopMargin - pListing->fCurrentOffset + 1 + dm; double ymax = MIN (iTopMargin + pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2), iHeight - iBottomMargin); GList *e; for (e = pListing->pEntries; e != NULL; e = e->next) { if (iOffsetX >= NB_STEPS_FOR_1_ENTRY) // en dehors a droite a partir de celui-ci. break ; pEntry = e->data; if (pEntry->bHidden) continue ; dx = myDialogs.dialogTextDescription.iSize + 2; // marge a gauche. //if (iOffsetX > 0 && pListing->iAppearanceAnimationCount > 0) // dx += (double) iOffsetX * (iWidth - (myDialogs.dialogTextDescription.iSize + 2)) / NB_STEPS_FOR_1_ENTRY; dy += (myDialogs.dialogTextDescription.iSize + 2); while (dy + myDialogs.dialogTextDescription.iSize + 2 <= iTopMargin + 1) dy += pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2); while (dy > ymax) dy -= pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2); if (dy > ymax || dy + myDialogs.dialogTextDescription.iSize + 2 <= iTopMargin + 1) continue; cairo_save (pCairoContext); cairo_translate (pCairoContext, dx, dy); // on fait un clip si necessaire. if (dy + myDialogs.dialogTextDescription.iSize + 2 > iHeight - iBottomMargin || dy < iTopMargin) // cette entree n'est que partiellement visible. { if (dy < iTopMargin) // elle depasse en haut. cairo_rectangle (pCairoContext, -iLeftMargin, iTopMargin - dy, iWidth, myDialogs.dialogTextDescription.iSize + 2 -(iTopMargin - dy)); else // elle depasse en bas. cairo_rectangle (pCairoContext, -iLeftMargin, 0, iWidth, iHeight - iBottomMargin - dy); cairo_clip (pCairoContext); } // on dessine l'icone. if (pEntry->pIconSurface != NULL) { cairo_set_source_surface (pCairoContext, pEntry->pIconSurface, - iLeftMargin + 1, 0.); cairo_paint (pCairoContext); } // on souligne l'entree courante. if (e == pListing->pCurrentEntry) { double f = 1. - (double) pListing->iCurrentEntryAnimationCount / NB_STEPS_FOR_CURRENT_ENTRY; if (f != 0) { cairo_save (pCairoContext); double rx = .5*(iWidth - iLeftMargin - iRightMargin); double ry = .5*(myDialogs.dialogTextDescription.iSize + 2); cairo_pattern_t *pPattern = cairo_pattern_create_radial (ry, ry, 0., ry, ry, f * ry); cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_NONE); cairo_pattern_add_color_stop_rgba (pPattern, 0., 0., 0., 1., .3); cairo_pattern_add_color_stop_rgba (pPattern, 1., 0., 0., 0., 0.); cairo_scale (pCairoContext, rx/ry, 1.); cairo_set_source (pCairoContext, pPattern); cairo_paint (pCairoContext); cairo_pattern_destroy (pPattern); cairo_restore (pCairoContext); // on dessine l'indicateur de sous-listing. if (pEntry->list != NULL) { cairo_set_source_rgba (pCairoContext, 0., 0., 0., f); cairo_move_to (pCairoContext, iWidth - iLeftMargin - iRightMargin, myDialogs.dialogTextDescription.iSize/4); cairo_rel_line_to (pCairoContext, iRightMargin, myDialogs.dialogTextDescription.iSize/4); cairo_rel_line_to (pCairoContext, -iRightMargin, myDialogs.dialogTextDescription.iSize/4); cairo_close_path (pCairoContext); cairo_stroke (pCairoContext); } } } // on dessine le texte. cairo_set_source_rgba (pCairoContext, 0., 0., 0., 1. - (double) iOffsetX / NB_STEPS_FOR_1_ENTRY); pango_layout_set_text (pLayout, pEntry->cName, -1); pango_cairo_show_layout (pCairoContext, pLayout); // on separe la 1ere entree de la derniere. if (e->prev == NULL) { cairo_set_source_rgba (pCairoContext, 0., 0., 0., .5); cairo_move_to (pCairoContext, 0., 1.); cairo_rel_line_to (pCairoContext, iWidth - iLeftMargin - iRightMargin, 0.); double dashes = 2.; cairo_set_dash (pCairoContext, &dashes, 1, 0.); cairo_stroke (pCairoContext); cairo_set_dash (pCairoContext, &dashes, 0, 0.); } cairo_restore (pCairoContext); iOffsetX += NB_STEPS_LATE; } // on dessine le chemin de l'entree courante. if (pListing->pCurrentEntry) { pEntry = pListing->pCurrentEntry->data; cairo_save (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); cairo_translate (pCairoContext, fRadius - pListing->iTitleOffset, 0.); pango_layout_set_text (pLayout, pEntry->cPath ? pEntry->cPath : pEntry->cName, -1); PangoRectangle ink, log; pango_layout_get_pixel_extents (pLayout, &ink, &log); pListing->iTitleWidth = ink.width; pango_cairo_show_layout (pCairoContext, pLayout); cairo_restore (pCairoContext); } } // on dessine l'etat de la recherche. cairo_translate (pCairoContext, 0, iHeight - iBottomMargin); cairo_set_source_surface (pCairoContext, myData.pScoobySurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); cairo_translate (pCairoContext, 2 * (myDialogs.dialogTextDescription.iSize + 2), GAP); if (myData.cStatus != NULL) { pango_layout_set_text (pLayout, myData.cStatus, -1); } pango_cairo_show_layout (pCairoContext, pLayout); // on dessine le filtre. cairo_translate (pCairoContext, 0., myDialogs.dialogTextDescription.iSize + 2); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_MATCH_CASE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F1) Match case"), -1); pango_cairo_show_layout (pCairoContext, pLayout); cairo_translate (pCairoContext, iWidth/3, 0.); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_MUSIC) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F2) Music"), -1); pango_cairo_show_layout (pCairoContext, pLayout); cairo_translate (pCairoContext, iWidth/3, 0.); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_IMAGE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F3) Image"), -1); pango_cairo_show_layout (pCairoContext, pLayout); cairo_translate (pCairoContext, -2*iWidth/3, myDialogs.dialogTextDescription.iSize + 2); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_VIDEO) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F4) Video"), -1); pango_cairo_show_layout (pCairoContext, pLayout); cairo_translate (pCairoContext, iWidth/3, 0.); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_TEXT) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F5) Text"), -1); pango_cairo_show_layout (pCairoContext, pLayout); cairo_translate (pCairoContext, iWidth/3, 0.); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_HTML) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F6) Html"), -1); pango_cairo_show_layout (pCairoContext, pLayout); cairo_translate (pCairoContext, -2*iWidth/3, myDialogs.dialogTextDescription.iSize + 2); cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_SOURCE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.); cairo_paint (pCairoContext); cairo_set_source_rgb (pCairoContext, 0., 0., 0.); pango_layout_set_text (pLayout, D_("(F7) Sources"), -1); pango_cairo_show_layout (pCairoContext, pLayout); g_object_unref (pLayout); }
static gboolean _togglebutton_draw(GtkWidget *widget, cairo_t *cr) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_TOGGLEBUTTON(widget), FALSE); GtkDarktableToggleButton *button = DTGTK_TOGGLEBUTTON(widget); GtkStateFlags state = gtk_widget_get_state_flags(widget); GdkRGBA bg_color, fg_color; GtkStyleContext *context = gtk_widget_get_style_context(widget); if(button->icon_flags & CPF_CUSTOM_BG) bg_color = button->bg; else { GdkRGBA *bc; gtk_style_context_get(context, state, "background-color", &bc, NULL); bg_color = *bc; gdk_rgba_free(bc); } if(button->icon_flags & CPF_CUSTOM_FG) fg_color = button->fg; else gtk_style_context_get_color(context, state, &fg_color); /* fetch flags */ int flags = DTGTK_TOGGLEBUTTON(widget)->icon_flags; /* set inner border */ int border = DT_PIXEL_APPLY_DPI((flags & CPF_DO_NOT_USE_BORDER) ? 2 : 6); /* update active state paint flag */ gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); if(active) flags |= CPF_ACTIVE; else flags &= ~(CPF_ACTIVE); /* prelight */ if(state & GTK_STATE_FLAG_PRELIGHT) flags |= CPF_PRELIGHT; else flags &= ~CPF_PRELIGHT; /* begin cairo drawing */ GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width; int height = allocation.height; /* draw standard button background if not transparent nor flat styled */ if((flags & CPF_STYLE_FLAT)) { if(flags & CPF_PRELIGHT || flags & CPF_ACTIVE) { cairo_rectangle(cr, 0, 0, width, height); gdk_cairo_set_source_rgba(cr, &bg_color); cairo_fill(cr); } } else if(!(flags & CPF_BG_TRANSPARENT)) { /* draw default boxed button */ gtk_render_background(context, cr, 0, 0, width, height); if(!(flags & CPF_DO_NOT_USE_BORDER)) gtk_render_frame(context, cr, 0, 0, width, height); } /* create pango text settings if label exists */ PangoLayout *layout = NULL; int pw = 0, ph = 0; const gchar *text = gtk_button_get_label(GTK_BUTTON(widget)); if(text) { layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, darktable.bauhaus->pango_font_desc); pango_cairo_context_set_resolution(pango_layout_get_context(layout), darktable.gui->dpi); pango_layout_set_text(layout, text, -1); pango_layout_get_pixel_size(layout, &pw, &ph); } gdk_cairo_set_source_rgba(cr, &fg_color); /* draw icon */ if(DTGTK_TOGGLEBUTTON(widget)->icon) { // if (flags & CPF_IGNORE_FG_STATE) // state = GTK_STATE_NORMAL; int icon_width = text ? height - (border * 2) : width - (border * 2); int icon_height = height - (border * 2); if(icon_width > 0 && icon_height > 0) { if(text) DTGTK_TOGGLEBUTTON(widget) ->icon(cr, border, border, height - (border * 2), height - (border * 2), flags); else DTGTK_TOGGLEBUTTON(widget) ->icon(cr, border, border, width - (border * 2), height - (border * 2), flags); } } /* draw label */ if(text) { int lx = DT_PIXEL_APPLY_DPI(2), ly = ((height / 2.0) - (ph / 2.0)); // if (DTGTK_TOGGLEBUTTON (widget)->icon) lx += width; // GdkRectangle t={x,y,x+width,y+height}; // gtk_paint_layout(style,gtk_widget_get_window(widget), // state,TRUE,&t,widget,"togglebutton",lx,ly,layout); cairo_translate(cr, lx, ly); pango_cairo_show_layout(cr, layout); g_object_unref(layout); } return FALSE; }
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jint r1, jint g1, jint b1, jint a1, jint r2, jint g2, jint b2, jint a2, jboolean cyclic) { struct graphics2d *gr = NULL; cairo_surface_t *surf = NULL; cairo_matrix_t *mat = NULL; gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj); g_assert (gr != NULL); gdk_threads_enter(); if (peer_is_disposed(env, obj)) { gdk_threads_leave(); return; } if (gr->debug) printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n", x1, y1, x2, y2, r1, g1, b1, a1, r2, g2, b2, a2); cairo_save (gr->cr); if (cyclic) surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2); else surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2); g_assert (surf != NULL); cairo_set_target_surface (gr->cr, surf); cairo_identity_matrix (gr->cr); cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0); cairo_set_alpha (gr->cr, a1 / 255.0); cairo_rectangle (gr->cr, 0, 0, 1, 2); cairo_fill (gr->cr); cairo_set_rgb_color (gr->cr, r2 / 255.0, g2 / 255.0, b2 / 255.0); cairo_set_alpha (gr->cr, a2 / 255.0); cairo_rectangle (gr->cr, 1, 0, 1, 2); cairo_fill (gr->cr); if (cyclic) { cairo_set_rgb_color (gr->cr, r1 / 255.0, g1 / 255.0, b1 / 255.0); cairo_set_alpha (gr->cr, a1 / 255.0); cairo_rectangle (gr->cr, 2, 0, 1, 2); cairo_fill (gr->cr); } mat = cairo_matrix_create (); g_assert (mat != NULL); /* consider the vector [x2 - x1, y2 - y1] = [p,q] this is a line in space starting at an 'origin' x1, y1. it can also be thought of as a "transformed" unit vector in either the x or y directions. we have just *drawn* our gradient as a unit vector (well, a 2-3x unit vector) in the x dimension. so what we want to know is which transformation turns our existing unit vector into [p,q]. which means solving for M in [p,q] = M[1,0] [p,q] = |a b| [1,0] |c d| [p,q] = [a,c], with b = d = 0. what does this mean? it means that our gradient is 1-dimensional; as you move through the x axis of our 2 or 3 pixel gradient from logical x positions 0 to 1, the transformation of your x coordinate under the matrix M causes you to accumulate both x and y values in fill space. the y value of a gradient coordinate is ignored, since the gradient is one dimensional. which is correct. unfortunately we want the opposite transformation, it seems, because of the way cairo is going to use this transformation. I'm a bit confused by that, but it seems to work right, so we take reciprocals of values and negate offsets. oh well. */ { double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1)); double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1)); double dx = (x1 == 0.) ? 0. : 1. / x1; double dy = (y1 == 0.) ? 0. : 1. / y1; cairo_matrix_set_affine (mat, a, 0., c, 0., dx, dy); cairo_surface_set_matrix (surf, mat); cairo_matrix_destroy (mat); cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR); } /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */ /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */ if (gr->pattern) cairo_pattern_destroy (gr->pattern); if (gr->pattern_surface) cairo_surface_destroy (gr->pattern_surface); if (gr->pattern_pixels) free (gr->pattern_pixels); gr->pattern_pixels = NULL; gr->pattern_surface = surf; gr->pattern = cairo_pattern_create_for_surface(surf); cairo_restore (gr->cr); cairo_set_pattern (gr->cr, gr->pattern); gdk_threads_leave(); }
int main(int argc, char *argv[]) { int pid = fork(); if (!pid) { drawing_information dinformation; drawing_information* di = &dinformation; di->ball_x = 360; di->ball_y = 240; di->paddle_one_y = 0; di->paddle_two_y = 0; di->score_one = 0; di->score_two = 0; di->ball_speed = 1; int shmid; key_t key = 25568; if ((shmid = shmget(key, sizeof(drawing_information), IPC_CREAT | 0666)) < 0) { printf("Error shmgetting...\n"); exit(1); } int width = 720; int height = 520; int videoFlags = SDL_SWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF; int bpp = 32; if (SDL_Init(SDL_INIT_VIDEO) < 0) { return -1; } SDL_WM_SetCaption("Pong", "Pong"); SDL_Surface *screen; screen = SDL_SetVideoMode(width, height, bpp, videoFlags); SDL_EnableKeyRepeat(300, 130); SDL_EnableUNICODE(1); SDL_Surface *sdl_surface = SDL_CreateRGBSurface ( videoFlags, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0 ); int done = 0; while (!done) { di = (drawing_information *)shmat(shmid, NULL, 0); SDL_FillRect(sdl_surface, NULL, 0); cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data((unsigned char *)sdl_surface->pixels, CAIRO_FORMAT_RGB24, sdl_surface->w, sdl_surface->h, sdl_surface->pitch); cairo_t *cr = cairo_create(cairo_surface); //do_drawing(cr); cairo_set_source_rgb(cr,255,255,255); cairo_rectangle(cr, 20, di->paddle_one_y, 7, 40); cairo_fill(cr); cairo_rectangle(cr, 693, di->paddle_two_y, 7, 40); cairo_fill(cr); cairo_arc(cr, di->ball_x, di->ball_y, 5, 0, 2*M_PI); cairo_fill(cr); cairo_move_to(cr, 0, 480); cairo_line_to(cr, 720, 480); cairo_stroke(cr); cairo_select_font_face(cr, "Courier", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 38); cairo_move_to(cr, 20, 510); char *to_send = (char *)malloc(100); sprintf(to_send, "%d", di->score_one); cairo_show_text(cr, to_send); cairo_move_to(cr, 693, 510); sprintf(to_send, "%d", di->score_two); cairo_show_text(cr, to_send); SDL_BlitSurface(sdl_surface, NULL, screen, NULL); SDL_Flip(screen); //dont with cairo surface cairo_surface_destroy(cairo_surface); cairo_destroy(cr); //Event handling SDL_Event event; while (SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) { done = 1; } else if (event.key.keysym.sym == SDLK_w) { if (di->paddle_one_y > 15) { di->paddle_one_y -= 15; } } else if (event.key.keysym.sym == SDLK_s) { if (di->paddle_one_y < 410) { di->paddle_one_y += 15; } } else if (event.key.keysym.sym == SDLK_UP) { if (di->paddle_two_y > 15) { di->paddle_two_y -= 15; } } else if (event.key.keysym.sym == SDLK_DOWN) { if (di->paddle_two_y < 410) { di->paddle_two_y += 15; } } break; case SDL_QUIT: done = 1; break; } } SDL_Delay(1); } //cleanup SDL_FreeSurface(sdl_surface); SDL_Quit(); return 0; } else { drawing_information dinformation; drawing_information* di = &dinformation; di->ball_x = 360; di->ball_y = 240; di->paddle_one_y = 0; di->paddle_two_y = 0; di->score_one = 0; di->score_two = 0; int to_server; int from_server; char buffer[100]; to_server = client_handshake(&from_server); while (1) { // Reading loop // Take input from user // Write to server // If the message is exit, then shut down // write(to_server, buffer, sizeof(buffer)); // Get message from server read(from_server, buffer, sizeof(buffer)); // Print confirmation char *to_send = parse_input(buffer, di); write(to_server, to_send, 100); } } }
/* 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 meta_draw_window_decoration (decor_t *d) { Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); cairo_surface_t *surface; Picture src; MetaButtonState button_states [META_BUTTON_TYPE_LAST]; MetaButtonLayout button_layout; MetaFrameGeometry fgeom; MetaFrameFlags flags; MetaFrameType frame_type; MetaTheme *theme; GtkStyleContext *context; cairo_t *cr; gint i; GdkRectangle clip; Region top_region = NULL; Region bottom_region = NULL; Region left_region = NULL; Region right_region = NULL; gdouble meta_active_opacity, meta_inactive_opacity; gboolean meta_active_shade_opacity, meta_inactive_shade_opacity; g_object_get (settings, "metacity-active-opacity", &meta_active_opacity, NULL); g_object_get (settings, "metacity-inactive-opacity", &meta_inactive_opacity, NULL); g_object_get (settings, "metacity-active-shade-opacity", &meta_active_shade_opacity, NULL); g_object_get (settings, "metacity-inactive-shade-opacity", &meta_inactive_shade_opacity, NULL); double alpha = (d->active) ? meta_active_opacity : meta_inactive_opacity; gboolean shade_alpha = (d->active) ? meta_active_shade_opacity : meta_inactive_shade_opacity; MetaFrameStyle *frame_style; GtkWidget *style_window; GdkRGBA bg_rgba; if (!d->surface || !d->picture) return; if (decoration_alpha == 1.0) alpha = 1.0; if (cairo_xlib_surface_get_depth (d->surface) == 32) { context = gtk_widget_get_style_context (d->frame->style_window_rgba); style_window = d->frame->style_window_rgba; } else { context = gtk_widget_get_style_context (d->frame->style_window_rgb); style_window = d->frame->style_window_rgb; } cr = cairo_create (d->buffer_surface ? d->buffer_surface : d->surface); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); theme = meta_theme_get_current (); frame_type = meta_frame_type_from_string (d->frame->type); if (frame_type == META_FRAME_TYPE_LAST) frame_type = META_FRAME_TYPE_NORMAL; meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout, frame_type, &clip); if ((d->prop_xid || !d->buffer_surface) && !d->frame_window) draw_shadow_background (d, cr, d->shadow, d->context); for (i = 0; i < META_BUTTON_TYPE_LAST; ++i) button_states[i] = meta_button_state_for_button_type (d, i); frame_style = meta_theme_get_frame_style (theme, frame_type, flags); gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &bg_rgba); bg_rgba.alpha = 1.0; if (frame_style->window_background_color) { meta_color_spec_render (frame_style->window_background_color, gtk_widget_get_style_context (style_window), &bg_rgba); bg_rgba.alpha = frame_style->window_background_alpha / 255.0; } /* Draw something that will be almost invisible to user. This is hacky way * to fix invisible decorations. */ cairo_set_source_rgba (cr, 0, 0, 0, 0.01); cairo_rectangle (cr, 0, 0, 1, 1); cairo_fill (cr); /* ------------ */ cairo_destroy (cr); if (d->frame_window) surface = create_surface (clip.width, clip.height, d->frame->style_window_rgb); else surface = create_surface (clip.width, clip.height, d->frame->style_window_rgba); cr = cairo_create (surface); gdk_cairo_set_source_rgba (cr, &bg_rgba); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); src = XRenderCreatePicture (xdisplay, cairo_xlib_surface_get_drawable (surface), get_format_for_surface (d, surface), 0, NULL); cairo_paint (cr); meta_theme_draw_frame (theme, style_window, cr, frame_type, flags, clip.width - fgeom.left_width - fgeom.right_width, clip.height - fgeom.top_height - fgeom.bottom_height, d->layout, d->frame->text_height, &button_layout, button_states, d->icon_pixbuf, NULL); if (fgeom.top_height) { top_region = meta_get_top_border_region (&fgeom, clip.width); decor_blend_border_picture (xdisplay, d->context, src, 0, 0, d->picture, &d->border_layout, BORDER_TOP, top_region, alpha * 0xffff, shade_alpha, 0); } if (fgeom.bottom_height) { bottom_region = meta_get_bottom_border_region (&fgeom, clip.width); decor_blend_border_picture (xdisplay, d->context, src, 0, clip.height - fgeom.bottom_height, d->picture, &d->border_layout, BORDER_BOTTOM, bottom_region, alpha * 0xffff, shade_alpha, 0); } if (fgeom.left_width) { left_region = meta_get_left_border_region (&fgeom, clip.height); decor_blend_border_picture (xdisplay, d->context, src, 0, fgeom.top_height, d->picture, &d->border_layout, BORDER_LEFT, left_region, alpha * 0xffff, shade_alpha, 0); } if (fgeom.right_width) { right_region = meta_get_right_border_region (&fgeom, clip.height); decor_blend_border_picture (xdisplay, d->context, src, clip.width - fgeom.right_width, fgeom.top_height, d->picture, &d->border_layout, BORDER_RIGHT, right_region, alpha * 0xffff, shade_alpha, 0); } cairo_destroy (cr); cairo_surface_destroy (surface); XRenderFreePicture (xdisplay, src); copy_to_front_buffer (d); if (d->frame_window) { GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window); GdkPixbuf *pixbuf = gdk_pixbuf_get_from_surface (d->surface, 0, 0, d->width, d->height); gtk_image_set_from_pixbuf (GTK_IMAGE (d->decor_image), pixbuf); g_object_unref (pixbuf); gtk_window_resize (GTK_WINDOW (d->decor_window), d->width, d->height); gdk_window_move (gdk_frame_window, d->context->left_corner_space - 1, d->context->top_corner_space - 1); gdk_window_lower (gdk_frame_window); } if (d->prop_xid) { /* translate from frame to client window space */ if (top_region) XOffsetRegion (top_region, -fgeom.left_width, -fgeom.top_height); if (bottom_region) XOffsetRegion (bottom_region, -fgeom.left_width, 0); if (left_region) XOffsetRegion (left_region, -fgeom.left_width, 0); decor_update_meta_window_property (d, theme, flags, top_region, bottom_region, left_region, right_region); d->prop_xid = 0; } if (top_region) XDestroyRegion (top_region); if (bottom_region) XDestroyRegion (bottom_region); if (left_region) XDestroyRegion (left_region); if (right_region) XDestroyRegion (right_region); }
static void _gtk_theming_background_paint_layer (GtkThemingBackground *bg, GtkThemingBackgroundLayer *layer, cairo_t *cr) { cairo_save (cr); _gtk_rounded_box_path (&layer->clip_box, cr); cairo_clip (cr); if (layer->image && layer->image_rect.width > 0 && layer->image_rect.height > 0) { const GtkCssValue *pos, *repeat; double image_width, image_height; double width, height; GtkCssRepeatStyle hrepeat, vrepeat; pos = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_POSITION), layer->idx); repeat = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_REPEAT), layer->idx); hrepeat = _gtk_css_background_repeat_value_get_x (repeat); vrepeat = _gtk_css_background_repeat_value_get_y (repeat); width = layer->image_rect.width; height = layer->image_rect.height; _gtk_css_bg_size_value_compute_size (_gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_SIZE), layer->idx), layer->image, width, height, &image_width, &image_height); /* optimization */ if (image_width == width) hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT; if (image_height == height) vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT; cairo_translate (cr, layer->image_rect.x, layer->image_rect.y); if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT && vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT) { cairo_translate (cr, _gtk_css_position_value_get_x (pos, width - image_width), _gtk_css_position_value_get_y (pos, height - image_height)); /* shortcut for normal case */ _gtk_css_image_draw (layer->image, cr, image_width, image_height); } else { int surface_width, surface_height; cairo_rectangle_t fill_rect; cairo_surface_t *surface; cairo_t *cr2; /* If ‘background-repeat’ is ‘round’ for one (or both) dimensions, * there is a second step. The UA must scale the image in that * dimension (or both dimensions) so that it fits a whole number of * times in the background positioning area. In the case of the width * (height is analogous): * * If X ≠ 0 is the width of the image after step one and W is the width * of the background positioning area, then the rounded width * X' = W / round(W / X) where round() is a function that returns the * nearest natural number (integer greater than zero). * * If ‘background-repeat’ is ‘round’ for one dimension only and if * ‘background-size’ is ‘auto’ for the other dimension, then there is * a third step: that other dimension is scaled so that the original * aspect ratio is restored. */ if (hrepeat == GTK_CSS_REPEAT_STYLE_ROUND) { double n = round (width / image_width); n = MAX (1, n); if (vrepeat != GTK_CSS_REPEAT_STYLE_ROUND /* && vsize == auto (it is by default) */) image_height *= width / (image_width * n); image_width = width / n; } if (vrepeat == GTK_CSS_REPEAT_STYLE_ROUND) { double n = round (height / image_height); n = MAX (1, n); if (hrepeat != GTK_CSS_REPEAT_STYLE_ROUND /* && hsize == auto (it is by default) */) image_width *= height / (image_height * n); image_height = height / n; } /* if hrepeat or vrepeat is 'space', we create a somewhat larger surface * to store the extra space. */ if (hrepeat == GTK_CSS_REPEAT_STYLE_SPACE) { double n = floor (width / image_width); surface_width = n ? round (width / n) : 0; } else surface_width = round (image_width); if (vrepeat == GTK_CSS_REPEAT_STYLE_SPACE) { double n = floor (height / image_height); surface_height = n ? round (height / n) : 0; } else surface_height = round (image_height); surface = cairo_surface_create_similar (cairo_get_target (cr), CAIRO_CONTENT_COLOR_ALPHA, surface_width, surface_height); cr2 = cairo_create (surface); cairo_translate (cr2, 0.5 * (surface_width - image_width), 0.5 * (surface_height - image_height)); _gtk_css_image_draw (layer->image, cr2, image_width, image_height); cairo_destroy (cr2); cairo_set_source_surface (cr, surface, _gtk_css_position_value_get_x (pos, width - image_width), _gtk_css_position_value_get_y (pos, height - image_height)); cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); cairo_surface_destroy (surface); if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT) { fill_rect.x = _gtk_css_position_value_get_x (pos, width - image_width); fill_rect.width = image_width; } else { fill_rect.x = 0; fill_rect.width = width; } if (vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT) { fill_rect.y = _gtk_css_position_value_get_y (pos, height - image_height); fill_rect.height = image_height; } else { fill_rect.y = 0; fill_rect.height = height; } cairo_rectangle (cr, fill_rect.x, fill_rect.y, fill_rect.width, fill_rect.height); cairo_fill (cr); } } cairo_restore (cr); }
NS_IMETHODIMP compzillaRenderingContext::CopyImageDataFrom (Display *dpy, Window drawable, PRInt32 src_x, PRInt32 src_y, PRUint32 w, PRUint32 h) { DEBUG ("CopyImageDataFrom (%d,%d)\n", w, h); // XXX this is wrong, but it'll do for now. it needs to create a // (possibly smaller) subimage and composite it into the larger // mSurface. XImage *image = XGetImage (dpy, drawable, src_x, src_y, w, h, AllPlanes, ZPixmap); #ifdef MOZ_CAIRO_GFX DEBUG ("thebes\n"); gfxImageSurface *imagesurf = new gfxImageSurface(gfxIntSize (w, h), gfxASurface::ImageFormatARGB32); unsigned char *r = imagesurf->Data(); unsigned char *p = (unsigned char*)image->data; for (int i = 0; i < w * h; i ++) { *r++ = *p++; *r++ = *p++; *r++ = *p++; *r = 255; r++; p++; } mThebesContext->SetSource (imagesurf, gfxPoint (src_x, src_y)); mThebesContext->Paint (); #if 0 mThebesContext->DrawSurface (imagesurf, gfxSize (w, h)); #endif #else // Fix colors unsigned char *r = (unsigned char*)image->data; for (int i = 0; i < w * h; i ++) { r[3] = 255; r += 4; } if (mImageSurfaceData) { int stride = mWidth*4; PRUint8 *dest = mImageSurfaceData + stride*src_y + src_x*4; for (int32 i = 0; i < src_y; i++) { memcpy(dest, image->data + (w*4)*i, w*4); dest += stride; } } else { cairo_surface_t *imgsurf; imgsurf = cairo_image_surface_create_for_data ((unsigned char*)image->data, CAIRO_FORMAT_ARGB32, w, h, w*4); cairo_save (mCairo); cairo_identity_matrix (mCairo); cairo_translate (mCairo, src_x, src_y); cairo_new_path (mCairo); cairo_rectangle (mCairo, 0, 0, w, h); cairo_set_source_surface (mCairo, imgsurf, 0, 0); cairo_set_operator (mCairo, CAIRO_OPERATOR_SOURCE); cairo_fill (mCairo); cairo_restore (mCairo); cairo_surface_destroy (imgsurf); } #endif XFree (image); // XXX this redraws the entire canvas element. we only need to // force a redraw of the affected rectangle. return Redraw (); }
static gboolean _label_expose(GtkWidget *widget, GdkEventExpose *event) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_LABEL(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON); // uninitialized? if(style->depth == -1) return FALSE; int state = gtk_widget_get_state(widget); int x = widget->allocation.x; int y = widget->allocation.y; int width = widget->allocation.width; int height = widget->allocation.height; // Formating the display of text and draw it... PangoLayout *layout; layout = gtk_widget_create_pango_layout(widget,NULL); pango_layout_set_font_description(layout,style->font_desc); const gchar *text=gtk_label_get_text(GTK_LABEL(widget)); pango_layout_set_text(layout,text,-1); GdkRectangle t= {x,y,x+width,y+height}; int pw,ph; pango_layout_get_pixel_size(layout,&pw,&ph); // Begin cairo drawing cairo_t *cr; cr = gdk_cairo_create(widget->window); cairo_set_source_rgba(cr, /* style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0,*/ 1,1,1, 0.10 ); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_UNDERLINED ) { cairo_move_to(cr,x,y+height-2); cairo_line_to(cr,x+width,y+height-2); cairo_stroke(cr); } else if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_BACKFILLED ) { cairo_rectangle(cr,x,y,width,height); cairo_fill(cr); } else if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_TAB ) { int rx=x,rw=pw+2; if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_RIGHT ) rx=x+width-pw-8; cairo_rectangle(cr,rx,y,rw+4,height-1); cairo_fill(cr); if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_RIGHT ) { // /| cairo_move_to(cr,x+width-rw-6,y); cairo_line_to(cr,x+width-rw-6-15,y+height-2); cairo_line_to(cr,x+width-rw-6,y+height-2); cairo_fill(cr); // hline cairo_move_to(cr,x,y+height-1); cairo_line_to(cr,x+width-rw-6,y+height-1); cairo_stroke(cr); } else { // | cairo_move_to(cr,x+rw+4,y); cairo_line_to(cr,x+rw+4+15,y+height-2); cairo_line_to(cr,x+rw+4,y+height-2); cairo_fill(cr); // hline cairo_move_to(cr,x+rw+4,y+height-1); cairo_line_to(cr,x+width,y+height-1); cairo_stroke(cr); } } cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); cairo_destroy(cr); // draw text int lx=x+4, ly=y+((height/2.0)-(ph/2.0)); if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_RIGHT ) lx=x+width-pw-6; else if( DTGTK_LABEL(widget)->flags&DARKTABLE_LABEL_ALIGN_CENTER ) lx=(width/2.0)-(pw/2.0); gtk_paint_layout(style,widget->window, state,TRUE,&t,widget,"label",lx,ly,layout); return FALSE; }
void draw_rect (drawctx_t *ctx, float x, float y, float w, float h, int fill) { cairo_rectangle (ctx->drawable, x, y, w, h); fill ? cairo_fill (ctx->drawable) : cairo_stroke (ctx->drawable); }
// ---------------------------------------------------------------------- void DrawableNodeDefault:: draw( cairo_t* cr, double t, const Context& C ) const throw(std::runtime_error) { Drawable::draw(cr,t,C); if( visible() ) { shawn::Vec pos = position(t); double size = node_properties().size(t); shawn::Vec bg; shawn::ConstTagHandle rtag = node().find_tag( "red" ); shawn::ConstTagHandle gtag = node().find_tag( "green" ); shawn::ConstTagHandle btag = node().find_tag( "blue" ); //if(rtag!=NULL && gtag!=NULL && btag!=NULL) //{ // double r = dynamic_cast<const shawn::DoubleTag*>( rtag.get() )->value(); // double g = dynamic_cast<const shawn::DoubleTag*>( gtag.get() )->value(); // double b = dynamic_cast<const shawn::DoubleTag*>( btag.get() )->value(); // // bg = shawn::Vec(r,g,b); //} //else //{ bg = node_properties().background(t); //} int shape = node_properties().shape(t); cairo_save(cr); cairo_translate(cr,pos.x(),pos.y()); cairo_set_line_width( cr, 0 ); switch(shape) { case 2: cairo_rectangle(cr,-size,-size,size*2,size*2); break; default: cairo_arc(cr,0.0,0.0,size,0,2.0*M_PI); break; } blend_set_color(cr,bg); cairo_fill(cr); if( C.draft_level()<2 ) { double lw = node_properties().line_width(t); shawn::Vec fg = node_properties().foreground(t); cairo_set_line_width( cr, lw ); switch(shape) { case 2: cairo_rectangle(cr,-size,-size,size*2,size*2); break; default: cairo_arc(cr,0.0,0.0,size,0,2.0*M_PI); break; } blend_set_color(cr,fg); cairo_stroke(cr); } cairo_restore(cr); } }
static void gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer, GtkWidget *widget, GimpTempBuf *temp_buf, gint temp_buf_x, gint temp_buf_y, gint channel, GimpViewBG inside_bg, GimpViewBG outside_bg, cairo_surface_t *surface, gint surface_width, gint surface_height) { cairo_t *cr; gint x, y; gint width, height; const Babl *temp_buf_format; gint temp_buf_width; gint temp_buf_height; g_return_if_fail (temp_buf != NULL); g_return_if_fail (surface != NULL); temp_buf_format = gimp_temp_buf_get_format (temp_buf); temp_buf_width = gimp_temp_buf_get_width (temp_buf); temp_buf_height = gimp_temp_buf_get_height (temp_buf); /* Here are the different cases this functions handles correctly: * 1) Offset temp_buf which does not necessarily cover full image area * 2) Color conversion of temp_buf if it is gray and image is color * 3) Background check buffer for transparent temp_bufs * 4) Using the optional "channel" argument, one channel can be extracted * from a multi-channel temp_buf and composited as a grayscale * Prereqs: * 1) Grayscale temp_bufs have bytes == {1, 2} * 2) Color temp_bufs have bytes == {3, 4} * 3) If image is gray, then temp_buf should have bytes == {1, 2} */ cr = cairo_create (surface); if (outside_bg == GIMP_VIEW_BG_CHECKS || inside_bg == GIMP_VIEW_BG_CHECKS) { if (! renderer->pattern) renderer->pattern = gimp_cairo_checkerboard_create (cr, GIMP_CHECK_SIZE_SM, gimp_render_light_check_color (), gimp_render_dark_check_color ()); } switch (outside_bg) { case GIMP_VIEW_BG_CHECKS: cairo_set_source (cr, renderer->pattern); break; case GIMP_VIEW_BG_WHITE: cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); break; } cairo_paint (cr); if (! gimp_rectangle_intersect (0, 0, surface_width, surface_height, temp_buf_x, temp_buf_y, temp_buf_width, temp_buf_height, &x, &y, &width, &height)) { cairo_destroy (cr); return; } if (inside_bg != outside_bg && babl_format_has_alpha (temp_buf_format) && channel == -1) { cairo_rectangle (cr, x, y, width, height); switch (inside_bg) { case GIMP_VIEW_BG_CHECKS: cairo_set_source (cr, renderer->pattern); break; case GIMP_VIEW_BG_WHITE: cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); break; } cairo_fill (cr); } if (babl_format_has_alpha (temp_buf_format) && channel == -1) { GeglBuffer *src_buffer; GeglBuffer *dest_buffer; cairo_surface_t *alpha_surface; alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); src_buffer = gimp_temp_buf_create_buffer (temp_buf); dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface); if (! renderer->profile_transform) gimp_view_renderer_transform_create (renderer, widget, src_buffer, dest_buffer); if (renderer->profile_transform) { gimp_gegl_convert_color_transform (src_buffer, GEGL_RECTANGLE (x - temp_buf_x, y - temp_buf_y, width, height), renderer->profile_src_format, dest_buffer, GEGL_RECTANGLE (0, 0, 0, 0), renderer->profile_dest_format, renderer->profile_transform); } else { gegl_buffer_copy (src_buffer, GEGL_RECTANGLE (x - temp_buf_x, y - temp_buf_y, width, height), GEGL_ABYSS_NONE, dest_buffer, GEGL_RECTANGLE (0, 0, 0, 0)); } g_object_unref (src_buffer); g_object_unref (dest_buffer); cairo_surface_mark_dirty (alpha_surface); cairo_translate (cr, x, y); cairo_rectangle (cr, 0, 0, width, height); cairo_set_source_surface (cr, alpha_surface, 0, 0); cairo_fill (cr); cairo_surface_destroy (alpha_surface); } else if (channel == -1) { GeglBuffer *src_buffer; GeglBuffer *dest_buffer; cairo_surface_flush (surface); src_buffer = gimp_temp_buf_create_buffer (temp_buf); dest_buffer = gimp_cairo_surface_create_buffer (surface); if (! renderer->profile_transform) gimp_view_renderer_transform_create (renderer, widget, src_buffer, dest_buffer); if (renderer->profile_transform) { gimp_gegl_convert_color_transform (src_buffer, GEGL_RECTANGLE (x - temp_buf_x, y - temp_buf_y, width, height), renderer->profile_src_format, dest_buffer, GEGL_RECTANGLE (x, y, 0, 0), renderer->profile_dest_format, renderer->profile_transform); } else { gegl_buffer_copy (src_buffer, GEGL_RECTANGLE (x - temp_buf_x, y - temp_buf_y, width, height), GEGL_ABYSS_NONE, dest_buffer, GEGL_RECTANGLE (x, y, 0, 0)); } g_object_unref (src_buffer); g_object_unref (dest_buffer); cairo_surface_mark_dirty (surface); } else { const Babl *fish; const guchar *src; guchar *dest; gint dest_stride; gint bytes; gint rowstride; gint i; cairo_surface_flush (surface); bytes = babl_format_get_bytes_per_pixel (temp_buf_format); rowstride = temp_buf_width * bytes; src = gimp_temp_buf_get_data (temp_buf) + ((y - temp_buf_y) * rowstride + (x - temp_buf_x) * bytes); dest = cairo_image_surface_get_data (surface); dest_stride = cairo_image_surface_get_stride (surface); dest += y * dest_stride + x * 4; fish = babl_fish (temp_buf_format, babl_format ("cairo-RGB24")); for (i = y; i < (y + height); i++) { const guchar *s = src; guchar *d = dest; gint j; for (j = x; j < (x + width); j++, d += 4, s += bytes) { if (bytes > 2) { guchar pixel[4] = { s[channel], s[channel], s[channel], 255 }; babl_process (fish, pixel, d, 1); } else { guchar pixel[2] = { s[channel], 255 }; babl_process (fish, pixel, d, 1); } } src += rowstride; dest += dest_stride; } cairo_surface_mark_dirty (surface); } cairo_destroy (cr); }
void cairo_context::fill() { cairo_fill(cairo_.get()); check_object_status_and_throw_exception(*this); }
/* This file is part of darktable, copyright (c) 2009--2011 johannes hanika. copyright (c) 2012 tobias ellinghaus. copyright (c) 2014 henrik andersson. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. darktable is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with darktable. If not, see <http://www.gnu.org/licenses/>. */ #include "bauhaus/bauhaus.h" #include "common/camera_control.h" #include "common/darktable.h" #include "common/image_cache.h" #include "common/mipmap_cache.h" #include "control/conf.h" #include "control/control.h" #include "control/jobs.h" #include "dtgtk/button.h" #include "gui/accelerators.h" #include "gui/gtk.h" #include "gui/guides.h" #include "libs/lib.h" #include "libs/lib_api.h" #include <gdk/gdkkeysyms.h> typedef enum dt_lib_live_view_flip_t { FLAG_FLIP_NONE = 0, FLAG_FLIP_HORIZONTAL = 1<<0, FLAG_FLIP_VERTICAL = 1<<1, FLAG_FLIP_BOTH = FLAG_FLIP_HORIZONTAL|FLAG_FLIP_VERTICAL } dt_lib_live_view_flip_t; typedef enum dt_lib_live_view_overlay_t { OVERLAY_NONE = 0, OVERLAY_SELECTED, OVERLAY_ID } dt_lib_live_view_overlay_t; #define HANDLE_SIZE 0.02 static const cairo_operator_t _overlay_modes[] = { CAIRO_OPERATOR_OVER, CAIRO_OPERATOR_XOR, CAIRO_OPERATOR_ADD, CAIRO_OPERATOR_SATURATE #if(CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)) , CAIRO_OPERATOR_MULTIPLY, CAIRO_OPERATOR_SCREEN, CAIRO_OPERATOR_OVERLAY, CAIRO_OPERATOR_DARKEN, CAIRO_OPERATOR_LIGHTEN, CAIRO_OPERATOR_COLOR_DODGE, CAIRO_OPERATOR_COLOR_BURN, CAIRO_OPERATOR_HARD_LIGHT, CAIRO_OPERATOR_SOFT_LIGHT, CAIRO_OPERATOR_DIFFERENCE, CAIRO_OPERATOR_EXCLUSION, CAIRO_OPERATOR_HSL_HUE, CAIRO_OPERATOR_HSL_SATURATION, CAIRO_OPERATOR_HSL_COLOR, CAIRO_OPERATOR_HSL_LUMINOSITY #endif }; DT_MODULE(1) typedef struct dt_lib_live_view_t { int imgid; int splitline_rotation; double overlay_x0, overlay_x1, overlay_y0, overlay_y1; double splitline_x, splitline_y; // 0..1 gboolean splitline_dragging; GtkWidget *live_view, *live_view_zoom, *rotate_ccw, *rotate_cw, *flip; GtkWidget *focus_out_small, *focus_out_big, *focus_in_small, *focus_in_big; GtkWidget *guide_selector, *flip_guides, *guides_widgets; GList *guides_widgets_list; GtkWidget *overlay, *overlay_id_box, *overlay_id, *overlay_mode, *overlay_splitline; } dt_lib_live_view_t; static void guides_presets_set_visibility(dt_lib_live_view_t *lib, int which) { if(which == 0) { gtk_widget_set_no_show_all(lib->guides_widgets, TRUE); gtk_widget_hide(lib->guides_widgets); gtk_widget_set_no_show_all(lib->flip_guides, TRUE); gtk_widget_hide(lib->flip_guides); } else { GtkWidget *widget = g_list_nth_data(lib->guides_widgets_list, which - 1); if(widget) { gtk_widget_set_no_show_all(lib->guides_widgets, FALSE); gtk_widget_show_all(lib->guides_widgets); gtk_stack_set_visible_child(GTK_STACK(lib->guides_widgets), widget); } else { gtk_widget_set_no_show_all(lib->guides_widgets, TRUE); gtk_widget_hide(lib->guides_widgets); } gtk_widget_set_no_show_all(lib->flip_guides, FALSE); gtk_widget_show_all(lib->flip_guides); } // TODO: add a support_flip flag to guides to hide the flip gui? } static void guides_presets_changed(GtkWidget *combo, dt_lib_live_view_t *lib) { int which = dt_bauhaus_combobox_get(combo); guides_presets_set_visibility(lib, which); } static void overlay_changed(GtkWidget *combo, dt_lib_live_view_t *lib) { int which = dt_bauhaus_combobox_get(combo); if(which == OVERLAY_NONE) { gtk_widget_set_visible(GTK_WIDGET(lib->overlay_mode), FALSE); gtk_widget_set_visible(GTK_WIDGET(lib->overlay_splitline), FALSE); } else { gtk_widget_set_visible(GTK_WIDGET(lib->overlay_mode), TRUE); gtk_widget_set_visible(GTK_WIDGET(lib->overlay_splitline), TRUE); } if(which == OVERLAY_ID) gtk_widget_set_visible(GTK_WIDGET(lib->overlay_id_box), TRUE); else gtk_widget_set_visible(GTK_WIDGET(lib->overlay_id_box), FALSE); } const char *name(dt_lib_module_t *self) { return _("live view"); } uint32_t views(dt_lib_module_t *self) { return DT_VIEW_TETHERING; } uint32_t container(dt_lib_module_t *self) { return DT_UI_CONTAINER_PANEL_RIGHT_CENTER; } void gui_reset(dt_lib_module_t *self) { } int position() { return 998; } void init_key_accels(dt_lib_module_t *self) { dt_accel_register_lib(self, NC_("accel", "toggle live view"), GDK_KEY_v, 0); dt_accel_register_lib(self, NC_("accel", "zoom live view"), GDK_KEY_z, 0); dt_accel_register_lib(self, NC_("accel", "rotate 90 degrees CCW"), 0, 0); dt_accel_register_lib(self, NC_("accel", "rotate 90 degrees CW"), 0, 0); dt_accel_register_lib(self, NC_("accel", "flip horizontally"), 0, 0); dt_accel_register_lib(self, NC_("accel", "move focus point in (big steps)"), 0, 0); dt_accel_register_lib(self, NC_("accel", "move focus point in (small steps)"), 0, 0); dt_accel_register_lib(self, NC_("accel", "move focus point out (small steps)"), 0, 0); dt_accel_register_lib(self, NC_("accel", "move focus point out (big steps)"), 0, 0); } void connect_key_accels(dt_lib_module_t *self) { dt_lib_live_view_t *lib = (dt_lib_live_view_t *)self->data; dt_accel_connect_button_lib(self, "toggle live view", GTK_WIDGET(lib->live_view)); dt_accel_connect_button_lib(self, "zoom live view", GTK_WIDGET(lib->live_view_zoom)); dt_accel_connect_button_lib(self, "rotate 90 degrees CCW", GTK_WIDGET(lib->rotate_ccw)); dt_accel_connect_button_lib(self, "rotate 90 degrees CW", GTK_WIDGET(lib->rotate_cw)); dt_accel_connect_button_lib(self, "flip horizontally", GTK_WIDGET(lib->flip)); dt_accel_connect_button_lib(self, "move focus point in (big steps)", GTK_WIDGET(lib->focus_in_big)); dt_accel_connect_button_lib(self, "move focus point in (small steps)", GTK_WIDGET(lib->focus_in_small)); dt_accel_connect_button_lib(self, "move focus point out (small steps)", GTK_WIDGET(lib->focus_out_small)); dt_accel_connect_button_lib(self, "move focus point out (big steps)", GTK_WIDGET(lib->focus_out_big)); } static void _rotate_ccw(GtkWidget *widget, gpointer user_data) { dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera; cam->live_view_rotation = (cam->live_view_rotation + 1) % 4; // 0 -> 1 -> 2 -> 3 -> 0 -> ... } static void _rotate_cw(GtkWidget *widget, gpointer user_data) { dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera; cam->live_view_rotation = (cam->live_view_rotation + 3) % 4; // 0 -> 3 -> 2 -> 1 -> 0 -> ... } // Congratulations to Simon for being the first one recognizing live view in a screen shot ^^ static void _toggle_live_view_clicked(GtkWidget *widget, gpointer user_data) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == TRUE) { if(dt_camctl_camera_start_live_view(darktable.camctl) == FALSE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE); } else { dt_camctl_camera_stop_live_view(darktable.camctl); } } // TODO: using a toggle button would be better, but this setting can also be changed by right clicking on the // canvas (src/views/capture.c). // maybe using a signal would work? i have no idea. static void _zoom_live_view_clicked(GtkWidget *widget, gpointer user_data) { dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera; if(cam->is_live_viewing) { cam->live_view_zoom = !cam->live_view_zoom; if(cam->live_view_zoom == TRUE) dt_camctl_camera_set_property_string(darktable.camctl, NULL, "eoszoom", "5"); else dt_camctl_camera_set_property_string(darktable.camctl, NULL, "eoszoom", "1"); } } static void _focus_button_clicked(GtkWidget *widget, gpointer user_data) { int focus = GPOINTER_TO_INT(user_data); dt_camctl_camera_set_property_choice(darktable.camctl, NULL, "manualfocusdrive", focus); } static void _toggle_flip_clicked(GtkWidget *widget, gpointer user_data) { dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera; cam->live_view_flip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); } static void _overlay_id_changed(GtkWidget *widget, gpointer user_data) { dt_lib_live_view_t *lib = (dt_lib_live_view_t *)user_data; lib->imgid = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)); dt_conf_set_int("plugins/lighttable/live_view/overlay_imgid", lib->imgid); } static void _overlay_mode_changed(GtkWidget *combo, gpointer user_data) { dt_conf_set_int("plugins/lighttable/live_view/overlay_mode", dt_bauhaus_combobox_get(combo)); } static void _overlay_splitline_changed(GtkWidget *combo, gpointer user_data) { dt_conf_set_int("plugins/lighttable/live_view/splitline", dt_bauhaus_combobox_get(combo)); } void gui_init(dt_lib_module_t *self) { self->data = calloc(1, sizeof(dt_lib_live_view_t)); // Setup lib data dt_lib_live_view_t *lib = self->data; lib->splitline_x = lib->splitline_y = 0.5; // Setup gui self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); GtkWidget *box; box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(self->widget), box, TRUE, TRUE, 0); lib->live_view = dtgtk_togglebutton_new(dtgtk_cairo_paint_eye, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); lib->live_view_zoom = dtgtk_button_new( dtgtk_cairo_paint_zoom, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); // TODO: see _zoom_live_view_clicked lib->rotate_ccw = dtgtk_button_new(dtgtk_cairo_paint_refresh, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); lib->rotate_cw = dtgtk_button_new(dtgtk_cairo_paint_refresh, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_UP); lib->flip = dtgtk_togglebutton_new(dtgtk_cairo_paint_flip, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_UP); gtk_box_pack_start(GTK_BOX(box), lib->live_view, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->live_view_zoom, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->rotate_ccw, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->rotate_cw, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->flip, TRUE, TRUE, 0); gtk_widget_set_tooltip_text(lib->live_view, _("toggle live view")); gtk_widget_set_tooltip_text(lib->live_view_zoom, _("zoom live view")); gtk_widget_set_tooltip_text(lib->rotate_ccw, _("rotate 90 degrees ccw")); gtk_widget_set_tooltip_text(lib->rotate_cw, _("rotate 90 degrees cw")); gtk_widget_set_tooltip_text(lib->flip, _("flip live view horizontally")); g_signal_connect(G_OBJECT(lib->live_view), "clicked", G_CALLBACK(_toggle_live_view_clicked), lib); g_signal_connect(G_OBJECT(lib->live_view_zoom), "clicked", G_CALLBACK(_zoom_live_view_clicked), lib); g_signal_connect(G_OBJECT(lib->rotate_ccw), "clicked", G_CALLBACK(_rotate_ccw), lib); g_signal_connect(G_OBJECT(lib->rotate_cw), "clicked", G_CALLBACK(_rotate_cw), lib); g_signal_connect(G_OBJECT(lib->flip), "clicked", G_CALLBACK(_toggle_flip_clicked), lib); // focus buttons box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(self->widget), box, TRUE, TRUE, 0); lib->focus_in_big = dtgtk_button_new(dtgtk_cairo_paint_solid_triangle, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_LEFT); lib->focus_in_small = dtgtk_button_new(dtgtk_cairo_paint_arrow, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_LEFT); // TODO icon not centered lib->focus_out_small = dtgtk_button_new(dtgtk_cairo_paint_arrow, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_RIGHT); // TODO same here lib->focus_out_big = dtgtk_button_new(dtgtk_cairo_paint_solid_triangle, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_RIGHT); gtk_box_pack_start(GTK_BOX(box), lib->focus_in_big, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->focus_in_small, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->focus_out_small, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(box), lib->focus_out_big, TRUE, TRUE, 0); gtk_widget_set_tooltip_text(lib->focus_in_big, _("move focus point in (big steps)")); gtk_widget_set_tooltip_text(lib->focus_in_small, _("move focus point in (small steps)")); gtk_widget_set_tooltip_text(lib->focus_out_small, _("move focus point out (small steps)")); gtk_widget_set_tooltip_text(lib->focus_out_big, _("move focus point out (big steps)")); // Near 3 g_signal_connect(G_OBJECT(lib->focus_in_big), "clicked", G_CALLBACK(_focus_button_clicked), GINT_TO_POINTER(2)); // Near 1 g_signal_connect(G_OBJECT(lib->focus_in_small), "clicked", G_CALLBACK(_focus_button_clicked), GINT_TO_POINTER(0)); // Far 1 g_signal_connect(G_OBJECT(lib->focus_out_small), "clicked", G_CALLBACK(_focus_button_clicked), GINT_TO_POINTER(4)); // Far 3 g_signal_connect(G_OBJECT(lib->focus_out_big), "clicked", G_CALLBACK(_focus_button_clicked), GINT_TO_POINTER(6)); // Guides lib->guide_selector = dt_bauhaus_combobox_new(NULL); dt_bauhaus_widget_set_label(lib->guide_selector, NULL, _("guides")); gtk_box_pack_start(GTK_BOX(self->widget), lib->guide_selector, TRUE, TRUE, 0); lib->guides_widgets = gtk_stack_new(); gtk_stack_set_homogeneous(GTK_STACK(lib->guides_widgets), FALSE); gtk_box_pack_start(GTK_BOX(self->widget), lib->guides_widgets, TRUE, TRUE, 0); dt_bauhaus_combobox_add(lib->guide_selector, _("none")); int i = 0; for(GList *iter = darktable.guides; iter; iter = g_list_next(iter), i++) { GtkWidget *widget = NULL; dt_guides_t *guide = (dt_guides_t *)iter->data; dt_bauhaus_combobox_add(lib->guide_selector, _(guide->name)); if(guide->widget) { // generate some unique name so that we can have the same name several times char name[5]; snprintf(name, sizeof(name), "%d", i); widget = guide->widget(NULL, guide->user_data); gtk_widget_show_all(widget); gtk_stack_add_named(GTK_STACK(lib->guides_widgets), widget, name); } lib->guides_widgets_list = g_list_append(lib->guides_widgets_list, widget); } gtk_widget_set_no_show_all(lib->guides_widgets, TRUE); gtk_widget_set_tooltip_text(lib->guide_selector, _("display guide lines to help compose your photograph")); g_signal_connect(G_OBJECT(lib->guide_selector), "value-changed", G_CALLBACK(guides_presets_changed), lib); lib->flip_guides = dt_bauhaus_combobox_new(NULL); dt_bauhaus_widget_set_label(lib->flip_guides, NULL, _("flip")); dt_bauhaus_combobox_add(lib->flip_guides, _("none")); dt_bauhaus_combobox_add(lib->flip_guides, _("horizontally")); dt_bauhaus_combobox_add(lib->flip_guides, _("vertically")); dt_bauhaus_combobox_add(lib->flip_guides, _("both")); gtk_widget_set_tooltip_text(lib->flip_guides, _("flip guides")); gtk_box_pack_start(GTK_BOX(self->widget), lib->flip_guides, TRUE, TRUE, 0); lib->overlay = dt_bauhaus_combobox_new(NULL); dt_bauhaus_widget_set_label(lib->overlay, NULL, _("overlay")); dt_bauhaus_combobox_add(lib->overlay, _("none")); dt_bauhaus_combobox_add(lib->overlay, _("selected image")); dt_bauhaus_combobox_add(lib->overlay, _("id")); gtk_widget_set_tooltip_text(lib->overlay, _("overlay another image over the live view")); g_signal_connect(G_OBJECT(lib->overlay), "value-changed", G_CALLBACK(overlay_changed), lib); gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay, TRUE, TRUE, 0); lib->overlay_id_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); GtkWidget *label = gtk_label_new(_("image id")); gtk_widget_set_halign(label, GTK_ALIGN_START); lib->overlay_id = gtk_spin_button_new_with_range(0, 1000000000, 1); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(lib->overlay_id), 0); gtk_widget_set_tooltip_text(lib->overlay_id, _("enter image id of the overlay manually")); g_signal_connect(G_OBJECT(lib->overlay_id), "value-changed", G_CALLBACK(_overlay_id_changed), lib); gtk_spin_button_set_value(GTK_SPIN_BUTTON(lib->overlay_id), dt_conf_get_int("plugins/lighttable/live_view/overlay_imgid")); gtk_box_pack_start(GTK_BOX(lib->overlay_id_box), label, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(lib->overlay_id_box), lib->overlay_id, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay_id_box, TRUE, TRUE, 0); gtk_widget_show(lib->overlay_id); gtk_widget_show(label); lib->overlay_mode = dt_bauhaus_combobox_new(NULL); dt_bauhaus_widget_set_label(lib->overlay_mode, NULL, _("overlay mode")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "normal")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "xor")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "add")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "saturate")); #if(CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0)) dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "multiply")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "screen")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "overlay")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "darken")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "lighten")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "color dodge")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "color burn")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "hard light")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "soft light")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "difference")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "exclusion")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL hue")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL saturation")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL color")); dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL luminosity")); #endif gtk_widget_set_tooltip_text(lib->overlay_mode, _("mode of the overlay")); dt_bauhaus_combobox_set(lib->overlay_mode, dt_conf_get_int("plugins/lighttable/live_view/overlay_mode")); g_signal_connect(G_OBJECT(lib->overlay_mode), "value-changed", G_CALLBACK(_overlay_mode_changed), lib); gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay_mode, TRUE, TRUE, 0); lib->overlay_splitline = dt_bauhaus_combobox_new(NULL); dt_bauhaus_widget_set_label(lib->overlay_splitline, NULL, _("split line")); dt_bauhaus_combobox_add(lib->overlay_splitline, _("off")); dt_bauhaus_combobox_add(lib->overlay_splitline, _("on")); gtk_widget_set_tooltip_text(lib->overlay_splitline, _("only draw part of the overlay")); dt_bauhaus_combobox_set(lib->overlay_splitline, dt_conf_get_int("plugins/lighttable/live_view/splitline")); g_signal_connect(G_OBJECT(lib->overlay_splitline), "value-changed", G_CALLBACK(_overlay_splitline_changed), lib); gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay_splitline, TRUE, TRUE, 0); gtk_widget_set_visible(GTK_WIDGET(lib->overlay_mode), FALSE); gtk_widget_set_visible(GTK_WIDGET(lib->overlay_id_box), FALSE); gtk_widget_set_visible(GTK_WIDGET(lib->overlay_splitline), FALSE); gtk_widget_set_no_show_all(GTK_WIDGET(lib->overlay_mode), TRUE); gtk_widget_set_no_show_all(GTK_WIDGET(lib->overlay_id_box), TRUE); gtk_widget_set_no_show_all(GTK_WIDGET(lib->overlay_splitline), TRUE); guides_presets_set_visibility(lib, 0); } void gui_cleanup(dt_lib_module_t *self) { // dt_lib_live_view_t *lib = self->data; // g_list_free(lib->guides_widgets_list); // INTENTIONAL. it's supposed to be leaky until lua is fixed. free(self->data); self->data = NULL; } void view_enter(struct dt_lib_module_t *self,struct dt_view_t *old_view,struct dt_view_t *new_view) { // disable buttons that won't work with this camera // TODO: initialize tethering mode outside of libs/camera.s so we can use darktable.camctl->active_camera // here dt_lib_live_view_t *lib = self->data; const dt_camera_t *cam = darktable.camctl->active_camera; if(cam == NULL) cam = darktable.camctl->wanted_camera; gboolean sensitive = cam && cam->can_live_view_advanced; gtk_widget_set_sensitive(lib->live_view_zoom, sensitive); gtk_widget_set_sensitive(lib->focus_in_big, sensitive); gtk_widget_set_sensitive(lib->focus_in_small, sensitive); gtk_widget_set_sensitive(lib->focus_out_big, sensitive); gtk_widget_set_sensitive(lib->focus_out_small, sensitive); } // TODO: find out where the zoom window is and draw overlay + grid accordingly #define MARGIN 20 #define BAR_HEIGHT 18 /* see libs/camera.c */ void gui_post_expose(dt_lib_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery) { dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera; dt_lib_live_view_t *lib = self->data; if(cam->is_live_viewing == FALSE || cam->live_view_zoom == TRUE) return; dt_pthread_mutex_lock(&cam->live_view_pixbuf_mutex); if(GDK_IS_PIXBUF(cam->live_view_pixbuf) == FALSE) { dt_pthread_mutex_unlock(&cam->live_view_pixbuf_mutex); return; } double w = width - (MARGIN * 2.0f); double h = height - (MARGIN * 2.0f) - BAR_HEIGHT; gint pw = gdk_pixbuf_get_width(cam->live_view_pixbuf); gint ph = gdk_pixbuf_get_height(cam->live_view_pixbuf); lib->overlay_x0 = lib->overlay_x1 = lib->overlay_y0 = lib->overlay_y1 = 0.0; gboolean use_splitline = (dt_bauhaus_combobox_get(lib->overlay_splitline) == 1); // OVERLAY int imgid = 0; switch(dt_bauhaus_combobox_get(lib->overlay)) { case OVERLAY_SELECTED: imgid = dt_view_tethering_get_selected_imgid(darktable.view_manager); break; case OVERLAY_ID: imgid = lib->imgid; break; } if(imgid > 0) { cairo_save(cr); const dt_image_t *img = dt_image_cache_testget(darktable.image_cache, imgid, 'r'); // if the user points at this image, we really want it: if(!img) img = dt_image_cache_get(darktable.image_cache, imgid, 'r'); int zoom = 1; float imgwd = 0.90f; if(zoom == 1) { imgwd = .97f; } dt_mipmap_buffer_t buf; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size(darktable.mipmap_cache, imgwd * w, imgwd * h); dt_mipmap_cache_get(darktable.mipmap_cache, &buf, imgid, mip, 0, 'r'); float scale = 1.0; 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.buf, CAIRO_FORMAT_RGB24, buf.width, buf.height, stride); if(zoom == 1) { scale = fminf(fminf(w, pw) / (float)buf.width, fminf(h, ph) / (float)buf.height); } else scale = fminf(w * imgwd / (float)buf.width, h * imgwd / (float)buf.height); } // draw centered and fitted: cairo_translate(cr, width / 2.0, (height + BAR_HEIGHT) / 2.0f); cairo_scale(cr, scale, scale); if(buf.buf) { cairo_translate(cr, -.5f * buf.width, -.5f * buf.height); if(use_splitline) { double x0, y0, x1, y1; switch(lib->splitline_rotation) { case 0: x0 = 0.0; y0 = 0.0; x1 = buf.width * lib->splitline_x; y1 = buf.height; break; case 1: x0 = 0.0; y0 = 0.0; x1 = buf.width; y1 = buf.height * lib->splitline_y; break; case 2: x0 = buf.width * lib->splitline_x; y0 = 0.0; x1 = buf.width; y1 = buf.height; break; case 3: x0 = 0.0; y0 = buf.height * lib->splitline_y; x1 = buf.width; y1 = buf.height; break; default: fprintf(stderr, "OMFG, the world will collapse, this shouldn't be reachable!\n"); return; } cairo_rectangle(cr, x0, y0, x1, y1); cairo_clip(cr); } 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); int overlay_modes_index = dt_bauhaus_combobox_get(lib->overlay_mode); if(overlay_modes_index >= 0) { cairo_operator_t mode = _overlay_modes[overlay_modes_index]; cairo_set_operator(cr, mode); } cairo_fill(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_surface_destroy(surface); } cairo_restore(cr); if(buf.buf) dt_mipmap_cache_release(darktable.mipmap_cache, &buf); if(img) dt_image_cache_read_release(darktable.image_cache, img); // ON CANVAS CONTROLS if(use_splitline) { float scale = fminf(1.0, fminf(w / pw, h / ph)); // image coordinates lib->overlay_x0 = 0.5 * (width - pw * scale); lib->overlay_y0 = 0.5 * (height - ph * scale + BAR_HEIGHT); lib->overlay_x1 = lib->overlay_x0 + pw * scale; lib->overlay_y1 = lib->overlay_y0 + ph * scale; // splitline position to absolute coords: double sl_x = lib->overlay_x0 + lib->splitline_x * pw * scale; double sl_y = lib->overlay_y0 + lib->splitline_y * ph * scale; int x0 = sl_x, y0 = 0.0, x1 = x0, y1 = height; if(lib->splitline_rotation % 2 != 0) { x0 = 0.0; y0 = sl_y; x1 = width; y1 = y0; } gboolean mouse_over_control = (lib->splitline_rotation % 2 == 0) ? (fabs(sl_x - pointerx) < 5) : (fabs(sl_y - pointery) < 5); cairo_save(cr); cairo_set_source_rgb(cr, .7, .7, .7); cairo_set_line_width(cr, (mouse_over_control ? 2.0 : 0.5)); cairo_move_to(cr, x0, y0); cairo_line_to(cr, x1, y1); cairo_stroke(cr); /* if mouse over control lets draw center rotate control, hide if split is dragged */ if(!lib->splitline_dragging && mouse_over_control) { cairo_set_line_width(cr, 0.5); double s = width * HANDLE_SIZE; dtgtk_cairo_paint_refresh(cr, sl_x - (s * 0.5), sl_y - (s * 0.5), s, s, 1); } cairo_restore(cr); } } // GUIDES if(cam->live_view_rotation % 2 == 1) { gint tmp = pw; pw = ph; ph = tmp; } float scale = 1.0; // if(cam->live_view_zoom == FALSE) // { if(pw > w) scale = w / pw; if(ph > h) scale = fminf(scale, h / ph); // } double sw = scale * pw; double sh = scale * ph; // draw guides int guide_flip = dt_bauhaus_combobox_get(lib->flip_guides); double left = (width - sw) * 0.5; double top = (height + BAR_HEIGHT - sh) * 0.5; double dashes = 5.0; cairo_save(cr); cairo_rectangle(cr, left, top, sw, sh); cairo_clip(cr); cairo_set_dash(cr, &dashes, 1, 0); // Move coordinates to local center selection. cairo_translate(cr, (sw / 2 + left), (sh / 2 + top)); // Flip horizontal. if(guide_flip & FLAG_FLIP_HORIZONTAL) cairo_scale(cr, -1, 1); // Flip vertical. if(guide_flip & FLAG_FLIP_VERTICAL) cairo_scale(cr, 1, -1); int which = dt_bauhaus_combobox_get(lib->guide_selector); dt_guides_t *guide = (dt_guides_t *)g_list_nth_data(darktable.guides, which - 1); if(guide) { guide->draw(cr, -sw / 2, -sh / 2, sw, sh, 1.0, guide->user_data); cairo_stroke_preserve(cr); cairo_set_dash(cr, &dashes, 0, 0); cairo_set_source_rgba(cr, .3, .3, .3, .8); cairo_stroke(cr); } cairo_restore(cr); dt_pthread_mutex_unlock(&cam->live_view_pixbuf_mutex); }
WindowPanel::WindowPanel() : auto_hide_(false) { ClutterLayoutManager * main_layout = clutter_bin_layout_new(CLUTTER_BIN_ALIGNMENT_FIXED, CLUTTER_BIN_ALIGNMENT_FIXED); actor_ = clutter_box_new(main_layout); ClutterActor * menu = clutter_cairo_texture_new(110, 22); clutter_actor_set_position(menu, 10.0f, 0.0f); cairo_t * context = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(menu)); cairo_move_to(context, 0.0, 0.0); cairo_line_to(context, 0.0, 19.0); cairo_curve_to(context, 1.0, 21.0, 2.0, 22.0, 3.0, 22.0); cairo_line_to(context, 107.0, 22.0); cairo_curve_to(context, 108.0, 22.0, 109.0, 21.0, 110.0, 19.0); cairo_line_to(context, 110.0, 0.0); cairo_close_path(context); cairo_set_source_rgb(context, 0.8, 0.8, 0.8); cairo_fill_preserve(context); cairo_set_line_width(context, 1.0); cairo_set_source_rgb(context, 0.0, 0.0, 0.0); cairo_stroke(context); cairo_select_font_face(context, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(context, 12.0); cairo_text_extents_t extents; cairo_text_extents(context, DISPLAY_NAME, &extents); cairo_move_to(context, 55.0 - ((extents.width / 2.0) + extents.x_bearing), 11.0 - ((extents.height / 2.0) + extents.y_bearing)); cairo_text_path(context, DISPLAY_NAME); cairo_set_source_rgb(context, 0.0, 0.0, 0.0); cairo_fill(context); cairo_destroy(context); clutter_box_pack(CLUTTER_BOX(actor_), menu, NULL, NULL); ClutterLayoutManager * controls_layout = clutter_box_layout_new(); clutter_box_layout_set_spacing(CLUTTER_BOX_LAYOUT(controls_layout), 10u); ClutterActor * controls = clutter_box_new(controls_layout); clutter_actor_add_constraint(controls, clutter_align_constraint_new(clutter_stage_get_default(), CLUTTER_ALIGN_X_AXIS, 0.95f)); clutter_actor_add_constraint(controls, clutter_bind_constraint_new(clutter_stage_get_default(), CLUTTER_BIND_Y, 5.0f)); fullscreen_button_ = clutter_cairo_texture_new(18, 16); clutter_actor_set_reactive(fullscreen_button_, TRUE); g_signal_connect(fullscreen_button_, "button-press-event", G_CALLBACK(fullscreen_clicked_cb), this); g_signal_connect(fullscreen_button_, "enter-event", G_CALLBACK(actor_highlight_on_cb), fullscreen_button_); g_signal_connect(fullscreen_button_, "leave-event", G_CALLBACK(actor_highlight_off_cb), fullscreen_button_); clutter_box_pack(CLUTTER_BOX(controls), fullscreen_button_, NULL, NULL); close_button_ = clutter_cairo_texture_new(15, 15); context = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(close_button_)); cairo_move_to(context, 1.0, 3.0); cairo_line_to(context, 3.0, 1.0); cairo_line_to(context, 8.0, 6.0); cairo_line_to(context, 13.0, 1.0); cairo_line_to(context, 15.0, 3.0); cairo_line_to(context, 10.0, 8.0); cairo_line_to(context, 15.0, 13.0); cairo_line_to(context, 13.0, 15.0); cairo_line_to(context, 8.0, 10.0); cairo_line_to(context, 3.0, 15.0); cairo_line_to(context, 1.0, 13.0); cairo_line_to(context, 6.0, 8.0); cairo_close_path(context); cairo_set_source_rgb(context, 1.0, 1.0, 1.0); cairo_fill_preserve(context); cairo_set_line_width(context, 1.0); cairo_set_source_rgb(context, 0.0, 0.0, 0.0); cairo_stroke(context); cairo_destroy(context); clutter_actor_set_reactive(close_button_, TRUE); g_signal_connect(close_button_, "button-press-event", G_CALLBACK(close_clicked_cb), NULL); g_signal_connect(close_button_, "enter-event", G_CALLBACK(actor_highlight_on_cb), close_button_); g_signal_connect(close_button_, "leave-event", G_CALLBACK(actor_highlight_off_cb), close_button_); clutter_box_pack(CLUTTER_BOX(controls), close_button_, NULL, NULL); draw_window_controls(); clutter_box_pack(CLUTTER_BOX(actor_), controls, NULL, NULL); g_signal_connect(clutter_stage_get_default(), "fullscreen", G_CALLBACK(fullscreen_status_changed_cb), this); g_signal_connect(clutter_stage_get_default(), "unfullscreen", G_CALLBACK(fullscreen_status_changed_cb), this); g_signal_connect(clutter_stage_get_default(), "motion-event", G_CALLBACK(show_panel_cb), this); }
void SaveSummary(const std::string &fname, Result &result, Config &config) { #if 0 const float fnorm = 2.f / sqrtf(result.npoints); const float rnorm = 1.f / sqrtf(2.f / (SQRT3 * result.npoints)); const int csize = 512; // Composition cell size const double dashes[] = { 6.0, 3.0 }; cairo_surface_t *surface = cairo_pdf_surface_create(fname.c_str(), 2*csize, 1.5*csize); cairo_pdf_surface_restrict_to_version(surface, CAIRO_PDF_VERSION_1_4); cairo_t *cr = cairo_create(surface); unsigned char *imgdata = NULL; cairo_surface_t *image = NULL; // Draw points const float radius = 2.0; cairo_identity_matrix(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1); for (int i = 0; i < result.points.size(); ++i) { float x = result.points[i].x * csize; float y = (1.f - result.points[i].y) * csize; cairo_arc(cr, x, y, radius, 0, TWOPI); cairo_fill(cr); } // Draw radial power reference level cairo_identity_matrix(cr); cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1); cairo_set_line_width(cr, 1.0); cairo_set_dash(cr, dashes, 2, 0); const float rpref = 1.f - (1.f - config.fymin) / (config.fymax - config.fymin); cairo_move_to(cr, csize, csize + rpref*csize/2); cairo_line_to(cr, 2*csize, csize + rpref*csize/2); cairo_stroke(cr); // Draw radial power cairo_identity_matrix(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_line_width(cr, 1.0); cairo_set_dash(cr, NULL, 0, 0); for (int i = 0; i < result.rp.size(); ++i) { float x = i / (float) result.rp.size(); float y = 1.f - (result.rp[i] - config.fymin) / (config.fymax - config.fymin); Clamp01(y); if (i == 0) cairo_move_to(cr, csize + x*csize, csize + y*csize/2); else cairo_line_to(cr, csize + x*csize, csize + y*csize/2); } cairo_stroke(cr); // Draw spectrum int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, result.spectrum.width); result.spectrum.GetRGBA(imgdata); image = cairo_image_surface_create_for_data(imgdata, CAIRO_FORMAT_RGB24, result.spectrum.width, result.spectrum.height, stride); cairo_identity_matrix(cr); cairo_translate(cr, csize, 0); cairo_scale(cr, csize / (float) result.spectrum.width, csize / (float) result.spectrum.height); cairo_set_source_surface(cr, image, 0, 0); cairo_paint(cr); // Draw RDF reference level cairo_identity_matrix(cr); cairo_set_source_rgba(cr, 0.6, 0.6, 0.6, 1); cairo_set_line_width(cr, 1.0); cairo_set_dash(cr, dashes, 2, 0); const float rdfref = 1.f - (1.f - config.rymin) / (config.rymax - config.rymin); cairo_move_to(cr, 0, csize + rdfref*csize/2); cairo_line_to(cr, csize, csize + rdfref*csize/2); cairo_stroke(cr); // Draw RDF cairo_identity_matrix(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_line_width(cr, 1.0); cairo_set_dash(cr, NULL, 0, 0); for (int i = 0; i < result.rdf.size(); ++i) { float x = i / (float) result.rdf.size(); float y = 1.f - (result.rdf[i] - config.rymin) / (config.rymax - config.rymin); Clamp01(y); if (i == 0) cairo_move_to(cr, x*csize, csize + y*csize/2); else cairo_line_to(cr, x*csize, csize + y*csize/2); } cairo_stroke(cr); // Draw separators cairo_identity_matrix(cr); cairo_set_line_width(cr, 1.0); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_move_to(cr, 0, csize); cairo_line_to(cr, 2*csize, csize); cairo_stroke(cr); cairo_move_to(cr, csize, 0); cairo_line_to(cr, csize, 1.5*csize); cairo_stroke(cr); // Draw labels cairo_identity_matrix(cr); cairo_set_font_size(cr, 12.0); cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_move_to(cr, 0.0125 * csize, 1.025 * csize); cairo_show_text(cr, "RDF"); cairo_stroke(cr); cairo_move_to(cr, 1.0125 * csize, 1.025 * csize); cairo_show_text(cr, "Power Spectrum"); cairo_stroke(cr); // Draw stats box #ifdef PSA_HAS_CGAL int nlines = 5; #else int nlines = 4; #endif nlines += (result.nsets > 1); double offset = 0.03; double bsize[] = { 0.33 * csize, (nlines * offset + 0.01) * csize }; double banchor = 0.0125 * csize; cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.7); cairo_rectangle(cr, banchor, banchor, bsize[0], bsize[1]); cairo_fill(cr); // Draw stats and corresponding labels cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); cairo_set_font_size(cr, 12.0); cairo_select_font_face(cr, "monospace", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); const int len = 128; char label[len]; double tanchor[2] = { 1.75 * banchor, 0.9 * banchor }; int i = 1; if (result.nsets > 1) { snprintf(label, len, "Averaged over %d sets", result.nsets); cairo_move_to(cr, tanchor[0], tanchor[1] + i * offset * csize); cairo_show_text(cr, label); ++i; } snprintf(label, len, "Gbl. Mindist %.5f", result.stats.mindist * rnorm); cairo_move_to(cr, tanchor[0], tanchor[1] + i * offset * csize); ++i; cairo_show_text(cr, label); snprintf(label, len, "Avg. Mindist %.5f", result.stats.avgmindist * rnorm); cairo_move_to(cr, tanchor[0], tanchor[1] + i * offset * csize); ++i; cairo_show_text(cr, label); #ifdef PSA_HAS_CGAL snprintf(label, len, "Orient. order %.5f", result.stats.orientorder); cairo_move_to(cr, tanchor[0], tanchor[1] + i * offset * csize); ++i; cairo_show_text(cr, label); #endif snprintf(label, len, "Eff. Nyquist %.5f", result.stats.effnyquist * fnorm); cairo_move_to(cr, tanchor[0], tanchor[1] + i * offset * csize); ++i; cairo_show_text(cr, label); snprintf(label, len, "Oscillations %.5f", result.stats.oscillations); cairo_move_to(cr, tanchor[0], tanchor[1] + i * offset * csize); ++i; cairo_show_text(cr, label); cairo_stroke(cr); // Save and clean up cairo_show_page(cr); cairo_surface_destroy(image); if (imgdata) delete[] imgdata; cairo_destroy(cr); cairo_surface_destroy(surface); #endif }
static void do_drawing(cairo_t *cr) { double angle[TC + 1]; double X[TC + 1]; double Y[TC + 1]; int i; double degree; for (i = 0; i < TC; i++) { degree = 360/TC * i; angle[i] = 1.0*(270 + degree) * (M_PI)/180.0; X[i] = MID_X + sin(degree * M_PI /180.0) * MID_R; Y[i] = MID_Y - cos(degree * M_PI /180.0) * MID_R; } for (i = 0; i < TC; i++) { float red, green; if (counts[i] > 2500) { red = 1.0; green = 1.0*(5000-counts[i]) /2500; } else { green = 1.0; red = 1.0*(counts[i]) / 2500; } cairo_set_source_rgba (cr, red, green, 0, 1); cairo_move_to (cr, MID_X, MID_Y); cairo_line_to (cr, X[i], Y[i]); cairo_arc (cr, MID_X, MID_Y, MID_R, angle[i], angle[(i+1)%TC]); cairo_line_to (cr, MID_X, MID_Y); cairo_fill (cr); } cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_set_line_width (cr, 1.0); for (i = 0; i < TC; i++) { cairo_move_to (cr, MID_X, MID_Y); cairo_line_to (cr, X[i], Y[i]); cairo_arc (cr, MID_X, MID_Y, MID_R, angle[i], angle[(i+1)%TC]); cairo_line_to (cr, MID_X, MID_Y); cairo_stroke (cr); } cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 20.0); for (i = 0; i < TC; i++) { float x, y; gchar *hour; degree = 360/TC * i; x = MID_X + sin(degree * M_PI /180.0) * MID_R * 1.2 - 5; y = MID_Y - cos(degree * M_PI /180.0) * MID_R * 1.2 + 5; cairo_set_font_size (cr, 20.0); cairo_set_source_rgba (cr, 0, 0, 0, 1); cairo_move_to (cr, x, y); hour = g_strdup_printf ("%d", i); cairo_show_text (cr, hour); if (i == 8) { cairo_set_source_rgba (cr, 1, 0, 0, 1); cairo_set_font_size (cr, 15.0); cairo_move_to (cr, x + 20, y); cairo_show_text (cr, "开始上班"); } else if (i == 13) { cairo_set_source_rgba (cr, 1, 0, 0, 1); cairo_set_font_size (cr, 15.0); cairo_move_to (cr, x + 5, y + 20); cairo_show_text (cr, "午饭时间"); } else if (i == 19) { cairo_set_source_rgba (cr, 1, 0, 0, 1); cairo_set_font_size (cr, 15.0); cairo_move_to (cr, x - 10, y - 20); cairo_show_text (cr, "回家晚饭"); } } gchar *note[6] = {"微信群统计", "数据来源:", "真实群一年来", "4万多条聊天记录", "绿色表示发言较少", "红色表示发言较多"}; cairo_set_font_size (cr, 20); cairo_move_to (cr, 700, 180); cairo_show_text (cr, note[0]); for (i = 1; i < 6; i++) { cairo_move_to (cr, 700, 200 + i * 30); cairo_show_text (cr, note[i]); } }
void plot_view::render(cairo_t *cr, const plot_view::bounds_t &bounds) { cairo_matrix_t original_matrix; cairo_get_matrix(cr, &original_matrix); // purple background for padding checking //cairo_set_source_rgb(cr, 0.50, 0.00, 0.50); //cairo_rectangle(cr, bounds.x, bounds.y, bounds.width, bounds.height); //cairo_fill(cr); double pad_left = width * pad_left_factor; double pad_top = height * pad_top_factor; double pad_bottom = height * pad_bottom_factor; double pad_right = width * pad_right_factor; // compute bounds for subclasses to render content into bounds_t content_bounds; content_bounds.x = bounds.x + pad_left; content_bounds.y = bounds.y + pad_top; content_bounds.width = bounds.width - pad_right - pad_left; content_bounds.height = bounds.height - pad_bottom - pad_top; cairo_text_extents_t title_extents; cairo_text_extents_t subtitle_extents; double font_size_title = title_font_size; cairo_translate(cr, bounds.x, bounds.y); double title_base_y = 0.0; if(title_on_bottom) { title_base_y = bounds.height - pad_bottom; } cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, font_size_title); cairo_set_source_rgb(cr, 0, 0, 0); cairo_text_extents(cr, title.c_str(), &title_extents); // Is the title too wide? double title_max_width = bounds.width * title_max_width_ratio; if(title_extents.width > title_max_width) { // scale the font size accordingly font_size_title *= title_max_width / title_extents.width; cairo_set_font_size(cr, font_size_title); cairo_text_extents(cr, title.c_str(), &title_extents); } // derive subtitle size and measure double font_size_subtitle = font_size_title * subtitle_font_size_factor; cairo_set_font_size(cr, font_size_subtitle); cairo_text_extents(cr, subtitle.c_str(), &subtitle_extents); double intertitle_padding = subtitle_extents.height * subtitle_y_pad_factor; cairo_set_font_size(cr, font_size_title); double title_padded_height = title_extents.height * title_y_pad_factor; // render title text cairo_move_to(cr, (bounds.width - title_extents.width) / 2.0, title_base_y + title_extents.height + (title_padded_height - title_extents.height) / 2); cairo_show_text(cr, title.c_str()); // render subtitle text cairo_set_font_size(cr, font_size_subtitle); cairo_move_to(cr, (bounds.width - subtitle_extents.width) / 2.0, title_base_y + ((title_padded_height - title_extents.height) / 2) + title_extents.height + intertitle_padding + subtitle_extents.height); cairo_show_text(cr, subtitle.c_str()); // render axis labels cairo_matrix_t unrotated_matrix; cairo_get_matrix(cr, &unrotated_matrix); cairo_text_extents_t axis_label_extents; cairo_set_font_size(cr, y_axis_font_size); cairo_text_extents(cr, y_label.c_str(), &axis_label_extents); double y_label_x = 0.0 + axis_label_extents.height; double y_label_centering_pad = ((content_bounds.height - axis_label_extents.width) / 2.0); double y_label_y = pad_top + y_label_centering_pad + axis_label_extents.width; cairo_move_to(cr, y_label_x, y_label_y); cairo_rotate(cr, -M_PI / 2.0); cairo_show_text(cr, y_label.c_str()); cairo_set_matrix(cr, &unrotated_matrix); // add y axis decoration // TODO not implemented for brevity cairo_set_font_size(cr, x_axis_font_size); cairo_text_extents(cr, x_label.c_str(), &axis_label_extents); double x_label_centering_pad = (content_bounds.width - axis_label_extents.width) / 2.0; double x_label_x = pad_left + x_label_centering_pad; double x_label_y = bounds.height; cairo_move_to(cr, x_label_x, x_label_y); cairo_show_text(cr, x_label.c_str()); // add x axis decoration if(x_axis_decoration == AXIS_SPAN_ARROW || x_axis_decoration == AXIS_SPAN_STOP) { double angle = span_arrow_angle; double line_width = x_axis_font_size * text_line_base_width; double tip_length = line_width * 10.0; if(x_axis_decoration == AXIS_SPAN_STOP) { angle = span_stop_angle; tip_length = line_width * 5.0; } double gap = line_width * 10.0; double x = x_label_x - gap; double y = x_label_y - axis_label_extents.height / 3.0; double pr_x, pr_y; // previous x and y positions // left of label cairo_move_to(cr, x, y); pr_x = x; pr_y = y; x = pr_x - (x_label_centering_pad - gap); y = pr_y; cairo_line_to(cr, x, y); pr_x = x; pr_y = y; x = pr_x + tip_length * sin(angle + M_PI / 2.0); y = pr_y + tip_length * cos(angle + M_PI / 2.0); cairo_line_to(cr, x, y); cairo_move_to(cr, pr_x, pr_y); x = pr_x + tip_length * sin(-angle + M_PI / 2.0); y = pr_y + tip_length * cos(-angle + M_PI / 2.0); cairo_line_to(cr, x, y); // right of label x = x_label_x + axis_label_extents.width + gap; y = x_label_y - axis_label_extents.height / 3.0; cairo_move_to(cr, x, y); pr_x = x; pr_y = y; x = pr_x + (x_label_centering_pad - gap); y = pr_y; cairo_line_to(cr, x, y); pr_x = x; pr_y = y; x = pr_x + tip_length * sin(angle - M_PI / 2.0); y = pr_y - tip_length * cos(angle - M_PI / 2.0); cairo_line_to(cr, x, y); cairo_move_to(cr, pr_x, pr_y); x = pr_x + tip_length * sin(-angle - M_PI / 2.0); y = pr_y - tip_length * cos(-angle - M_PI / 2.0); cairo_line_to(cr, x, y); cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); cairo_set_line_width(cr, line_width); cairo_stroke(cr); } // render ticks double tick_length = bounds.width * tick_length_factor; double tick_width = bounds.height * tick_width_factor; // y ticks (packet counts) cairo_set_font_size(cr, y_tick_font_size); // translate down so the top of the window aligns with the top of // the graph itself cairo_translate(cr, 0, pad_top); double y_height = bounds.height - pad_bottom - pad_top; double y_tick_spacing = 0.0; if(y_tick_labels.size() > 1) { y_tick_spacing = y_height / (double) (y_tick_labels.size() - 1); } for(size_t ii = 0; ii < y_tick_labels.size(); ii++) { cairo_text_extents_t label_extents; double yy = y_height - (((double) ii) * y_tick_spacing); string label = y_tick_labels.at(ii); cairo_text_extents(cr, label.c_str(), &label_extents); cairo_move_to(cr, (pad_left - tick_length - label_extents.width), yy + (label_extents.height / 2)); cairo_show_text(cr, label.c_str()); // tick mark cairo_rectangle(cr, pad_left - tick_length, yy - (tick_width / 2), tick_length, tick_width); cairo_fill(cr); } // right ticks (packet counts) cairo_set_font_size(cr, right_tick_font_size); if(right_tick_labels.size() > 1) { y_tick_spacing = y_height / (double) (right_tick_labels.size() - 1); } for(size_t ii = 0; ii < right_tick_labels.size(); ii++) { cairo_text_extents_t label_extents; double yy = y_height - (((double) ii) * y_tick_spacing); string label = right_tick_labels.at(ii); cairo_text_extents(cr, label.c_str(), &label_extents); cairo_move_to(cr, (bounds.width - pad_right + tick_length), yy + (label_extents.height / 2)); cairo_show_text(cr, label.c_str()); // tick mark cairo_rectangle(cr, bounds.width - pad_right, yy - (tick_width / 2), tick_length, tick_width); cairo_fill(cr); } cairo_set_matrix(cr, &original_matrix); cairo_translate(cr, bounds.x, bounds.y); // x ticks (time) // TODO prevent overlap cairo_set_font_size(cr, x_tick_font_size); cairo_translate(cr, pad_left, bounds.height - pad_bottom); double x_width = bounds.width - (pad_right + pad_left); double x_tick_spacing = x_width / (x_tick_labels.size() - 1); for(size_t ii = 0; ii < x_tick_labels.size(); ii++) { cairo_text_extents_t label_extents; double xx = ii * x_tick_spacing; const char *label = x_tick_labels.at(ii).c_str(); cairo_text_extents(cr, label, &label_extents); double pad = ((label_extents.height * x_tick_label_pad_factor) - label_extents.height) / 2; // prevent labels from running off the edge of the image double label_x = xx - (label_extents.width / 2.0); label_x = max(label_x, - pad_left); label_x = min(bounds.width - label_extents.width, label_x); cairo_move_to(cr, label_x, label_extents.height + pad); cairo_show_text(cr, label); } cairo_set_matrix(cr, &original_matrix); cairo_translate(cr, bounds.x, bounds.y); // render legend cairo_text_extents_t legend_label_extents; double chip_length = 0.0; // derive color chip size from largest label height for(size_t ii = 0; ii < legend.size(); ii++) { const legend_entry_t &entry = legend.at(ii); cairo_text_extents(cr, entry.label.c_str(), &legend_label_extents); chip_length = max(chip_length, legend_label_extents.height); } chip_length *= legend_chip_factor; cairo_translate(cr, bounds.width - (pad_right * 0.9), pad_top); cairo_set_font_size(cr, legend_font_size); for(size_t ii = 0; ii < legend.size(); ii++) { const legend_entry_t &entry = legend.at(ii); // chip cairo_set_source_rgb(cr, entry.color.r, entry.color.g, entry.color.b); cairo_rectangle(cr, 0, 0, chip_length, chip_length); cairo_fill(cr); // label cairo_set_source_rgb(cr, 0, 0, 0); cairo_text_extents(cr, entry.label.c_str(), &legend_label_extents); cairo_move_to(cr, chip_length * 1.2, (chip_length / 2.0) + (legend_label_extents.height / 2.0)); cairo_show_text(cr, entry.label.c_str()); // translate down for the next legend entry cairo_translate(cr, 0, chip_length); } cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_matrix(cr, &original_matrix); // render axes and update content bounds double axis_width = bounds.height * axis_thickness_factor; cairo_rectangle(cr, content_bounds.x, content_bounds.y, axis_width, content_bounds.height); cairo_rectangle(cr, content_bounds.x, content_bounds.y + (content_bounds.height - axis_width), content_bounds.width, axis_width); // if there are right hand ticks, draw a right-hand axis if(right_tick_labels.size() > 0) { cairo_rectangle(cr, content_bounds.x + content_bounds.width - axis_width, content_bounds.y, axis_width, content_bounds.height); } cairo_fill(cr); content_bounds.x += axis_width; content_bounds.width -= axis_width; if(right_tick_labels.size() > 0) { content_bounds.width -= axis_width; } content_bounds.height -= axis_width; // render data! render_data(cr, content_bounds); }
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); }
/** * ppg_ruler_draw_ruler: * @ruler: (in): A #PpgRuler. * * Draws the background of the ruler containing the time values and ticks * to an offscreen pixmap that can be blitted to the widget during * "expose-event". * * Returns: None. * Side effects: None. */ static void ppg_ruler_draw_ruler (PpgRuler *ruler) { PpgRulerPrivate *priv; GtkAllocation alloc; PangoLayout *layout; cairo_t *cr; GtkStyle *style; GdkColor text_color; gint text_width; gint text_height; gdouble every = 1.0; gdouble n_seconds; gdouble v; gdouble p; gint pw; gint ph; gint x; gint xx; gint n; gint z = 0; g_return_if_fail(PPG_IS_RULER(ruler)); priv = ruler->priv; gtk_widget_get_allocation(GTK_WIDGET(ruler), &alloc); style = gtk_widget_get_style(GTK_WIDGET(ruler)); cr = cairo_create(priv->ruler); cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle(cr, 0, 0, alloc.width, alloc.height); cairo_fill(cr); cairo_restore(cr); text_color = style->text[GTK_STATE_NORMAL]; cairo_set_line_width(cr, 1.0); gdk_cairo_set_source_color(cr, &text_color); layout = pango_cairo_create_layout(cr); pango_layout_set_font_description(layout, priv->font_desc); pango_layout_set_markup(layout, "00:00:00.000", -1); pango_layout_get_pixel_size(layout, &text_width, &text_height); text_width += 5; n_seconds = priv->upper - priv->lower; if ((alloc.width / n_seconds) < text_width) { every = ceil(text_width / (alloc.width / n_seconds)); } for (v = floor(priv->lower); v < priv->upper; v += every) { gdk_cairo_set_source_color(cr, &text_color); x = get_x_offset(priv, &alloc, v); cairo_move_to(cr, x + 0.5, alloc.height - 1.5); cairo_line_to(cr, x + 0.5, 0.5); /* * Mini lines. */ for (p = v, n = 0, z = 0; p < v + every; p += (every / 10), n++, z++) { if (n == 0 || n == 10) { continue; } xx = get_x_offset(priv, &alloc, p); cairo_move_to(cr, xx + 0.5, alloc.height - 1.5); if (z % 2 == 0) { cairo_line_to(cr, xx + 0.5, text_height + 8.5); } else { cairo_line_to(cr, xx + 0.5, text_height + 5.5); } } cairo_stroke(cr); cairo_move_to(cr, x + 1.5, 1.5); ppg_ruler_update_layout_text(ruler, layout, CLAMP(v, priv->lower, priv->upper)); /* * If there is enough room to draw this layout before we get to the * next layout, then draw it. */ pango_layout_get_pixel_size(layout, &pw, &ph); if ((x + pw) < get_x_offset(priv, &alloc, floor(v) + every)) { pango_cairo_show_layout(cr, layout); } } g_object_unref(layout); cairo_destroy(cr); }
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); }