static void moblin_netbook_draw_check (GtkStyle *style, GdkWindow *window, GtkStateType state_type, GtkShadowType shadow_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, gint x, gint y, gint width, gint height) { cairo_t *cr; gint radius = MOBLIN_NETBOOK_STYLE (style)->radius; DEBUG; cr = moblin_netbook_cairo_create (window, area); cairo_set_line_width (cr, 1.0); if (shadow_type == GTK_SHADOW_IN && state_type != GTK_STATE_INSENSITIVE) { state_type = GTK_STATE_SELECTED; } /* we don't support anything other than 15x15 */ width = 15; height = 15; moblin_netbook_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height - 1, radius); /* fill the background */ gdk_cairo_set_source_color (cr, &style->base[state_type]); cairo_fill_preserve (cr); /* draw the border */ moblin_netbook_set_border_color (cr, style, state_type); cairo_stroke (cr); gdk_cairo_set_source_color (cr, &style->text[state_type]); /* draw a tick when checked */ if (shadow_type == GTK_SHADOW_IN) { cairo_translate (cr, x, y); cairo_move_to (cr, 3, 6); cairo_line_to (cr, 6, 9); cairo_line_to (cr, 12, 3); cairo_line_to (cr, 12, 6); cairo_line_to (cr, 6, 12); cairo_line_to (cr, 3, 9); cairo_line_to (cr, 3, 6); cairo_fill (cr); } cairo_destroy (cr); }
/* Set gadget's background */ gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, block_notes_core_s *core) { cairo_t *cr; double x0 = 5.0; double y0 = 12.0; double rect_width = core->width - 10; double rect_height = core->height - 15; double radius = 30; double x1,y1; cr = gdk_cairo_create (widget->window); /* settaggi per rendere trasparente lo sfondo */ cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 0.0f); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); x1 = x0 + rect_width; y1 = y0 + rect_height; if (!rect_width || !rect_height) return; cairo_move_to (cr, x0, y0 + radius); cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0); cairo_line_to (cr, x1 - radius, y0); cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius); cairo_line_to (cr, x1 , y1 - radius); cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1); cairo_line_to (cr, x0 + radius, y1); cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius); cairo_close_path (cr); cairo_set_source_rgba (cr, (float) core->gadget.red / 65535.0, (float) core->gadget.green / 65535.0, (float) core->gadget.blue / 65535.0, 1.0); cairo_fill_preserve (cr); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.7); cairo_set_source_rgba (cr, (float) core->border.red / 65535.0, (float) core->border.green / 65535.0, (float) core->border.blue / 65535.0, core->border_transparency); cairo_set_line_width (cr, 3.0); cairo_stroke (cr); cairo_destroy (cr); return FALSE; }
/*! \brief Draw a box on the screen. * \par Function Description * This function is used to draw a box on screen. The box is described in * the OBJECT which is referred by <B>o_current</B>. The box is displayed * according to the current state, described in the GSCHEM_TOPLEVEL object * pointed by <B>w_current</B>. * * It first checks if the OBJECT pointed is valid or not. If not it * returns and do not output anything. That should never happen though. * * \param [in] w_current The GSCHEM_TOPLEVEL object. * \param [in] o_current BOX OBJECT to draw. */ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current) { int angle1, pitch1, angle2, pitch2; FILL_FUNC fill_func; if (o_current->box == NULL) { return; } /* * The drawing of the box is divided in two steps : first step is to * draw the outline, the second is to draw the filling pattern inside * (if any). Finally the function takes care of the grips. */ /* * The values describing the line type are extracted from the <B>o_current</B> * pointed structure. These are the width of the line, the field called * length and the field called space and the desired end type for the line. * * Depending on the type of the line that has to be used to draw the box * the appropriate function is called. Values of space and length are * adapted to the type of line. The possible functions are the following : * #o_box_draw_solid(), #o_box_draw_dotted(), #o_box_draw_dashed() and * #o_box_draw_phantom(). * * The combination <B>length</B> == 0 and <B>space</B> == 0 is avoided as it * lead to an endless loop in function called after. If such a case is * encountered the box is drawn as a solid box independently of its * initial type. */ /* * The values needed for the fill operation are taken from the * <B>o_current</B> pointed OBJECT. It include the type of fill required, * the width of the lines (if the fill use line) and angles and pitchs * for hatch based filling. * * Once again the width of the line is important as if it is equal to * 0 it may not be displayed. That is definetely not what we are looking for. * * Depending on the type of fill that has to be used inside the box the * appropriate function is called. Values of <B>angle1</B>, * <B>angle2</B>, <B>pitch1</B> and <B>pitch2</B> are adapted to the type of * filling. The possible functions are the following : * #o_box_fill_hollow(), #o_box_fill_fill(), #o_box_fill_mesh() and * #o_box_fill_hatch(). * * The combination <B>pitch1</B> <= 0 and <B>pitch2</B> <= 0 is avoided as * it lead to an endless loop in function called after. It happens when * the zoom factor is too small for two lines separated by the pitch * to be distinct. If such a case is encountered the circle is filled * hollow (e.q. not filled). */ angle1 = o_current->fill_angle1; pitch1 = o_current->fill_pitch1; angle2 = o_current->fill_angle2; pitch2 = o_current->fill_pitch2; switch (o_current->fill_type) { case FILLING_HOLLOW: angle1 = -1; angle2 = -1; pitch1 = 1; pitch2 = 1; /* this function is empty ! however if it do not use it we have to add * a test before the call. Simply putting a return here instead is not * possible as it would prevent any hollow box from having its grips * drawn */ fill_func = o_box_fill_hollow; break; case FILLING_FILL: angle1 = -1; angle2 = -1; pitch1 = 1; pitch2 = 1; fill_func = o_box_fill_fill; break; case FILLING_MESH: fill_func = o_box_fill_mesh; break; case FILLING_HATCH: angle2 = -1; pitch2 = 1; fill_func = o_box_fill_hatch; break; case FILLING_VOID: default: angle1 = -1; angle2 = -1; pitch1 = 1; pitch2 = 1; fill_func = o_box_fill_hollow; fprintf (stderr, _("Unknown type for box (fill)!\n")); } if ((pitch1 <= 0) || (pitch2 <= 0)) fill_func = o_box_fill_fill; (*fill_func) (w_current, o_drawing_color (w_current, o_current), o_current->box, o_current->fill_width, angle1, pitch1, angle2, pitch2); gschem_cairo_set_source_color (w_current, o_drawing_color (w_current, o_current)); gschem_cairo_box (w_current, o_current->line_width, o_current->box->lower_x, o_current->box->lower_y, o_current->box->upper_x, o_current->box->upper_y); if (o_current->fill_type == FILLING_FILL) cairo_fill_preserve (w_current->cr); gschem_cairo_stroke (w_current, o_current->line_type, o_current->line_end, o_current->line_width, o_current->line_length, o_current->line_space); if (o_current->selected && w_current->draw_grips) o_box_draw_grips (w_current, o_current); }
static void draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data) { PrintData *data = (PrintData *)user_data; cairo_t *cr; PangoLayout *layout; gint text_width, text_height; gdouble width; gint line, i; PangoFontDescription *desc; gchar *page_str; cr = gtk_print_context_get_cairo_context (context); width = gtk_print_context_get_width (context); cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT); cairo_set_source_rgb (cr, 0.8, 0.8, 0.8); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_set_line_width (cr, 1); cairo_stroke (cr); layout = gtk_print_context_create_pango_layout (context); desc = pango_font_description_from_string ("sans 14"); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_text (layout, data->filename, -1); pango_layout_get_pixel_size (layout, &text_width, &text_height); if (text_width > width) { pango_layout_set_width (layout, width); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START); pango_layout_get_pixel_size (layout, &text_width, &text_height); } cairo_move_to (cr, (width - text_width) / 2, (HEADER_HEIGHT - text_height) / 2); pango_cairo_show_layout (cr, layout); page_str = g_strdup_printf ("%d/%d", page_nr + 1, data->num_pages); pango_layout_set_text (layout, page_str, -1); g_free (page_str); pango_layout_set_width (layout, -1); pango_layout_get_pixel_size (layout, &text_width, &text_height); cairo_move_to (cr, width - text_width - 4, (HEADER_HEIGHT - text_height) / 2); pango_cairo_show_layout (cr, layout); g_object_unref (layout); layout = gtk_print_context_create_pango_layout (context); desc = pango_font_description_from_string ("monospace"); pango_font_description_set_size (desc, data->font_size * PANGO_SCALE); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP); line = page_nr * data->lines_per_page; for (i = 0; i < data->lines_per_page && line < data->num_lines; i++) { pango_layout_set_text (layout, data->lines[line], -1); pango_cairo_show_layout (cr, layout); cairo_rel_move_to (cr, 0, data->font_size); line++; } g_object_unref (layout); }
static void add_average (struct chart *c, int test, int report, double value) { double dx, dy, x; cairo_text_extents_t extents; char buf[80]; double y; if (fabs (value) < 0.1) return; dy = (c->height/2. - PAD) / MAX (-c->min_value, c->max_value); /* the first report is always skipped, as it is used as the baseline */ dx = c->width / (double) (c->num_tests * c->num_reports); x = dx * (c->num_reports * test + report - .5); cairo_rectangle (c->cr, floor (x), c->height / 2., floor (x + dx) - floor (x), ceil (-dy*value - c->height/2.) + c->height/2.); if (dx < 5) { set_report_color (c, report); cairo_fill (c->cr); } else { set_report_gradient (c, report, floor (x), c->height / 2., floor (x + dx) - floor (x), ceil (-dy*value - c->height/2.) + c->height/2.); cairo_fill_preserve (c->cr); cairo_save (c->cr); cairo_clip_preserve (c->cr); set_report_color (c, report); cairo_stroke (c->cr); cairo_restore (c->cr); } /* Skip the label if the difference between the two is less than 0.1% */ if (fabs (value) < 0.1) return; cairo_save (c->cr); cairo_set_font_size (c->cr, dx - 2); if (value < 0) { sprintf (buf, "%.1f", -value/100 + 1); } else { sprintf (buf, "%.1f", value/100 + 1); } cairo_text_extents (c->cr, buf, &extents); /* will it be clipped? */ y = -dy * value; if (y < -c->height/2) { y = -c->height/2; } else if (y > c->height/2) { y = c->height/2; } if (y < 0) { if (y > -extents.width - 6) y -= extents.width + 6; } else { if (y < extents.width + 6) y += extents.width + 6; } cairo_translate (c->cr, floor (x) + (floor (x + dx) - floor (x))/2, floor (y) + c->height/2.); cairo_rotate (c->cr, -M_PI/2); if (y < 0) { cairo_move_to (c->cr, -extents.x_bearing -extents.width - 4, -extents.y_bearing/2); } else { cairo_move_to (c->cr, 2, -extents.y_bearing/2); } cairo_set_source_rgb (c->cr, .95, .95, .95); cairo_show_text (c->cr, buf); cairo_restore (c->cr); }
void CanvasCairo::pathFillStroke(const Color4B &fill, const Color4B &stroke) { cairo_set_source_rgba(_context, fill.r / 255.0, fill.g / 255.0, fill.b / 255.0, fill.a / 255.0); cairo_fill_preserve(_context); cairo_set_source_rgba(_context, stroke.r / 255.0, stroke.g / 255.0, stroke.b / 255.0, stroke.a / 255.0); cairo_stroke(_context); }
static void clearlooks_glossy_draw_checkbox (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *widget, const CheckboxParameters *checkbox, int x, int y, int width, int height) { const CairoColor *border; const CairoColor *dot; gboolean inconsistent = FALSE; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; if (widget->disabled) { border = &colors->shade[5]; dot = &colors->shade[6]; } else { if (widget->prelight) border = &colors->spot[2]; else border = &colors->shade[6]; dot = &colors->text[GTK_STATE_NORMAL]; } cairo_translate (cr, x, y); cairo_set_line_width (cr, 1); if (widget->xthickness > 2 && widget->ythickness > 2) { widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0, width, height, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); /* Draw the rectangle for the checkbox itself */ ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); } else { /* Draw the rectangle for the checkbox itself */ ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); } if (!widget->disabled) { if (widget->prelight) clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); else ge_cairo_set_color (cr, &colors->base[0]); cairo_fill_preserve (cr); } ge_cairo_set_color (cr, border); cairo_stroke (cr); if (draw_bullet) { if (inconsistent) /* Inconsistent */ { cairo_set_line_width (cr, 2.0); cairo_move_to (cr, 3, height*0.5); cairo_line_to (cr, width-3, height*0.5); } else { cairo_set_line_width (cr, 1.7); cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5)); cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7)); cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7), 0.5 + (width*0.5), (height*0.4), 0.5 + (width*0.70), (height*0.25)); } ge_cairo_set_color (cr, dot); cairo_stroke (cr); } }
void gt_graphics_cairo_draw_box(GtGraphics *gg, double x, double y, double width, double height, GtColor fill_color, ArrowStatus arrow_status, double arrow_width, double stroke_width, GtColor stroke_color, bool dashed) { GtGraphicsCairo *g = gt_graphics_cairo_cast(gg); double dashes[]={2.0}; bool widthdiff_geq0; gt_assert(g); /* save cairo context */ cairo_save(g->cr); cairo_rectangle(g->cr, rnd_to_nhalf(g->margin_x), g->margin_y, rnd_to_nhalf(g->width-2*g->margin_x), g->height-2*g->margin_y); cairo_clip(g->cr); widthdiff_geq0 = gt_double_smaller_double(0, width - arrow_width); /* construct shape of the box or arrow */ switch (arrow_status) { case ARROW_RIGHT: cairo_move_to(g->cr, rnd_to_nhalf(x), rnd_to_nhalf(y)); if (widthdiff_geq0) cairo_line_to(g->cr, x + width - arrow_width, rnd_to_nhalf(y)); cairo_line_to(g->cr, rnd_to_nhalf(x + width), rnd_to_nhalf(y + height / 2)); if (widthdiff_geq0) cairo_line_to(g->cr, x + width - arrow_width, rnd_to_nhalf(y + height)); cairo_line_to(g->cr, rnd_to_nhalf(x), rnd_to_nhalf(y + height)); cairo_close_path(g->cr); break; case ARROW_LEFT: cairo_move_to(g->cr, rnd_to_nhalf(x + width), rnd_to_nhalf(y)); if (widthdiff_geq0) { cairo_line_to(g->cr, rnd_to_nhalf(x + arrow_width), rnd_to_nhalf(y)); } cairo_line_to(g->cr, rnd_to_nhalf(x), rnd_to_nhalf(y + height / 2)); if (widthdiff_geq0) { cairo_line_to(g->cr, rnd_to_nhalf(x + arrow_width), rnd_to_nhalf(y + height)); } cairo_line_to(g->cr, rnd_to_nhalf(x + width), rnd_to_nhalf(y + height)); cairo_close_path(g->cr); break; case ARROW_BOTH: cairo_move_to(g->cr, rnd_to_nhalf(x), rnd_to_nhalf(y + height/2)); if (gt_double_smaller_double(width, 2*arrow_width)) { cairo_line_to(g->cr, rnd_to_nhalf(x + width/2), rnd_to_nhalf(y)); cairo_line_to(g->cr, rnd_to_nhalf(x + width), rnd_to_nhalf(y + height/2)); cairo_line_to(g->cr, rnd_to_nhalf(x + width/2), rnd_to_nhalf(y + height)); } else { cairo_line_to(g->cr, rnd_to_nhalf(x + arrow_width), rnd_to_nhalf(y)); cairo_line_to(g->cr, rnd_to_nhalf(x + width - arrow_width), rnd_to_nhalf(y)); cairo_line_to(g->cr, rnd_to_nhalf(x + width), rnd_to_nhalf(y + height/2)); cairo_line_to(g->cr, rnd_to_nhalf(x + width - arrow_width), rnd_to_nhalf(y + height)); cairo_line_to(g->cr, rnd_to_nhalf(x + arrow_width), y + height); } cairo_close_path(g->cr); break; case ARROW_NONE: cairo_rectangle(g->cr, rnd_to_nhalf(x), rnd_to_nhalf(y), width, height); } /* fill area */ cairo_set_source_rgba(g->cr, fill_color.red, fill_color.green, fill_color.blue, fill_color.alpha); cairo_fill_preserve(g->cr); /* draw outline */ cairo_set_line_width(g->cr, stroke_width); cairo_set_source_rgba(g->cr, stroke_color.red, stroke_color.green, stroke_color.blue, stroke_color.alpha); if (dashed) cairo_set_dash(g->cr, dashes, 1, (double) 0); cairo_stroke(g->cr); /* restore cairo context */ cairo_restore(g->cr); }
void panadapter_update(float *data,int tx) { int i; int result; float saved_max; float saved_min; gfloat saved_hz_per_pixel; cairo_text_extents_t extents; hz_per_pixel=(double)getSampleRate()/(double)display_width; samples=data; //if(result==1) { if(panadapter_surface) { if(tx) { saved_max=panadapter_high; saved_min=panadapter_low; saved_hz_per_pixel=hz_per_pixel; panadapter_high=20; panadapter_low=-80; //if(protocol==ORIGINAL_PROTOCOL) { hz_per_pixel=48000.0/(double)display_width; //} else { // hz_per_pixel=192000.0/(double)display_width; //} } //clear_panadater_surface(); cairo_t *cr; cr = cairo_create (panadapter_surface); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); // filter cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); if(ctun && isTransmitting()) { filter_left=(double)display_width/2.0+((double)getFilterLow()/hz_per_pixel); filter_right=(double)display_width/2.0+((double)getFilterHigh()/hz_per_pixel); } else { filter_left=(double)display_width/2.0+(((double)getFilterLow()+ddsOffset)/hz_per_pixel); filter_right=(double)display_width/2.0+(((double)getFilterHigh()+ddsOffset)/hz_per_pixel); } cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height); cairo_fill(cr); // plot the levels int V = (int)(panadapter_high - panadapter_low); int numSteps = V / 20; for (i = 1; i < numSteps; i++) { int num = panadapter_high - i * 20; int y = (int)floor((panadapter_high - num) * display_height / V); cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,0.0,(double)y); cairo_line_to(cr,(double)display_width,(double)y); cairo_set_source_rgb (cr, 0, 1, 1); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; sprintf(v,"%d dBm",num); cairo_move_to(cr, 1, (double)y); cairo_show_text(cr, v); } cairo_stroke(cr); // plot frequency markers long f; long divisor=20000; long half=(long)getSampleRate()/2L; long frequency=getFrequency(); if(ctun && isTransmitting()) { frequency+=ddsOffset; } switch(sample_rate) { case 48000: divisor=5000L; break; case 96000: case 100000: divisor=10000L; break; case 192000: divisor=20000L; break; case 384000: divisor=25000L; break; case 768000: divisor=50000L; break; case 1048576: case 1536000: case 2097152: divisor=100000L; break; } for(i=0;i<display_width;i++) { f = frequency - half + (long) (hz_per_pixel * i); if (f > 0) { if ((f % divisor) < (long) hz_per_pixel) { cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); //cairo_move_to(cr,(double)i,0.0); cairo_move_to(cr,(double)i,10.0); cairo_line_to(cr,(double)i,(double)display_height); cairo_set_source_rgb (cr, 0, 1, 1); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; sprintf(v,"%0ld.%03ld",f/1000000,(f%1000000)/1000); //cairo_move_to(cr, (double)i, (double)(display_height-10)); cairo_text_extents(cr, v, &extents); cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0); cairo_show_text(cr, v); } } } cairo_stroke(cr); // band edges long min_display=frequency-half; long max_display=frequency+half; BAND_LIMITS* bandLimits=getBandLimits(min_display,max_display); if(bandLimits!=NULL) { cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 2.0); if((min_display<bandLimits->minFrequency)&&(max_display>bandLimits->minFrequency)) { i=(bandLimits->minFrequency-min_display)/(long long)hz_per_pixel; cairo_move_to(cr,(double)i,0.0); cairo_line_to(cr,(double)i,(double)display_height); } if((min_display<bandLimits->maxFrequency)&&(max_display>bandLimits->maxFrequency)) { i=(bandLimits->maxFrequency-min_display)/(long long)hz_per_pixel; cairo_move_to(cr,(double)i,0.0); cairo_line_to(cr,(double)i,(double)display_height); } } // agc if(agc!=AGC_OFF && !tx) { double hang=0.0; double thresh=0; GetRXAAGCHangLevel(CHANNEL_RX0, &hang); GetRXAAGCThresh(CHANNEL_RX0, &thresh, 4096.0, (double)sample_rate); double knee_y=thresh+(double)get_attenuation(); knee_y = floor((panadapter_high - knee_y) * (double) display_height / (panadapter_high - panadapter_low)); double hang_y=hang+(double)get_attenuation(); hang_y = floor((panadapter_high - hang_y) * (double) display_height / (panadapter_high - panadapter_low)); //fprintf(stderr,"hang=%f thresh=%f hang_y=%f knee_y=%f\n",rx1_hang,rx1_thresh,hang_y,knee_y); if(agc!=AGC_MEDIUM && agc!=AGC_FAST) { cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); cairo_move_to(cr,40.0,hang_y-8.0); cairo_rectangle(cr, 40, hang_y-8.0,8.0,8.0); cairo_fill(cr); cairo_move_to(cr,40.0,hang_y); cairo_line_to(cr,(double)display_width-40.0,hang_y); cairo_stroke(cr); cairo_move_to(cr,48.0,hang_y); cairo_show_text(cr, "-H"); } cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_move_to(cr,40.0,knee_y-8.0); cairo_rectangle(cr, 40, knee_y-8.0,8.0,8.0); cairo_fill(cr); cairo_move_to(cr,40.0,knee_y); cairo_line_to(cr,(double)display_width-40.0,knee_y); cairo_stroke(cr); cairo_move_to(cr,48.0,knee_y); cairo_show_text(cr, "-G"); } // cursor cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),0.0); cairo_line_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),(double)display_height); cairo_stroke(cr); // signal double s1,s2; samples[0]=-200.0; samples[display_width-1]=-200.0; if(tx && protocol==NEW_PROTOCOL) { int offset=1200; s1=(double)samples[0+offset]+(double)get_attenuation(); s1 = floor((panadapter_high - s1) * (double) display_height / (panadapter_high - panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;i<display_width;i++) { s2=(double)samples[i+offset]+(double)get_attenuation(); s2 = floor((panadapter_high - s2) * (double) display_height / (panadapter_high - panadapter_low)); cairo_line_to(cr, (double)i, s2); } } else { s1=(double)samples[0]+(double)get_attenuation(); s1 = floor((panadapter_high - s1) * (double) display_height / (panadapter_high - panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;i<display_width;i++) { s2=(double)samples[i]+(double)get_attenuation(); s2 = floor((panadapter_high - s2) * (double) display_height / (panadapter_high - panadapter_low)); cairo_line_to(cr, (double)i, s2); } } if(display_filled) { cairo_close_path (cr); cairo_set_source_rgba(cr, 1, 1, 1,0.5); cairo_fill_preserve (cr); } cairo_set_source_rgb(cr, 1, 1, 1); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); #ifdef FREEDV if(mode==modeFREEDV) { if(tx) { cairo_set_source_rgb(cr, 1, 0, 0); } else { cairo_set_source_rgb(cr, 0, 1, 0); } cairo_set_font_size(cr, 16); cairo_text_extents(cr, freedv_text_data, &extents); cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0); cairo_show_text(cr, freedv_text_data); } #endif cairo_destroy (cr); gtk_widget_queue_draw (panadapter); if(tx) { panadapter_high=saved_max; panadapter_low=saved_min; hz_per_pixel=saved_hz_per_pixel; } /* else if(mode==modeFREEDV) { panadapter_high=saved_max; panadapter_low=saved_min; hz_per_pixel=saved_hz_per_pixel; } */ } //} }
void render_signal_aspect(sem_render_context* ctx, sem_signal_aspect aspect) { render_signal_set_aspect(ctx, aspect); cairo_fill_preserve(ctx->cr); cairo_set_source_rgb(ctx->cr, 0.0, 0.0, 0.0); cairo_stroke(ctx->cr); }
static void draw_unlock_indicator() { /* Initialise the surface if not yet done */ if (unlock_indicator_surface == NULL) { button_diameter_physical = ceil(scaling_factor() * BUTTON_DIAMETER); DEBUG("scaling_factor is %.f, physical diameter is %d px\n", scaling_factor(), button_diameter_physical); unlock_indicator_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, button_diameter_physical, button_diameter_physical); } cairo_t *ctx = cairo_create(unlock_indicator_surface); /* clear the surface */ cairo_save(ctx); cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR); cairo_paint(ctx); cairo_restore(ctx); if (unlock_state >= STATE_KEY_PRESSED && unlock_indicator) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, 0 /* start */, 2 * M_PI /* end */); /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, 0, 114.0/255, 255.0/255, 0.75); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 250.0/255, 0, 0, 0.75); break; default: cairo_set_source_rgba(ctx, 0, 0, 0, 0.75); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgb(ctx, 51.0/255, 0, 250.0/255); break; case STATE_PAM_WRONG: cairo_set_source_rgb(ctx, 125.0/255, 51.0/255, 0); break; case STATE_PAM_IDLE: cairo_set_source_rgb(ctx, 51.0/255, 125.0/255, 0); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); cairo_stroke(ctx); cairo_set_line_width(ctx, 10.0); /* Display a (centered) text of the current PAM state. */ char *text = NULL; /* We don't want to show more than a 3-digit number. */ char buf[4]; cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_font_size(ctx, 28.0); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; default: if (show_failed_attempts && failed_attempts > 0){ if (failed_attempts > 999) { text = "> 999"; } else { snprintf(buf, sizeof(buf), "%d", failed_attempts); text = buf; } cairo_set_source_rgb(ctx, 1, 0, 0); cairo_set_font_size(ctx, 32.0); } break; } if (text) { cairo_text_extents_t extents; double x, y; cairo_text_extents(ctx, text, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); cairo_move_to(ctx, x, y); cairo_show_text(ctx, text); cairo_close_path(ctx); } /* After the user pressed any valid key or the backspace key, we * highlight a random part of the unlock indicator to confirm this * keypress. */ if (unlock_state == STATE_KEY_ACTIVE || unlock_state == STATE_BACKSPACE_ACTIVE) { cairo_new_sub_path(ctx); double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start, highlight_start + (M_PI / 3.0)); if (unlock_state == STATE_KEY_ACTIVE) { /* For normal keys, we use a lighter green. */ cairo_set_source_rgb(ctx, 51.0/255, 219.0/255, 0); } else { /* For backspace, we use red. */ cairo_set_source_rgb(ctx, 219.0/255, 51.0/255, 0); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); cairo_stroke(ctx); } } cairo_destroy(ctx); }
void rendering_draw_caroussel_in_desklet (cairo_t *pCairoContext, CairoDesklet *pDesklet, gboolean bRenderOptimized) { CDCarousselParameters *pCaroussel = (CDCarousselParameters *) pDesklet->pRendererData; //g_print ("%s(%x)\n", __func__, pCaroussel); if (pCaroussel == NULL) return ; double fTheta = G_PI/2 + pCaroussel->fRotationAngle, fDeltaTheta = pCaroussel->fDeltaTheta; int iEllipseHeight = pCaroussel->iEllipseHeight; double fInclinationOnHorizon = pCaroussel->fInclinationOnHorizon; int iFrameHeight = pCaroussel->iFrameHeight; double fExtraWidth = pCaroussel->fExtraWidth; double a = pCaroussel->a, b = pCaroussel->b; Icon *pIcon; GList *ic; if (pCaroussel->b3D) { for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (fTheta > G_PI && fTheta < 2*G_PI) // arriere-plan. { pIcon->fScale = (1 + .5 * fabs (fTheta - 3 * G_PI / 2) / (G_PI / 2)) / 1.5; pIcon->fAlpha = pIcon->fScale; } else { pIcon->fScale = 1.; pIcon->fAlpha = 1.; } pIcon->fDrawX = pDesklet->iWidth / 2 + a * cos (fTheta) - pIcon->fWidth/2 * 1; pIcon->fDrawY = pDesklet->iHeight / 2 + b * sin (fTheta) - pIcon->fHeight * pIcon->fScale + myLabels.iconTextDescription.iSize; fTheta += fDeltaTheta; if (fTheta >= G_PI/2 + 2*G_PI) fTheta -= 2*G_PI; } //\____________________ On trace le cadre. double fLineWidth = g_iDockLineWidth; double fMargin = 0*myBackground.iFrameMargin; double fDockWidth = pDesklet->iWidth - fExtraWidth; int sens=1; double fDockOffsetX, fDockOffsetY; // Offset du coin haut gauche du cadre. fDockOffsetX = fExtraWidth / 2; fDockOffsetY = (pDesklet->iHeight - iEllipseHeight) / 2 + myLabels.iconTextDescription.iSize; cairo_save (pCairoContext); cairo_dock_draw_frame (pCairoContext, g_iDockRadius, fLineWidth, fDockWidth, iFrameHeight, fDockOffsetX, fDockOffsetY, sens, fInclinationOnHorizon, pDesklet->bIsHorizontal); //\____________________ On dessine les decorations dedans. cairo_set_source_rgba (pCairoContext, .8, .8, .8, .75); cairo_fill_preserve (pCairoContext); //\____________________ On dessine le cadre. if (fLineWidth > 0) { cairo_set_line_width (pCairoContext, fLineWidth); cairo_set_source_rgba (pCairoContext, .9, .9, .9, 1.); cairo_stroke (pCairoContext); } cairo_restore (pCairoContext); //\____________________ On dessine les icones dans l'ordre qui va bien. for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight < pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 > pDesklet->iWidth / 2) // arriere-plan droite. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight < pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 <= pDesklet->iWidth / 2) // arriere-plan gauche. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } cairo_save (pCairoContext); pDesklet->pIcon->fDrawY = pDesklet->iHeight/2 - pDesklet->pIcon->fHeight + myLabels.iconTextDescription.iSize; cairo_dock_render_one_icon_in_desklet (pDesklet->pIcon, pCairoContext, TRUE, FALSE, pDesklet->iWidth); cairo_restore (pCairoContext); for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight >= pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 > pDesklet->iWidth / 2) // avant-plan droite. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); if (pIcon->fDrawY + pIcon->fHeight >= pDesklet->iHeight / 2 + myLabels.iconTextDescription.iSize && pIcon->fDrawX + pIcon->fWidth/2 <= pDesklet->iWidth / 2) // avant-plan gauche. cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, TRUE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } } } else { cairo_save (pCairoContext); cairo_dock_render_one_icon_in_desklet (pDesklet->pIcon, pCairoContext, FALSE, FALSE, pDesklet->iWidth); cairo_restore (pCairoContext); gboolean bFlip = (pDesklet->pIcon->fHeight > pDesklet->pIcon->fWidth); for (ic = pDesklet->icons; ic != NULL; ic = ic->next) { pIcon = ic->data; if (pIcon->pIconBuffer != NULL) { cairo_save (pCairoContext); pIcon->fDrawX = pDesklet->pIcon->fDrawX + pDesklet->pIcon->fWidth / 2 + (bFlip ? b : a) * cos (fTheta) - pIcon->fWidth/2; pIcon->fDrawY = pDesklet->pIcon->fDrawY + pDesklet->pIcon->fHeight / 2 + (bFlip ? a : b) * sin (fTheta) - pIcon->fHeight/2 + myLabels.iconTextDescription.iSize; cairo_dock_render_one_icon_in_desklet (pIcon, pCairoContext, FALSE, TRUE, pDesklet->iWidth); cairo_restore (pCairoContext); } fTheta += fDeltaTheta; if (fTheta >= G_PI/2 + 2*G_PI) fTheta -= 2*G_PI; } } }
static void ppg_ruler_draw_arrow (PpgRuler *ruler) { PpgRulerPrivate *priv; GtkStyle *style; GdkColor base_light; GdkColor base_dark; GdkColor hl_light; GdkColor hl_dark; 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 = gdk_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]; hl_dark = style->mid[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 moblin_netbook_draw_extension (GtkStyle *style, GdkWindow *window, GtkStateType state_type, GtkShadowType shadow_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, gint x, gint y, gint width, gint height, GtkPositionType gap_side) { cairo_t *cr; cairo_pattern_t *pattern; gint radius = MOBLIN_NETBOOK_STYLE (style)->radius; /* initialise the background */ gtk_style_apply_default_background (style, window, TRUE, state_type, area, x, y, width, height); cr = moblin_netbook_cairo_create (window, area); /* set up for line drawing */ cairo_set_line_width (cr, LINE_WIDTH); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_translate (cr, 0.5, 0.5); /* reduce with and height since we are using them for co-ordinate values */ width--; height--; /* tab border */ switch (gap_side) { case GTK_POS_TOP: /* bottom tab */ cairo_move_to (cr, x, y); cairo_arc_negative (cr, x + radius, y + height - radius, radius, M_PI, M_PI * 0.5); cairo_arc_negative (cr, x + width - radius, y + height - radius, radius, M_PI * 0.5, 0); cairo_line_to (cr, x + width, y); break; case GTK_POS_BOTTOM: /* top tab */ height++; /* add overlap */ if (state_type == GTK_STATE_NORMAL) cairo_arc_negative (cr, x, y + height - radius, radius, M_PI / 2.0, 0); else cairo_move_to (cr, x + radius, y + height); cairo_arc (cr, x + radius * 2, y + radius, radius, M_PI, M_PI * 1.5); cairo_arc (cr, x + width - radius * 2, y + radius, radius, M_PI * 1.5, 0); if (state_type == GTK_STATE_NORMAL) cairo_arc_negative (cr, x + width, y + height - radius, radius, M_PI, M_PI / 2.0); else cairo_line_to (cr, x + width - radius, y + height); break; case GTK_POS_LEFT: /* right tab */ cairo_move_to (cr, x, y); cairo_arc (cr, x + width - radius, y + radius, radius, M_PI * 1.5, 0); cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, M_PI * 0.5); cairo_line_to (cr, x, y + height); break; case GTK_POS_RIGHT: /* left tab */ cairo_move_to (cr, x + width, y); cairo_arc_negative (cr, x + radius, y + radius, radius, M_PI * 1.5, M_PI); cairo_arc_negative (cr, x + radius, y + height - radius, radius, M_PI, M_PI * 0.5); cairo_line_to (cr, x + width, y + height); break; } if (state_type == GTK_STATE_NORMAL) { pattern = cairo_pattern_create_linear (x, y, x, y +height); cairo_pattern_add_color_stop_rgb (pattern, 0, 0xf9/255.0, 0xf9/255.0,0xf9/255.0); cairo_pattern_add_color_stop_rgb (pattern, 1, 0xe6/255.0, 0xe6/255.0,0xe6/255.0); cairo_set_source (cr, pattern); cairo_fill_preserve (cr); cairo_pattern_destroy (pattern); } moblin_netbook_set_border_color (cr, style, state_type); cairo_stroke (cr); cairo_destroy (cr); }
static int cr_fill_preserve (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_fill_preserve(*obj); return 0; }
static gboolean draw_callback(GtkWidget *widget,cairo_t *cr,gpointer data) { guint width=gtk_widget_get_allocated_width(widget); guint height=gtk_widget_get_allocated_height(widget); double sw,sh,spacing; //PangoLayout* pn=gtk_widget_create_pango_layout(widget,"HELLO? IS THIS WORKING?(\u2126)"); PangoContext* pc=gtk_widget_get_pango_context(widget); PangoLayout* pn=pango_layout_new(pc); sw=((double)width-2*gutter)/grid.width; sh=((double)height-2*gutter)/grid.height; spacing=MIN(sw,sh); cairo_set_source_rgb(cr,0,0,255); // cairo_arc(cr,mouseX,mouseY,5,0,2*G_PI); cairo_translate(cr,(double)width/2,(double)height/2); cairo_translate(cr,-(double)grid.width/2.0*spacing,-(double)grid.height/2.0*spacing); int i,j; cairo_set_source_rgb(cr,0,0,0); for(i=0;i<grid.map.ccount;i++) { Component* c=grid.map.components+i; int A=c->A; int B=c->B; draw_component(cr,pc,spacing,spacing*(A%(grid.width+1)),spacing*(A/(grid.width+1)),spacing*(B%(grid.width+1)),spacing*(B/(grid.width+1)),c); } cairo_set_source_rgb(cr,0,0,0); char buffer[20]; for(i=0;i<=grid.width;i++) { for(j=0;j<=grid.height;j++) { if(draw_flags&VOLTAGES){ sprintf(buffer,"%.2fV",grid.map.vertices[i+j*(grid.width+1)].voltage); pango_layout_set_text(pn,buffer,-1); int w,h; pango_layout_get_pixel_size(pn,&w,&h); cairo_arc(cr,i*spacing,j*spacing,25,0,2*G_PI); cairo_set_source_rgb(cr,1.0,1.0,1.0); cairo_fill_preserve(cr); cairo_set_source_rgb(cr,0.0,0.0,0.0); cairo_stroke(cr); cairo_move_to(cr,i*spacing-w/2,j*spacing-h/2); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn); cairo_new_path(cr); /* sprintf(buffer,"%gV",grid.map.vertices[i+j*(grid.width+1)].voltage); pango_layout_set_text(pn,buffer,-1); int w,h; pango_layout_get_pixel_size(pn,&w,&h); cairo_arc(cr,i*spacing,j*spacing,w/2,0,2*G_PI); cairo_set_source_rgb(cr,1.0,1.0,1.0); cairo_fill_preserve(cr); cairo_set_source_rgb(cr,0.0,0.0,0.0); cairo_stroke(cr); cairo_move_to(cr,i*spacing-w/2,j*spacing-h/2); pango_cairo_update_layout(cr,pn); pango_cairo_show_layout(cr,pn); cairo_new_path(cr);*/ }else{ cairo_arc(cr,i*spacing,j*spacing,2,0,2*G_PI); cairo_set_source_rgb(cr,1.0,1.0,1.0); cairo_fill_preserve(cr); cairo_set_source_rgb(cr,0.0,0.0,0.0); cairo_stroke(cr); } } } //pango_cairo_show_layout(cr,pn); return FALSE; }
static void dt_ellipse_events_post_expose(cairo_t *cr, float zoom_scale, dt_masks_form_gui_t *gui, int index) { double dashed[] = { 4.0, 4.0 }; dashed[0] /= zoom_scale; dashed[1] /= zoom_scale; int len = sizeof(dashed) / sizeof(dashed[0]); dt_masks_form_gui_points_t *gpt = (dt_masks_form_gui_points_t *)g_list_nth_data(gui->points, index); if(!gpt) return; const float r = atan2(gpt->points[3] - gpt->points[1], gpt->points[2] - gpt->points[0]); const float sinr = sin(r); const float cosr = cos(r); float dx = 0.0f, dy = 0.0f, xref = gpt->points[0], yref = gpt->points[1]; float dxs = 0.0f, dys = 0.0f, xrefs = 0.0f, yrefs = 0.0f; float sinv = 0.0f, cosv = 1.0f; float scalea = 1.0f, scaleb = 1.0f, scaleab = 1.0f, scalebb = 1.0f; if(gpt->source_count > 10) { xrefs = gpt->source[0]; yrefs = gpt->source[1]; } if((gui->group_selected == index) && gui->form_dragging) { dx = gui->posx + gui->dx - xref; dy = gui->posy + gui->dy - yref; } else if((gui->group_selected == index) && gui->source_dragging) { xrefs = gpt->source[0], yrefs = gpt->source[1]; dxs = gui->posx + gui->dx - xrefs; dys = gui->posy + gui->dy - yrefs; } else if((gui->group_selected == index) && gui->form_rotating) { const float v = atan2(gui->posy - yref, gui->posx - xref) - atan2(-gui->dy, -gui->dx); sinv = sin(v); cosv = cos(v); } else if((gui->group_selected == index) && (gui->point_dragging >= 1)) { const int k = gui->point_dragging; const float rx = gpt->points[k * 2] - xref; const float ry = gpt->points[k * 2 + 1] - yref; const float bx = gpt->border[k * 2] - xref; const float by = gpt->border[k * 2 + 1] - yref; const float deltax = gui->posx + gui->dx - xref; const float deltay = gui->posy + gui->dy - yref; const float r = sqrtf(rx * rx + ry * ry); const float b = sqrtf(bx * bx + by * by); float d = (rx * deltax + ry * deltay) / r; if(r + d < 0) d = -r; if(k == 1 || k == 2) { scalea = r > 0 ? (r + d) / r : 0; scaleab = b > 0 ? (b + d) / b : 0; } else { scaleb = r > 0 ? (r + d) / r : 0; scalebb = b > 0 ? (b + d) / b : 0; } } float x, y; // draw shape if(gpt->points_count > 10) { cairo_set_dash(cr, dashed, 0, 0); if((gui->group_selected == index) && (gui->form_selected || gui->form_dragging)) cairo_set_line_width(cr, 5.0 / zoom_scale); else cairo_set_line_width(cr, 3.0 / zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); _ellipse_point_transform(xref, yref, gpt->points[10] + dx, gpt->points[11] + dy, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_move_to(cr, x, y); for(int i = 6; i < gpt->points_count; i++) { _ellipse_point_transform(xref, yref, gpt->points[i * 2] + dx, gpt->points[i * 2 + 1] + dy, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_line_to(cr, x, y); } _ellipse_point_transform(xref, yref, gpt->points[10] + dx, gpt->points[11] + dy, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_line_to(cr, x, y); cairo_stroke_preserve(cr); if((gui->group_selected == index) && (gui->form_selected || gui->form_dragging)) cairo_set_line_width(cr, 2.0 / zoom_scale); else cairo_set_line_width(cr, 1.0 / zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); cairo_stroke(cr); } // draw anchor points if(TRUE) { cairo_set_dash(cr, dashed, 0, 0); float anchor_size; // = (gui->form_dragging || gui->form_selected) ? 7.0f / zoom_scale : 5.0f / // zoom_scale; for(int i = 1; i < 5; i++) { cairo_set_source_rgba(cr, .8, .8, .8, .8); if(i == gui->point_dragging || i == gui->point_selected) anchor_size = 7.0f / zoom_scale; else anchor_size = 5.0f / zoom_scale; _ellipse_point_transform(xref, yref, gpt->points[i * 2] + dx, gpt->points[i * 2 + 1] + dy, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_rectangle(cr, x - (anchor_size * 0.5), y - (anchor_size * 0.5), anchor_size, anchor_size); cairo_fill_preserve(cr); if((gui->group_selected == index) && (i == gui->point_dragging || i == gui->point_selected)) cairo_set_line_width(cr, 2.0 / zoom_scale); if((gui->group_selected == index) && (gui->form_dragging || gui->form_selected)) cairo_set_line_width(cr, 2.0 / zoom_scale); else cairo_set_line_width(cr, 1.0 / zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); cairo_stroke(cr); } } // draw border if((gui->group_selected == index) && gpt->border_count > 10) { cairo_set_dash(cr, dashed, len, 0); if((gui->group_selected == index) && (gui->border_selected)) cairo_set_line_width(cr, 2.0 / zoom_scale); else cairo_set_line_width(cr, 1.0 / zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); _ellipse_point_transform(xref, yref, gpt->border[10] + dx, gpt->border[11] + dy, sinr, cosr, scaleab, scalebb, sinv, cosv, &x, &y); cairo_move_to(cr, x, y); for(int i = 6; i < gpt->border_count; i++) { _ellipse_point_transform(xref, yref, gpt->border[i * 2] + dx, gpt->border[i * 2 + 1] + dy, sinr, cosr, scaleab, scalebb, sinv, cosv, &x, &y); cairo_line_to(cr, x, y); } _ellipse_point_transform(xref, yref, gpt->border[10] + dx, gpt->border[11] + dy, sinr, cosr, scaleab, scalebb, sinv, cosv, &x, &y); cairo_line_to(cr, x, y); cairo_stroke_preserve(cr); if((gui->group_selected == index) && (gui->border_selected)) cairo_set_line_width(cr, 2.0 / zoom_scale); else cairo_set_line_width(cr, 1.0 / zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); cairo_set_dash(cr, dashed, len, 4); cairo_stroke(cr); } // draw the source if any if(gpt->source_count > 10) { // compute the dest inner ellipse intersection with the line from source center to dest center. float cdx = gpt->source[0] + dxs - gpt->points[0] - dx; float cdy = gpt->source[1] + dys - gpt->points[1] - dy; // we don't draw the line if source==point if(cdx != 0.0 && cdy != 0.0) { cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); float cangle = atan(cdx / cdy); if(cdy > 0) cangle = (M_PI / 2) - cangle; else cangle = -(M_PI / 2) - cangle; float arrowx = gpt->points[0] + dx; float arrowy = gpt->points[1] + dy; cairo_move_to(cr, gpt->source[0] + dxs, gpt->source[1] + dys); // source center cairo_line_to(cr, arrowx, arrowy); // dest border // then draw to line for the arrow itself const float arrow_scale = 8.0; cairo_move_to(cr, arrowx + arrow_scale * cos(cangle + (0.4)), arrowy + arrow_scale * sin(cangle + (0.4))); cairo_line_to(cr, arrowx, arrowy); cairo_line_to(cr, arrowx + arrow_scale * cos(cangle - (0.4)), arrowy + arrow_scale * sin(cangle - (0.4))); cairo_set_dash(cr, dashed, 0, 0); if((gui->group_selected == index) && (gui->form_selected || gui->form_dragging)) cairo_set_line_width(cr, 2.5 / zoom_scale); else cairo_set_line_width(cr, 1.5 / zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); cairo_stroke_preserve(cr); if((gui->group_selected == index) && (gui->form_selected || gui->form_dragging)) cairo_set_line_width(cr, 1.0 / zoom_scale); else cairo_set_line_width(cr, 0.5 / zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); cairo_stroke(cr); } // we draw the source cairo_set_dash(cr, dashed, 0, 0); if((gui->group_selected == index) && (gui->form_selected || gui->form_dragging)) cairo_set_line_width(cr, 2.5 / zoom_scale); else cairo_set_line_width(cr, 1.5 / zoom_scale); cairo_set_source_rgba(cr, .3, .3, .3, .8); _ellipse_point_transform(xrefs, yrefs, gpt->source[10] + dxs, gpt->source[11] + dys, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_move_to(cr, x, y); for(int i = 6; i < gpt->source_count; i++) { _ellipse_point_transform(xrefs, yrefs, gpt->source[i * 2] + dxs, gpt->source[i * 2 + 1] + dys, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_line_to(cr, x, y); } _ellipse_point_transform(xrefs, yrefs, gpt->source[10] + dxs, gpt->source[11] + dys, sinr, cosr, scalea, scaleb, sinv, cosv, &x, &y); cairo_line_to(cr, x, y); cairo_stroke_preserve(cr); if((gui->group_selected == index) && (gui->form_selected || gui->form_dragging)) cairo_set_line_width(cr, 1.0 / zoom_scale); else cairo_set_line_width(cr, 0.5 / zoom_scale); cairo_set_source_rgba(cr, .8, .8, .8, .8); cairo_stroke(cr); } }
/* This is our expose-event handler when the window is in a compositing manager. * We draw everything by hand, using Cairo, so that we can have a nice * transparent/rounded look. */ static void expose_when_composited (GtkWidget *widget, GdkEventExpose *event) { MsdOsdWindow *window; cairo_t *context; cairo_t *cr; cairo_surface_t *surface; int width; int height; GtkStyle *style; GdkColor color; double r, g, b; window = MSD_OSD_WINDOW (widget); context = gdk_cairo_create (gtk_widget_get_window (widget)); style = gtk_widget_get_style (widget); cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); gtk_window_get_size (GTK_WINDOW (widget), &width, &height); surface = cairo_surface_create_similar (cairo_get_target (context), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { goto done; } cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { goto done; } cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint (cr); /* draw a box */ msd_osd_window_draw_rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); msd_osd_window_color_reverse (&style->bg[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); cairo_fill_preserve (cr); msd_osd_window_color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); g_signal_emit (window, signals[EXPOSE_WHEN_COMPOSITED], 0, cr); cairo_destroy (cr); /* Make sure we have a transparent background */ cairo_rectangle (context, 0, 0, width, height); cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); cairo_fill (context); cairo_set_source_surface (context, surface, 0, 0); cairo_paint_with_alpha (context, window->priv->fade_out_alpha); done: if (surface != NULL) { cairo_surface_destroy (surface); } cairo_destroy (context); }
static void clearlooks_glossy_draw_radiobutton (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *widget, const CheckboxParameters *checkbox, int x, int y, int width, int height) { const CairoColor *border; const CairoColor *dot; CairoColor shadow; CairoColor highlight; cairo_pattern_t *pt; gboolean inconsistent; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); gdouble w, h, cx, cy, radius; w = (gdouble) width; h = (gdouble) height; cx = width / 2.0; cy = height / 2.0; radius = MIN (width, height) / 2.0; inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; if (widget->disabled) { border = &colors->shade[5]; dot = &colors->shade[6]; } else { if (widget->prelight) border = &colors->spot[2]; else border = &colors->shade[6]; dot = &colors->text[0]; } ge_shade_color (&widget->parentbg, 0.9, &shadow); ge_shade_color (&widget->parentbg, 1.1, &highlight); pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0); cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b); cairo_translate (cr, x, y); cairo_set_line_width (cr, MAX (1.0, floor (radius/3))); cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2); cairo_set_source (cr, pt); cairo_stroke (cr); cairo_pattern_destroy (pt); cairo_set_line_width (cr, MAX (1.0, floor (radius/6))); cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2); if (!widget->disabled) { if (widget->prelight) clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); else ge_cairo_set_color (cr, &colors->base[0]); cairo_fill_preserve (cr); } ge_cairo_set_color (cr, border); cairo_stroke (cr); if (draw_bullet) { if (inconsistent) { cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, ceil (radius * 2 / 3)); cairo_move_to (cr, ceil (cx - radius/3.0), ceil (cy)); cairo_line_to (cr, ceil (cx + radius/3.0), ceil (cy)); ge_cairo_set_color (cr, dot); cairo_stroke (cr); } else { cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2); ge_cairo_set_color (cr, dot); cairo_fill (cr); cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2); cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); cairo_fill (cr); } } }
static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, GsdMediaKeysWindow *window) { cairo_t *context; cairo_t *cr; cairo_surface_t *surface; int width; int height; GtkStyle *style; GdkColor color; double r, g, b; context = gdk_cairo_create (gtk_widget_get_window (widget)); style = gtk_widget_get_style (widget); cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); gtk_window_get_size (GTK_WINDOW (widget), &width, &height); surface = cairo_surface_create_similar (cairo_get_target (context), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { goto done; } cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { goto done; } cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint (cr); /* draw a box */ rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); color_reverse (&style->bg[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); cairo_fill_preserve (cr); color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); /* draw action */ draw_action (window, cr); cairo_destroy (cr); /* Make sure we have a transparent background */ cairo_rectangle (context, 0, 0, width, height); cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); cairo_fill (context); cairo_set_source_surface (context, surface, 0, 0); cairo_paint_with_alpha (context, window->priv->fade_out_alpha); done: if (surface != NULL) { cairo_surface_destroy (surface); } cairo_destroy (context); return FALSE; }
/* * Draws global image with fill color onto a pixmap with the given * resolution and returns it. * */ xcb_pixmap_t draw_image(uint32_t *resolution) { xcb_pixmap_t bg_pixmap = XCB_NONE; int button_diameter_physical = ceil(scaling_factor() * BUTTON_DIAMETER); DEBUG("scaling_factor is %.f, physical diameter is %d px\n", scaling_factor(), button_diameter_physical); if (!vistype) vistype = get_root_visual_type(screen); bg_pixmap = create_bg_pixmap(conn, screen, resolution, color); /* Initialize cairo: Create one in-memory surface to render the unlock * indicator on, create one XCB surface to actually draw (one or more, * depending on the amount of screens) unlock indicators on. */ cairo_surface_t *output = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, button_diameter_physical, button_diameter_physical); cairo_t *ctx = cairo_create(output); cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); cairo_t *xcb_ctx = cairo_create(xcb_output); char redgroups[3][3] = {{red[0], red[1], '\0'}, {red[2], red[3], '\0'}, {red[4], red[5], '\0'}}; uint32_t red16[3] = {(strtol(redgroups[0], NULL, 16)), (strtol(redgroups[1], NULL, 16)), (strtol(redgroups[2], NULL, 16))}; char greengroups[3][3] = {{green[0], green[1], '\0'}, {green[2], green[3], '\0'}, {green[4], green[5], '\0'}}; uint32_t green16[3] = {(strtol(greengroups[0], NULL, 16)), (strtol(greengroups[1], NULL, 16)), (strtol(greengroups[2], NULL, 16))}; char bluegroups[3][3] = {{blue[0], blue[1], '\0'}, {blue[2], blue[3], '\0'}, {blue[4], blue[5], '\0'}}; uint32_t blue16[3] = {(strtol(bluegroups[0], NULL, 16)), (strtol(bluegroups[1], NULL, 16)), (strtol(bluegroups[2], NULL, 16))}; char outgroups[3][3] = {{outline[0], outline[1], '\0'}, {outline[2], outline[3], '\0'}, {outline[4], outline[5], '\0'}}; uint32_t out16[3] = {(strtol(outgroups[0], NULL, 16)), (strtol(outgroups[1], NULL, 16)), (strtol(outgroups[2], NULL, 16))}; char bggroups[3][3] = {{background[0], background[1], '\0'}, {background[2], background[3], '\0'}, {background[4], background[5], '\0'}}; uint32_t bg16[3] = {(strtol(bggroups[0], NULL, 16)), (strtol(bggroups[1], NULL, 16)), (strtol(bggroups[2], NULL, 16))}; if (img) { if (!tile) { cairo_set_source_surface(xcb_ctx, img, 0, 0); cairo_paint(xcb_ctx); } else { /* create a pattern and fill a rectangle as big as the screen */ cairo_pattern_t *pattern; pattern = cairo_pattern_create_for_surface(img); cairo_set_source(xcb_ctx, pattern); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); cairo_pattern_destroy(pattern); } } else { char strgroups[3][3] = {{color[0], color[1], '\0'}, {color[2], color[3], '\0'}, {color[4], color[5], '\0'}}; uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), (strtol(strgroups[1], NULL, 16)), (strtol(strgroups[2], NULL, 16))}; cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[1] / 255.0); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); } if (unlock_state >= STATE_KEY_PRESSED && unlock_indicator) { cairo_scale(ctx, scaling_factor(), scaling_factor()); /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, 0 /* start */, 2 * M_PI /* end */); /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, blue16[0] / 255.0, blue16[1] / 255.0, blue16[2] / 255.0, 1.0); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, red16[0] / 255.0, red16[1] / 255.0, red16[2] / 255.0, 1.0); break; default: cairo_set_source_rgba(ctx, bg16[0] / 255.0, bg16[1] / 255.0, bg16[2] / 255.0, 1.0); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgb(ctx, blue16[0] / 255.0, blue16[1] / 255.0, blue16[2] / 255.0); break; case STATE_PAM_WRONG: cairo_set_source_rgb(ctx, red16[0] / 255.0, red16[1] / 255.0, red16[2] / 255.0); break; case STATE_PAM_IDLE: cairo_set_source_rgb(ctx, bg16[0] / 255.0, bg16[1] / 255.0, bg16[2] / 255.0); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgb(ctx, out16[0] / 255.0, out16[1] / 255.0, out16[2] / 255.0); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); cairo_stroke(ctx); cairo_set_line_width(ctx, 10.0); /* Display a (centered) text of the current PAM state. */ char *text = NULL; /* We don't want to show more than a 3-digit number. */ char buf[4]; cairo_set_source_rgb(ctx, out16[0] / 255.0, out16[1] / 255.0, out16[2] / 255.0); cairo_set_font_size(ctx, 28.0); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; default: if (show_failed_attempts && failed_attempts > 0) { if (failed_attempts > 999) { text = "> 999"; } else { snprintf(buf, sizeof(buf), "%d", failed_attempts); text = buf; } cairo_set_source_rgba(ctx, red16[0] / 255.0, red16[1] / 255.0, red16[2] / 255.0, 1.0); cairo_set_font_size(ctx, 32.0); } break; } if (text) { cairo_text_extents_t extents; double x, y; cairo_text_extents(ctx, text, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); cairo_move_to(ctx, x, y); cairo_show_text(ctx, text); cairo_close_path(ctx); } if (pam_state == STATE_PAM_WRONG && (modifier_string != NULL)) { cairo_text_extents_t extents; double x, y; cairo_set_font_size(ctx, 14.0); cairo_text_extents(ctx, modifier_string, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 28.0; cairo_move_to(ctx, x, y); cairo_show_text(ctx, modifier_string); cairo_close_path(ctx); } /* After the user pressed any valid key or the backspace key, we * highlight a random part of the unlock indicator to confirm this * keypress. */ if (unlock_state == STATE_KEY_ACTIVE || unlock_state == STATE_BACKSPACE_ACTIVE) { cairo_new_sub_path(ctx); double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start, highlight_start + (M_PI / 3.0)); if (unlock_state == STATE_KEY_ACTIVE) { /* For normal keys, we use a lighter green. */ cairo_set_source_rgb(ctx, green16[0] / 255.0, green16[1] / 255.0, green16[2] / 255.0); } else { /* For backspace, we use red. */ cairo_set_source_rgb(ctx, red16[0] / 255.0, red16[1] / 255.0, red16[2] / 255.0); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgb(ctx, out16[0] / 255.0, out16[1] / 255.0, out16[2] / 255.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); cairo_stroke(ctx); } } if (xr_screens > 0) { /* Composite the unlock indicator in the middle of each screen. */ for (int screen = 0; screen < xr_screens; screen++) { int x = (xr_resolutions[screen].x + ((xr_resolutions[screen].width / 2) - (button_diameter_physical / 2))); int y = (xr_resolutions[screen].y + ((xr_resolutions[screen].height / 2) - (button_diameter_physical / 2))); cairo_set_source_surface(xcb_ctx, output, x, y); cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical); cairo_fill(xcb_ctx); } } else { /* We have no information about the screen sizes/positions, so we just * place the unlock indicator in the middle of the X root window and * hope for the best. */ int x = (last_resolution[0] / 2) - (button_diameter_physical / 2); int y = (last_resolution[1] / 2) - (button_diameter_physical / 2); cairo_set_source_surface(xcb_ctx, output, x, y); cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical); cairo_fill(xcb_ctx); } cairo_surface_destroy(xcb_output); cairo_surface_destroy(output); cairo_destroy(ctx); cairo_destroy(xcb_ctx); return bg_pixmap; }
static void gimp_cell_renderer_color_render (GtkCellRenderer *cell, GdkWindow *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { GimpCellRendererColor *color = GIMP_CELL_RENDERER_COLOR (cell); GdkRectangle rect; gimp_cell_renderer_color_get_size (cell, widget, cell_area, &rect.x, &rect.y, &rect.width, &rect.height); rect.x += cell_area->x + cell->xpad; rect.y += cell_area->y + cell->ypad; rect.width -= 2 * cell->xpad; rect.height -= 2 * cell->ypad; if (rect.width > 2 && rect.height > 2) { cairo_t *cr = gdk_cairo_create (window); GtkStyle *style = gtk_widget_get_style (widget); GtkStateType state; cairo_rectangle (cr, rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2); gimp_cairo_set_source_rgb (cr, &color->color); cairo_fill (cr); if (! color->opaque && color->color.a < 1.0) { cairo_pattern_t *pattern; cairo_move_to (cr, rect.x + 1, rect.y + rect.height - 1); cairo_line_to (cr, rect.x + rect.width - 1, rect.y + rect.height - 1); cairo_line_to (cr, rect.x + rect.width - 1, rect.y + 1); cairo_close_path (cr); pattern = gimp_cairo_checkerboard_create (cr, GIMP_CHECK_SIZE_SM, NULL, NULL); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); cairo_fill_preserve (cr); gimp_cairo_set_source_rgba (cr, &color->color); cairo_fill (cr); } /* draw border */ cairo_rectangle (cr, rect.x + 0.5, rect.y + 0.5, rect.width - 1, rect.height - 1); if (! cell->sensitive || GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE) { state = GTK_STATE_INSENSITIVE; } else { state = (flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED : GTK_STATE_NORMAL); } cairo_set_line_width (cr, 1); gdk_cairo_set_source_color (cr, &style->fg[state]); cairo_stroke_preserve (cr); if (state == GTK_STATE_SELECTED && gimp_cairo_set_focus_line_pattern (cr, widget)) { gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]); cairo_stroke (cr); } cairo_destroy (cr); } }
void CairoGLRenderer::RenderDemo(HWND hWnd, HDC hdc, int height, int width, float fps) { wglMakeCurrent(m_hdc, m_hglrc); cairo_identity_matrix(m_cr); cairo_save(m_cr); double m_radius = 0.42; double m_line_width = 0.05; cairo_scale(m_cr, width, height); cairo_translate(m_cr, 0.5, 0.5); cairo_set_line_width(m_cr, m_line_width); // Background cairo_save(m_cr); cairo_set_source_rgba(m_cr, 0.337, 0.612, 0.117, 0.9); // green cairo_paint(m_cr); cairo_restore(m_cr); // Clock face: cairo_save(m_cr); cairo_new_sub_path(m_cr); cairo_arc(m_cr, 0, 0, m_radius, 0, 2 * M_PI); cairo_save(m_cr); cairo_set_source_rgba(m_cr, 1.0, 1.0, 1.0, 0.8); cairo_fill_preserve(m_cr); cairo_restore(m_cr); cairo_close_path(m_cr); cairo_stroke(m_cr); cairo_restore(m_cr); // clock ticks for (int i = 0; i < 12; ++i) { double inset = 0.05; cairo_save(m_cr); cairo_set_line_cap(m_cr, CAIRO_LINE_CAP_ROUND); if (i % 3 != 0) { inset *= 0.8; cairo_set_line_width(m_cr, 0.03); } const double angle = i * M_PI / 6.0f; const double sinAngle = std::sin(angle); const double cosAngle = std::cos(angle); cairo_move_to(m_cr, (m_radius - inset) * cosAngle, (m_radius - inset) * sinAngle); cairo_line_to (m_cr, m_radius * cosAngle, m_radius * sinAngle); cairo_stroke(m_cr); cairo_restore(m_cr); // stack-pen-size } // store the current time SYSTEMTIME time; GetLocalTime(&time); // compute the angles of the indicators of our clock double minutes = time.wMinute * M_PI / 30; double hours = time.wHour * M_PI / 6; double seconds= ((double)time.wSecond + (double)time.wMilliseconds / 1000) * M_PI / 30; cairo_save(m_cr); cairo_set_line_cap(m_cr, CAIRO_LINE_CAP_ROUND); // draw the seconds hand cairo_save(m_cr); cairo_set_line_width(m_cr, m_line_width / 3); cairo_set_source_rgba(m_cr, 0.7, 0.7, 0.7, 0.8); // gray cairo_move_to(m_cr, 0, 0); double secondHandLength = 0.9 * m_radius; double sinSec = std::sin(seconds); double cosSec = std::cos(seconds); cairo_line_to(m_cr, sinSec * secondHandLength, -cosSec * secondHandLength); cairo_stroke(m_cr); cairo_restore(m_cr); // draw the minutes hand cairo_set_source_rgba(m_cr, 0.117, 0.337, 0.612, 0.9); // blue cairo_move_to(m_cr, 0, 0); double minuteHandLength = 0.8 * m_radius; double sinMin = std::sin(minutes + seconds/60); double cosMin = std::cos(minutes + seconds/60); cairo_line_to(m_cr, sinMin * minuteHandLength, -cosMin * minuteHandLength); cairo_stroke(m_cr); // draw the hours hand cairo_set_source_rgba(m_cr, 0.337, 0.612, 0.117, 0.9); // green cairo_move_to(m_cr, 0, 0); double hourHandLength = 0.5 * m_radius; double sinHours = std::sin(hours + minutes / 12.0); double cosHours = std::cos(hours + minutes / 12.0); cairo_line_to(m_cr, sinHours * hourHandLength, -cosHours * hourHandLength); cairo_stroke(m_cr); cairo_restore(m_cr); // draw a little dot in the middle cairo_arc(m_cr, 0, 0, m_line_width / 3.0, 0, 2 * M_PI); cairo_fill(m_cr); cairo_stroke(m_cr); cairo_restore(m_cr); // Display FPS: cairo_select_font_face(m_cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(m_cr, 11.0); cairo_move_to(m_cr, 0, 10.0); char message[100]; sprintf(message, "fps: %0.2g", fps); cairo_show_text(m_cr, message); cairo_surface_flush(m_surface); if (cairo_status(m_cr) != CAIRO_STATUS_SUCCESS) printf("render failed with %s\n", cairo_status_to_string(cairo_status(m_cr))); }
void calendar_draw_page (GtkPrintOperation *operation, GtkPrintContext *context, gint npage, gpointer user_data) { PangoLayout *layout; PangoFontDescription *month_name_font, *day_name_font, *day_num_font, *event_font; cairo_t *cr; GDate *date; gdouble page_width, page_height, day_width, day_height; gint text_width, text_height, header_height, event_height, mnf_height, dnf_height, duf_height; gint day, month, i, j; guint32 julian; gboolean monday, actual; gchar buffer[BUFFER_SIZE]; gint padding = config.cal_print_padding; GUI *appGUI = (GUI *) user_data; date = g_date_new_julian (g_date_get_julian (appGUI->cal->date)); g_return_if_fail (date != NULL); cr = gtk_print_context_get_cairo_context (context); layout = gtk_print_context_create_pango_layout (context); month_name_font = pango_font_description_from_string (config.cal_print_month_name_font); day_name_font = pango_font_description_from_string (config.cal_print_day_name_font); day_num_font = pango_font_description_from_string (config.cal_print_day_num_font); event_font = pango_font_description_from_string (config.cal_print_event_font); pango_layout_set_text (layout, "Aj", -1); pango_layout_set_font_description (layout, month_name_font); pango_layout_get_pixel_size (layout, NULL, &mnf_height); mnf_height *= 1.2; pango_layout_set_font_description (layout, day_name_font); pango_layout_get_pixel_size (layout, NULL, &dnf_height); dnf_height *= 1.2; pango_layout_set_font_description (layout, day_num_font); pango_layout_get_pixel_size (layout, NULL, &duf_height); page_width = gtk_print_context_get_width (context); day_width = page_width / 7; page_height = gtk_print_context_get_height (context); header_height = mnf_height + dnf_height; day_height = (page_height - header_height) / 6; event_height = day_height - duf_height - padding * 3; cairo_set_line_width (cr, 1); monday = (config.display_options & GUI_CALENDAR_WEEK_START_MONDAY) ? TRUE : FALSE; /* Month and year */ pango_layout_set_font_description (layout, month_name_font); g_date_strftime (buffer, BUFFER_SIZE, "%B %Y", date); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_size (layout, &text_width, NULL); cairo_move_to (cr, (page_width - text_width) / 2, 0); pango_cairo_show_layout (cr, layout); /* Day names */ pango_layout_set_font_description (layout, day_name_font); for (i = 0; i < 7; i++) { g_snprintf (buffer, BUFFER_SIZE, "%s", utl_get_day_name (i + 7 + monday, FALSE)); pango_layout_set_text (layout, buffer, -1); pango_layout_get_pixel_size (layout, &text_width, NULL); cairo_move_to (cr, day_width * i + (day_width - text_width) / 2, mnf_height); pango_cairo_show_layout (cr, layout); } /* Day */ g_date_set_day (date, 1); day = g_date_get_weekday (date); month = g_date_get_month (date); day = monday ? day - 1 : day % 7; if (day > 0) g_date_subtract_days (date, day); day = g_date_get_day (date); julian = g_date_get_julian (date); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_width (layout, (day_width - padding * 2) * PANGO_SCALE); pango_layout_set_height (layout, event_height * PANGO_SCALE); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_indent (layout, -4 * PANGO_SCALE); for (i = 0; i < 6; i++) { for (j = 0; j < 7; j++) { actual = (month == g_date_get_month (date)) ? TRUE : FALSE; day = g_date_get_day (date); cairo_rectangle (cr, day_width * j, header_height + day_height * i, day_width, day_height); if (actual) { cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); } else { cairo_set_source_rgb (cr, 0.8, 0.8, 0.8); } cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); pango_layout_set_font_description (layout, day_num_font); if (actual) { cairo_move_to (cr, day_width * j + padding, header_height + day_height * i + padding); if ((j == 0 && !monday) || (j == 5 && monday) || j == 6) { g_snprintf (buffer, BUFFER_SIZE, "<span color=\"red\">%d</span>", day); } else { g_snprintf (buffer, BUFFER_SIZE, "%d", day); } pango_layout_set_markup (layout, buffer, -1); pango_cairo_show_layout (cr, layout); cal_print_get_events (buffer, julian, appGUI); pango_layout_set_markup (layout, "", -1); pango_layout_set_text (layout, buffer, -1); pango_layout_set_font_description (layout, event_font); pango_layout_get_pixel_size (layout, NULL, &text_height); cairo_move_to (cr, day_width * j + padding, header_height + day_height * (i + 1) - text_height - padding); pango_cairo_show_layout (cr, layout); } else { cairo_move_to (cr, day_width * j + padding, header_height + day_height * i + padding); g_snprintf (buffer, BUFFER_SIZE, "<span color=\"white\">%d</span>", day); pango_layout_set_markup (layout, buffer, -1); pango_cairo_show_layout (cr, layout); } g_date_add_days (date, 1); julian++; } } g_date_free (date); pango_font_description_free (month_name_font); pango_font_description_free (day_name_font); pango_font_description_free (day_num_font); pango_font_description_free (event_font); g_object_unref (layout); }
static gboolean dt_iop_zonesystem_preview_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self) { const int inset = DT_PIXEL_APPLY_DPI(2); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ GtkStyleContext *context = gtk_widget_get_style_context(self->expander); gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height); width -= 2 * inset; height -= 2 * inset; cairo_translate(cr, inset, inset); dt_pthread_mutex_lock(&g->lock); if(g->in_preview_buffer && g->out_preview_buffer && self->enabled) { /* calculate the zonemap */ float zonemap[MAX_ZONE_SYSTEM_SIZE] = { -1 }; _iop_zonesystem_calculate_zonemap(p, zonemap); /* let's generate a pixbuf from pixel zone buffer */ guchar *image = g_malloc_n((size_t)4 * g->preview_width * g->preview_height, sizeof(guchar)); guchar *buffer = g->mouse_over_output_zones ? g->out_preview_buffer : g->in_preview_buffer; for(int k = 0; k < g->preview_width * g->preview_height; k++) { int zone = 255 * CLIP(((1.0 / (p->size - 1)) * buffer[k])); image[4 * k + 2] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 255 : zone; image[4 * k + 1] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 255 : zone; image[4 * k + 0] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 0 : zone; } dt_pthread_mutex_unlock(&g->lock); const int wd = g->preview_width, ht = g->preview_height; const float scale = fminf(width / (float)wd, height / (float)ht); const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data(image, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width / 2.0, height / 2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f * wd, -.5f * ht); cairo_rectangle(cr, DT_PIXEL_APPLY_DPI(1), DT_PIXEL_APPLY_DPI(1), wd - DT_PIXEL_APPLY_DPI(2), ht - DT_PIXEL_APPLY_DPI(2)); cairo_set_source_surface(cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD); cairo_fill_preserve(cr); cairo_surface_destroy(surface); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0)); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); g_free(image); } else { dt_pthread_mutex_unlock(&g->lock); // draw a big, subdued dt logo if(g->image) { GdkRGBA *color; gtk_style_context_get(context, gtk_widget_get_state_flags(self->expander), "background-color", &color, NULL); cairo_set_source_surface(cr, g->image, (width - g->image_width) * 0.5, (height - g->image_height) * 0.5); cairo_rectangle(cr, 0, 0, width, height); cairo_set_operator(cr, CAIRO_OPERATOR_HSL_LUMINOSITY); cairo_fill_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_DARKEN); cairo_set_source_rgb(cr, color->red + 0.02, color->green + 0.02, color->blue + 0.02); cairo_fill_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_LIGHTEN); cairo_set_source_rgb(cr, color->red - 0.02, color->green - 0.02, color->blue - 0.02); cairo_fill(cr); gdk_rgba_free(color); } } cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
static gboolean dt_iop_zonesystem_preview_expose (GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *self) { const int inset = 2; int width = widget->allocation.width, height = widget->allocation.height; dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ GtkStateType state = gtk_widget_get_state(self->expander); GtkStyle *style = gtk_widget_get_style(self->expander); cairo_set_source_rgb (cr, style->bg[state].red/65535.0, style->bg[state].green/65535.0, style->bg[state].blue/65535.0); cairo_paint (cr); width -= 2*inset; height -= 2*inset; cairo_translate(cr, inset, inset); dt_pthread_mutex_lock(&g->lock); if( g->preview_buffer && self->enabled) { /* calculate the zonemap */ float zonemap[MAX_ZONE_SYSTEM_SIZE]= {-1}; _iop_zonesystem_calculate_zonemap (p,zonemap); /* let's generate a pixbuf from pixel zone buffer */ guchar *image = g_malloc ((g->preview_width*g->preview_height)*4); for (int k=0; k<g->preview_width*g->preview_height; k++) { int zone = 255*CLIP (((1.0/(p->size-1))*g->preview_buffer[k])); image[4*k+2] = (g->hilite_zone && g->preview_buffer[k]==g->zone_under_mouse)?255:zone; image[4*k+1] = (g->hilite_zone && g->preview_buffer[k]==g->zone_under_mouse)?255:zone; image[4*k+0] = (g->hilite_zone && g->preview_buffer[k]==g->zone_under_mouse)?0:zone; } dt_pthread_mutex_unlock(&g->lock); const int wd = g->preview_width, ht = g->preview_height; const float scale = fminf(width/(float)wd, height/(float)ht); const int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data (image, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width/2.0, height/2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f*wd, -.5f*ht); cairo_rectangle(cr, 1, 1, wd-2, ht-2); cairo_set_source_surface (cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD); cairo_fill_preserve(cr); cairo_surface_destroy (surface); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); g_free(image); } else dt_pthread_mutex_unlock(&g->lock); cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
/* Refresh gadget's background if needed */ gboolean refresh_background (block_notes_core_s *core) { GdkColor color; cairo_t *cr; double x0 = 5.0; double y0 = 12.0; double rect_width = core->width - 10; double rect_height = core->height - 12; double radius = 40; double x1,y1; cr = gdk_cairo_create (core->window->window); /* Set gadget's background transparent */ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); x1 = x0 + rect_width; y1 = y0 + rect_height; if (!rect_width || !rect_height) return; cairo_move_to (cr, x0, (y0 + y1)/2); cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0); cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2); cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1); cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2); cairo_close_path (cr); cairo_set_source_rgba (cr, (float) core->gadget.red / 65535.0, (float) core->gadget.green / 65535.0, (float) core->gadget.blue / 65535.0, 1.0); cairo_fill_preserve (cr); cairo_set_source_rgba (cr, (float) core->border.red / 65535.0, (float) core->border.green / 65535.0, (float) core->border.blue / 65535.0, core->border_transparency); cairo_set_line_width (cr, 3.0); cairo_stroke (cr); cairo_destroy (cr); gtk_widget_modify_base (core->view, GTK_STATE_NORMAL, &core->gadget); /* Reset textview font */ gtk_widget_modify_font (core->view, core->font_pango); /* Reset font color */ gtk_widget_modify_text (core->view, GTK_STATE_NORMAL, &core->text); /* Resize window */ gtk_window_resize (GTK_WINDOW(core->window), core->width, core->height); /* Reset buttons */ gtk_fixed_move (GTK_FIXED(core->fixed), core->button_setting, core->width - 40, 0); gtk_fixed_move (GTK_FIXED(core->fixed), core->button_move, core->width - 30, 0); gtk_fixed_move (GTK_FIXED(core->fixed), core->button_close, core->width - 20, 0); gtk_widget_set_size_request (core->view, core->width - 27, core->height - 30); return FALSE; }
/* * Draws global image with fill color onto a pixmap with the given * resolution and returns it. * */ xcb_pixmap_t draw_image(uint32_t *resolution) { xcb_pixmap_t bg_pixmap = XCB_NONE; #ifndef NOLIBCAIRO if (!vistype) vistype = get_root_visual_type(screen); bg_pixmap = create_bg_pixmap(conn, screen, resolution, color); /* Initialize cairo: Create one in-memory surface to render the unlock * indicator on, create one XCB surface to actually draw (one or more, * depending on the amount of screens) unlock indicators on. */ cairo_surface_t *output = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, BUTTON_DIAMETER, BUTTON_DIAMETER); cairo_t *ctx = cairo_create(output); cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); cairo_t *xcb_ctx = cairo_create(xcb_output); if (img) { if (!tile) { cairo_set_source_surface(xcb_ctx, img, 0, 0); cairo_paint(xcb_ctx); } else { /* create a pattern and fill a rectangle as big as the screen */ cairo_pattern_t *pattern; pattern = cairo_pattern_create_for_surface(img); cairo_set_source(xcb_ctx, pattern); cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); cairo_pattern_destroy(pattern); } } else { char strgroups[3][3] = {{color[0], color[1], '\0'}, {color[2], color[3], '\0'}, {color[4], color[5], '\0'}}; uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), (strtol(strgroups[1], NULL, 16)), (strtol(strgroups[2], NULL, 16))}; cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0); cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); cairo_fill(xcb_ctx); } #ifndef NOLIBCAIRO /* build indicator color arrays */ char strgroupsiv[4][3] = {{insidevercolor[0], insidevercolor[1], '\0'}, {insidevercolor[2], insidevercolor[3], '\0'}, {insidevercolor[4], insidevercolor[5], '\0'}, {insidevercolor[6], insidevercolor[7], '\0'}}; uint32_t insidever16[4] = {(strtol(strgroupsiv[0], NULL, 16)), (strtol(strgroupsiv[1], NULL, 16)), (strtol(strgroupsiv[2], NULL, 16)), (strtol(strgroupsiv[3], NULL, 16))}; char strgroupsiw[4][3] = {{insidewrongcolor[0], insidewrongcolor[1], '\0'}, {insidewrongcolor[2], insidewrongcolor[3], '\0'}, {insidewrongcolor[4], insidewrongcolor[5], '\0'}, {insidewrongcolor[6], insidewrongcolor[7], '\0'}}; uint32_t insidewrong16[4] = {(strtol(strgroupsiw[0], NULL, 16)), (strtol(strgroupsiw[1], NULL, 16)), (strtol(strgroupsiw[2], NULL, 16)), (strtol(strgroupsiw[3], NULL, 16))}; char strgroupsi[4][3] = {{insidecolor[0], insidecolor[1], '\0'}, {insidecolor[2], insidecolor[3], '\0'}, {insidecolor[4], insidecolor[5], '\0'}, {insidecolor[6], insidecolor[7], '\0'}}; uint32_t inside16[4] = {(strtol(strgroupsi[0], NULL, 16)), (strtol(strgroupsi[1], NULL, 16)), (strtol(strgroupsi[2], NULL, 16)), (strtol(strgroupsi[3], NULL, 16))}; char strgroupsrv[4][3] = {{ringvercolor[0], ringvercolor[1], '\0'}, {ringvercolor[2], ringvercolor[3], '\0'}, {ringvercolor[4], ringvercolor[5], '\0'}, {ringvercolor[6], ringvercolor[7], '\0'}}; uint32_t ringver16[4] = {(strtol(strgroupsrv[0], NULL, 16)), (strtol(strgroupsrv[1], NULL, 16)), (strtol(strgroupsrv[2], NULL, 16)), (strtol(strgroupsrv[3], NULL, 16))}; char strgroupsrw[4][3] = {{ringwrongcolor[0], ringwrongcolor[1], '\0'}, {ringwrongcolor[2], ringwrongcolor[3], '\0'}, {ringwrongcolor[4], ringwrongcolor[5], '\0'}, {ringwrongcolor[6], ringwrongcolor[7], '\0'}}; uint32_t ringwrong16[4] = {(strtol(strgroupsrw[0], NULL, 16)), (strtol(strgroupsrw[1], NULL, 16)), (strtol(strgroupsrw[2], NULL, 16)), (strtol(strgroupsrw[3], NULL, 16))}; char strgroupsr[4][3] = {{ringcolor[0], ringcolor[1], '\0'}, {ringcolor[2], ringcolor[3], '\0'}, {ringcolor[4], ringcolor[5], '\0'}, {ringcolor[6], ringcolor[7], '\0'}}; uint32_t ring16[4] = {(strtol(strgroupsr[0], NULL, 16)), (strtol(strgroupsr[1], NULL, 16)), (strtol(strgroupsr[2], NULL, 16)), (strtol(strgroupsr[3], NULL, 16))}; char strgroupsl[4][3] = {{linecolor[0], linecolor[1], '\0'}, {linecolor[2], linecolor[3], '\0'}, {linecolor[4], linecolor[5], '\0'}, {linecolor[6], linecolor[7], '\0'}}; uint32_t line16[4] = {(strtol(strgroupsl[0], NULL, 16)), (strtol(strgroupsl[1], NULL, 16)), (strtol(strgroupsl[2], NULL, 16)), (strtol(strgroupsl[3], NULL, 16))}; char strgroupst[4][3] = {{textcolor[0], textcolor[1], '\0'}, {textcolor[2], textcolor[3], '\0'}, {textcolor[4], textcolor[5], '\0'}, {textcolor[6], textcolor[7], '\0'}}; uint32_t text16[4] = {(strtol(strgroupst[0], NULL, 16)), (strtol(strgroupst[1], NULL, 16)), (strtol(strgroupst[2], NULL, 16)), (strtol(strgroupst[3], NULL, 16))}; char strgroupsk[4][3] = {{keyhlcolor[0], textcolor[1], '\0'}, {keyhlcolor[2], textcolor[3], '\0'}, {keyhlcolor[4], textcolor[5], '\0'}, {keyhlcolor[6], textcolor[7], '\0'}}; uint32_t keyhl16[4] = {(strtol(strgroupsk[0], NULL, 16)), (strtol(strgroupsk[1], NULL, 16)), (strtol(strgroupsk[2], NULL, 16)), (strtol(strgroupsk[3], NULL, 16))}; char strgroupsb[4][3] = {{bshlcolor[0], textcolor[1], '\0'}, {bshlcolor[2], textcolor[3], '\0'}, {bshlcolor[4], textcolor[5], '\0'}, {bshlcolor[6], textcolor[7], '\0'}}; uint32_t bshl16[4] = {(strtol(strgroupsb[0], NULL, 16)), (strtol(strgroupsb[1], NULL, 16)), (strtol(strgroupsb[2], NULL, 16)), (strtol(strgroupsb[3], NULL, 16))}; #endif if (unlock_state >= STATE_KEY_PRESSED && unlock_indicator) { /* Draw a (centered) circle with transparent background. */ cairo_set_line_width(ctx, 10.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, 0 /* start */, 2 * M_PI /* end */); /* Use the appropriate color for the different PAM states * (currently verifying, wrong password, or default) */ switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, (double)insidever16[0]/255, (double)insidever16[1]/255, (double)insidever16[2]/255, (double)insidever16[3]/255); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, (double)insidewrong16[0]/255, (double)insidewrong16[1]/255, (double)insidewrong16[2]/255, (double)insidewrong16[3]/255); break; default: cairo_set_source_rgba(ctx, (double)inside16[0]/255, (double)inside16[1]/255, (double)inside16[2]/255, (double)inside16[3]/255); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgba(ctx, (double)ringver16[0]/255, (double)ringver16[1]/255, (double)ringver16[2]/255, (double)ringver16[3]/255); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, (double)ringwrong16[0]/255, (double)ringwrong16[1]/255, (double)ringwrong16[2]/255, (double)ringwrong16[3]/255); break; case STATE_PAM_IDLE: cairo_set_source_rgba(ctx, (double)ring16[0]/255, (double)ring16[1]/255, (double)ring16[2]/255, (double)ring16[3]/255); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgba(ctx, (double)line16[0]/255, (double)line16[1]/255, (double)line16[2]/255, (double)line16[3]/255); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); cairo_stroke(ctx); cairo_set_line_width(ctx, 10.0); /* Display a (centered) text of the current PAM state. */ char *text = NULL; switch (pam_state) { case STATE_PAM_VERIFY: text = verifying_text; break; case STATE_PAM_WRONG: text = wrong_text; break; default: break; } if (text) { cairo_text_extents_t extents; double x, y; cairo_set_source_rgba(ctx, (double)text16[0]/255, (double)text16[1]/255, (double)text16[2]/255, (double)text16[3]/255); cairo_set_font_size(ctx, 28.0); cairo_text_extents(ctx, text, &extents); x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing); cairo_move_to(ctx, x, y); cairo_show_text(ctx, text); cairo_close_path(ctx); } /* After the user pressed any valid key or the backspace key, we * highlight a random part of the unlock indicator to confirm this * keypress. */ if (unlock_state == STATE_KEY_ACTIVE || unlock_state == STATE_BACKSPACE_ACTIVE) { cairo_new_sub_path(ctx); double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0; cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start, highlight_start + (M_PI / 3.0)); if (unlock_state == STATE_KEY_ACTIVE) { /* For normal keys, we use a lighter green. */ cairo_set_source_rgba(ctx, (double)keyhl16[0]/255, (double)keyhl16[1]/255, (double)keyhl16[2]/255, (double)keyhl16[3]/255); } else { /* For backspace, we use red. */ cairo_set_source_rgba(ctx, (double)bshl16[0]/255, (double)bshl16[1]/255, (double)bshl16[2]/255, (double)bshl16[3]/255); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgba(ctx, (double)line16[0]/255, (double)line16[1]/255, (double)line16[2]/255, (double)line16[3]/255); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); cairo_stroke(ctx); } } if (xr_screens > 0) { /* Composite the unlock indicator in the middle of each screen. */ for (int screen = 0; screen < xr_screens; screen++) { int x = (xr_resolutions[screen].x + ((xr_resolutions[screen].width / 2) - (BUTTON_DIAMETER / 2))); int y = (xr_resolutions[screen].y + ((xr_resolutions[screen].height / 2) - (BUTTON_DIAMETER / 2))); cairo_set_source_surface(xcb_ctx, output, x, y); cairo_rectangle(xcb_ctx, x, y, BUTTON_DIAMETER, BUTTON_DIAMETER); cairo_fill(xcb_ctx); } } else { /* We have no information about the screen sizes/positions, so we just * place the unlock indicator in the middle of the X root window and * hope for the best. */ int x = (last_resolution[0] / 2); int y = (last_resolution[1] / 2); cairo_set_source_surface(xcb_ctx, output, x, y); cairo_rectangle(xcb_ctx, x, y, BUTTON_DIAMETER, BUTTON_DIAMETER); cairo_fill(xcb_ctx); } cairo_surface_destroy(xcb_output); cairo_surface_destroy(output); cairo_destroy(ctx); cairo_destroy(xcb_ctx); #endif return bg_pixmap; }
void dt_view_image_expose( dt_view_image_over_t *image_over, uint32_t imgid, cairo_t *cr, int32_t width, int32_t height, int32_t zoom, int32_t px, int32_t py) { cairo_save (cr); float bgcol = 0.4, fontcol = 0.425, bordercol = 0.1, outlinecol = 0.2; int selected = 0, altered = 0, imgsel; DT_CTL_GET_GLOBAL(imgsel, lib_image_mouse_over_id); // if(img->flags & DT_IMAGE_SELECTED) selected = 1; /* clear and reset statements */ DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.is_selected); DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.have_history); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.is_selected); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.have_history); /* bind imgid to prepared statments */ DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.is_selected, 1, imgid); DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.have_history, 1, imgid); /* lets check if imgid is selected */ if(sqlite3_step(darktable.view_manager->statements.is_selected) == SQLITE_ROW) selected = 1; /* lets check if imgid has history */ if(sqlite3_step(darktable.view_manager->statements.have_history) == SQLITE_ROW) altered = 1; const dt_image_t *img = dt_image_cache_read_testget(darktable.image_cache, imgid); if(selected == 1) { outlinecol = 0.4; bgcol = 0.6; fontcol = 0.5; } if(imgsel == imgid) { bgcol = 0.8; // mouse over fontcol = 0.7; outlinecol = 0.6; // if the user points at this image, we really want it: if(!img) img = dt_image_cache_read_get(darktable.image_cache, imgid); } float imgwd = 0.90f; if(zoom == 1) { imgwd = .97f; // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); } else { double x0 = 1, y0 = 1, rect_width = width-2, rect_height = height-2, radius = 5; double x1, y1, off, off1; x1=x0+rect_width; y1=y0+rect_height; off=radius*0.666; off1 = radius-off; cairo_move_to (cr, x0, y0 + radius); cairo_curve_to (cr, x0, y0+off1, x0+off1 , y0, x0 + radius, y0); cairo_line_to (cr, x1 - radius, y0); cairo_curve_to (cr, x1-off1, y0, x1, y0+off1, x1, y0 + radius); cairo_line_to (cr, x1 , y1 - radius); cairo_curve_to (cr, x1, y1-off1, x1-off1, y1, x1 - radius, y1); cairo_line_to (cr, x0 + radius, y1); cairo_curve_to (cr, x0+off1, y1, x0, y1-off1, x0, y1- radius); cairo_close_path (cr); cairo_set_source_rgb(cr, bgcol, bgcol, bgcol); cairo_fill_preserve(cr); cairo_set_line_width(cr, 0.005*width); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); cairo_stroke(cr); if(img) { const char *ext = img->filename + strlen(img->filename); while(ext > img->filename && *ext != '.') ext--; ext++; cairo_set_source_rgb(cr, fontcol, fontcol, fontcol); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .25*width); cairo_move_to (cr, .01*width, .24*height); cairo_show_text (cr, ext); } } float scale = 1.0; dt_mipmap_buffer_t buf; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size( darktable.mipmap_cache, imgwd*width, imgwd*height); dt_mipmap_cache_read_get( darktable.mipmap_cache, &buf, imgid, mip, 0); 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(darktable.thumbnail_width, width) / (float)buf.width, fminf(darktable.thumbnail_height, height) / (float)buf.height ); } else scale = fminf(width*imgwd/(float)buf.width, height*imgwd/(float)buf.height); } // draw centered and fitted: cairo_save(cr); cairo_translate(cr, width/2.0, height/2.0f); cairo_scale(cr, scale, scale); if(buf.buf) { cairo_translate(cr, -.5f*buf.width, -.5f*buf.height); cairo_set_source_surface (cr, surface, 0, 0); if(buf.width <= 8 && buf.height <= 8) cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_rectangle(cr, 0, 0, buf.width, buf.height); cairo_fill(cr); cairo_surface_destroy (surface); if(zoom == 1) cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST); cairo_rectangle(cr, 0, 0, buf.width, buf.height); } // border around image const float border = zoom == 1 ? 16/scale : 2/scale; cairo_set_source_rgb(cr, bordercol, bordercol, bordercol); if(buf.buf && selected) { cairo_set_line_width(cr, 1./scale); if(zoom == 1) { // draw shadow around border cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_stroke(cr); // cairo_new_path(cr); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); float alpha = 1.0f; for(int k=0; k<16; k++) { cairo_rectangle(cr, 0, 0, buf.width, buf.height); cairo_new_sub_path(cr); cairo_rectangle(cr, -k/scale, -k/scale, buf.width+2.*k/scale, buf.height+2.*k/scale); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.6f; cairo_fill(cr); } } else { cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_new_sub_path(cr); cairo_rectangle(cr, -border, -border, buf.width+2.*border, buf.height+2.*border); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 1.0-bordercol, 1.0-bordercol, 1.0-bordercol); cairo_fill(cr); } } else if(buf.buf) { cairo_set_line_width(cr, 1); cairo_stroke(cr); } cairo_restore(cr); if(buf.buf) dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); const float fscale = fminf(width, height); if(imgsel == imgid) { // draw mouseover hover effects, set event hook for mouse button down! *image_over = DT_VIEW_DESERT; cairo_set_line_width(cr, 1.5); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); float r1, r2; if(zoom != 1) { r1 = 0.05*width; r2 = 0.022*width; } else { r1 = 0.015*fscale; r2 = 0.007*fscale; } float x, y; if(zoom != 1) y = 0.90*height; else y = .12*fscale; if(img) for(int k=0; k<5; k++) { if(zoom != 1) x = (0.41+k*0.12)*width; else x = (.08+k*0.04)*fscale; if((img->flags & 0x7) != 6) //if rejected: draw no stars { dt_view_star(cr, x, y, r1, r2); if((px - x)*(px - x) + (py - y)*(py - y) < r1*r1) { *image_over = DT_VIEW_STAR_1 + k; cairo_fill(cr); } else if((img->flags & 0x7) > k) { cairo_fill_preserve(cr); cairo_set_source_rgb(cr, 1.0-bordercol, 1.0-bordercol, 1.0-bordercol); cairo_stroke(cr); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); } else cairo_stroke(cr); } } //Image rejected? if(zoom !=1) x = 0.11*width; else x = .04*fscale; if((px - x)*(px - x) + (py - y)*(py - y) < r1*r1) { *image_over = DT_VIEW_REJECT; //mouse sensitive cairo_new_sub_path(cr); cairo_arc(cr, x, y, (r1+r2)*.5, 0, 2.0f*M_PI); cairo_stroke(cr); } else if (img && ((img->flags & 0x7) == 6)) { cairo_set_source_rgb(cr, 1., 0., 0.); cairo_new_sub_path(cr); cairo_arc(cr, x, y, (r1+r2)*.5, 0, 2.0f*M_PI); cairo_stroke(cr); cairo_set_line_width(cr, 2.5); } //reject cross: cairo_move_to(cr, x-r2, y-r2); cairo_line_to(cr, x+r2, y+r2); cairo_move_to(cr, x+r2, y-r2); cairo_line_to(cr, x-r2, y+r2); cairo_close_path(cr); cairo_stroke(cr); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); cairo_set_line_width(cr, 1.5); // image altered? if(altered) { // align to right float s = (r1+r2)*.5; if(zoom != 1) { x = width*0.9; y = height*0.1; } else x = (.04+7*0.04)*fscale; dt_view_draw_altered(cr, x, y, s); //g_print("px = %d, x = %.4f, py = %d, y = %.4f\n", px, x, py, y); if(img && abs(px-x) <= 1.2*s && abs(py-y) <= 1.2*s) // mouse hovers over the altered-icon -> history tooltip! { darktable.gui->center_tooltip = 1; } } } // kill all paths, in case img was not loaded yet, or is blocked: cairo_new_path(cr); // TODO: make mouse sensitive, just as stars! // TODO: cache in image struct! { // color labels: const float x = zoom == 1 ? (0.07)*fscale : .21*width; const float y = zoom == 1 ? 0.17*fscale: 0.1*height; const float r = zoom == 1 ? 0.01*fscale : 0.03*width; /* clear and reset prepared statement */ DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.get_color); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.get_color); /* setup statement and iterate rows */ DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_color, 1, imgid); while(sqlite3_step(darktable.view_manager->statements.get_color) == SQLITE_ROW) { cairo_save(cr); int col = sqlite3_column_int(darktable.view_manager->statements.get_color, 0); // see src/dtgtk/paint.c dtgtk_cairo_paint_label(cr, x+(3*r*col)-5*r, y-r, r*2, r*2, col); cairo_restore(cr); } } if(img && (zoom == 1)) { // some exif data cairo_set_source_rgb(cr, .7, .7, .7); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .025*fscale); cairo_move_to (cr, .02*fscale, .04*fscale); // cairo_show_text(cr, img->filename); cairo_text_path(cr, img->filename); char exifline[50]; cairo_move_to (cr, .02*fscale, .08*fscale); dt_image_print_exif(img, exifline, 50); cairo_text_path(cr, exifline); cairo_fill_preserve(cr); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr); } if(img) dt_image_cache_read_release(darktable.image_cache, img); cairo_restore(cr); // if(zoom == 1) cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); }
static cairo_time_t draw_spiral (cairo_t *cr, cairo_fill_rule_t fill_rule, align_t align, close_t close, int width, int height, int loops) { int i; int n=0; double x[MAX_SEGMENTS]; double y[MAX_SEGMENTS]; int step = 3; int side = width < height ? width : height; assert(5*(side/step/2+1)+2 < MAX_SEGMENTS); #define L(x_,y_) (x[n] = (x_), y[n] = (y_), n++) #define M(x_,y_) L(x_,y_) #define v(t) L(x[n-1], y[n-1] + (t)) #define h(t) L(x[n-1] + (t), y[n-1]) switch (align) { case PIXALIGN: M(0,0); break; case NONALIGN: M(0.1415926, 0.7182818); break; } while (side >= step && side >= 0) { v(side); h(side); v(-side); h(-side+step); v(step); side -= 2*step; } switch (close) { case RECTCLOSE: L(x[n-1],y[0]); break; case DIAGCLOSE: L(x[0],y[0]); break; } assert(n < MAX_SEGMENTS); cairo_save (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); cairo_translate (cr, 1, 1); cairo_set_fill_rule (cr, fill_rule); cairo_set_source_rgb (cr, 1, 0, 0); cairo_new_path (cr); cairo_move_to (cr, x[0], y[0]); for (i = 1; i < n; i++) { cairo_line_to (cr, x[i], y[i]); } cairo_close_path (cr); cairo_perf_timer_start (); cairo_perf_set_thread_aware (cr, FALSE); while (loops--) { if (loops == 0) cairo_perf_set_thread_aware (cr, TRUE); cairo_fill_preserve (cr); } cairo_perf_timer_stop (); cairo_restore (cr); return cairo_perf_timer_elapsed (); }